From 5bfe6383342d5fe6c28538e9111b1ebded089b89 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Tue, 4 Jun 2024 13:59:36 +0800 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20change?= =?UTF-8?q?s=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 [skip ci] --- .ci/generate-buildkite-pipeline-premerge | 1 - .github/new-prs-labeler.yml | 24 + .../restart-preempted-libcxx-jobs.yaml | 41 +- bolt/docs/CommandLineArgumentReference.md | 227 +- bolt/docs/generate_doc.py | 149 + bolt/include/bolt/Core/BinaryBasicBlock.h | 4 +- bolt/include/bolt/Core/FunctionLayout.h | 3 +- bolt/include/bolt/Rewrite/RewriteInstance.h | 4 + bolt/lib/Core/BinaryFunction.cpp | 10 +- bolt/lib/Core/FunctionLayout.cpp | 9 +- bolt/lib/Passes/IdenticalCodeFolding.cpp | 5 +- bolt/lib/Profile/YAMLProfileWriter.cpp | 3 + bolt/lib/Rewrite/DWARFRewriter.cpp | 2 +- bolt/lib/Rewrite/RewriteInstance.cpp | 12 +- bolt/test/AArch64/Inputs/array_end.lld_script | 3 + bolt/test/AArch64/lit.local.cfg | 2 +- bolt/test/Inputs/lsda.ldscript | 7 - .../dwarf4-df-input-lowpc-ranges-other.s | 710 ++++ .../dwarf4-subprogram-multiple-ranges-other.s | 335 ++ .../dwarf5-subprogram-multiple-ranges-other.s | 390 +++ bolt/test/X86/addr32.s | 2 +- bolt/test/X86/asm-func-debug.test | 14 +- bolt/test/X86/avx512-trap.test | 10 +- bolt/test/X86/bb-with-two-tail-calls.s | 6 +- bolt/test/X86/block-reordering.test | 5 +- ...olt-address-translation-internal-call.test | 10 +- .../X86/bolt-address-translation-yaml.test | 12 +- bolt/test/X86/bolt-address-translation.test | 54 +- bolt/test/X86/branch-data.test | 6 +- bolt/test/X86/broken_dynsym.test | 6 +- bolt/test/X86/bug-function-layout-execount.s | 2 +- bolt/test/X86/bug-reorder-bb-jrcxz.s | 16 +- bolt/test/X86/calculate-emitted-block-size.s | 6 +- bolt/test/X86/call-zero.s | 2 +- bolt/test/X86/cdsplit-call-scale.s | 14 +- bolt/test/X86/cdsplit-symbol-names.s | 6 +- bolt/test/X86/cfi-expr-rewrite.s | 4 +- bolt/test/X86/cfi-instrs-count.s | 22 +- bolt/test/X86/cfi-instrs-reordered.s | 4 +- bolt/test/X86/checkvma-large-section.test | 2 +- bolt/test/X86/ctc-and-unreachable.test | 4 +- bolt/test/X86/debug-fission-single-convert.s | 2 +- bolt/test/X86/debug-fission-single.s | 2 +- bolt/test/X86/double-jump.test | 6 +- .../X86/dwarf-handle-visit-loclist-error.s | 2 +- bolt/test/X86/dwarf-test-df-logging.test | 2 +- bolt/test/X86/dwarf3-lowpc-highpc-convert.s | 2 +- ...f4-cross-cu-backward-different-abbrev.test | 4 +- ...rf4-cross-cu-forward-different-abbrev.test | 4 +- ...oclist-dwarf4-loclist--dwarf5-loclist.test | 2 +- bolt/test/X86/dwarf4-df-basic.test | 2 +- .../dwarf4-df-call-site-change-low-pc.test | 2 +- ...f-change-in-dw-op-gnu-addr-index-main.test | 2 +- ...o-no-convert-low-pc-high-pc-to-ranges.test | 4 +- bolt/test/X86/dwarf4-df-dualcu-loclist.test | 2 +- bolt/test/X86/dwarf4-df-dualcu.test | 4 +- .../dwarf4-df-inlined-subroutine-lowpc-0.test | 4 +- .../X86/dwarf4-df-input-lowpc-ranges-cus.test | 97 + .../X86/dwarf4-df-input-lowpc-ranges.test | 4 +- bolt/test/X86/dwarf4-df-no-base.test | 4 +- ...o-no-convert-low-pc-high-pc-to-ranges.test | 4 +- bolt/test/X86/dwarf4-duplicate-types.test | 8 +- .../dwarf4-ftypes-dwo-input-dwp-output.test | 4 +- ...arf4-ftypes-dwo-mono-input-dwp-output.test | 6 +- .../dwarf4-ftypes-dwp-input-dwo-output.test | 4 +- .../dwarf4-ftypes-dwp-input-dwp-output.test | 4 +- .../dwarf4-gdb-index-types-gdb-generated.test | 2 +- .../dwarf4-gdb-index-types-lld-generated.test | 2 +- ...rence-die-offset-no-internal-dwarf-error.s | 2 +- ...with-internal-dwarf-error-cant-parse-die.s | 2 +- ...et-with-internal-dwarf-error-invalid-die.s | 2 +- bolt/test/X86/dwarf4-sibling.s | 4 +- .../X86/dwarf4-size-0-inlined_subroutine.s | 4 +- .../X86/dwarf4-split-dwarf-no-address.test | 2 +- ...4-split-gdb-index-types-gdb-generated.test | 2 +- ...dwarf4-subprogram-multiple-ranges-cus.test | 38 + .../dwarf4-subprogram-multiple-ranges.test | 2 +- .../dwarf4-subprogram-single-gc-ranges.test | 2 +- .../X86/dwarf4-subprogram-single-ranges.test | 2 +- bolt/test/X86/dwarf4-types-dwarf5-types.test | 2 +- bolt/test/X86/dwarf4-types-dwarf5.test | 2 +- ...4-types-forward-backward-cross-reference.s | 4 +- bolt/test/X86/dwarf4-types.test | 2 +- bolt/test/X86/dwarf5-addr-section-reuse.s | 4 +- .../dwarf5-call-pc-function-null-check.test | 4 +- bolt/test/X86/dwarf5-call-pc.test | 2 +- bolt/test/X86/dwarf5-cu-no-debug-addr.test | 2 +- .../X86/dwarf5-debug-info-dwarf4-debug-line.s | 2 +- .../X86/dwarf5-debug-line-not-modified.test | 2 +- bolt/test/X86/dwarf5-debug-line.s | 2 +- bolt/test/X86/dwarf5-debug-loclists.s | 2 +- .../dwarf5-df-call-site-change-low-pc.test | 2 +- ...f-change-in-dw-op-gnu-addr-index-main.test | 2 +- bolt/test/X86/dwarf5-df-cu-function-gc.test | 2 +- bolt/test/X86/dwarf5-df-dualcu-loclist.test | 2 +- bolt/test/X86/dwarf5-df-dualcu.test | 4 +- ...-inlined-subroutine-gc-sections-range.test | 4 +- .../dwarf5-df-inlined-subroutine-range-0.test | 4 +- .../X86/dwarf5-df-input-lowpc-ranges.test | 4 +- bolt/test/X86/dwarf5-df-mono-dualcu.test | 2 +- .../X86/dwarf5-df-output-dir-same-name.test | 10 +- .../X86/dwarf5-df-types-dup-dwp-input.test | 2 +- ...o-no-convert-low-pc-high-pc-to-ranges.test | 4 +- ...4-gdb-index-types-gdb-generated-gdb11.test | 2 +- ...f4-gdb-index-types-gdb-generated-gdb9.test | 2 +- ...-dwarf4-gdb-index-types-lld-generated.test | 2 +- bolt/test/X86/dwarf5-dwarf4-monolithic.test | 2 +- ...ypes-backward-forward-cross-reference.test | 4 +- ...arf5-ftypes-dwo-mono-input-dwp-output.test | 6 +- .../dwarf5-ftypes-dwp-input-dwo-output.test | 4 +- ...5-gdb-index-types-gdb-generated-gdb11.test | 2 +- ...f5-gdb-index-types-gdb-generated-gdb9.test | 2 +- .../dwarf5-gdb-index-types-lld-generated.test | 2 +- bolt/test/X86/dwarf5-locaddrx.test | 4 +- bolt/test/X86/dwarf5-locexpr-addrx.s | 4 +- bolt/test/X86/dwarf5-locexpr-referrence.test | 2 +- bolt/test/X86/dwarf5-loclist-offset-form.test | 2 +- bolt/test/X86/dwarf5-lowpc-highpc-convert.s | 4 +- .../X86/dwarf5-multiple-dw-op-addrx-locexpr.s | 2 +- .../X86/dwarf5-one-loclists-two-bases.test | 4 +- .../X86/dwarf5-rangeoffset-to-rangeindex.s | 2 +- bolt/test/X86/dwarf5-return-pc-form-addr.test | 2 +- bolt/test/X86/dwarf5-return-pc.test | 2 +- bolt/test/X86/dwarf5-shared-str-offset-base.s | 4 +- .../X86/dwarf5-split-dwarf4-monolithic.test | 6 +- ...5-split-gdb-index-types-gdb-generated.test | 2 +- ...dwarf5-subprogram-multiple-ranges-cus.test | 38 + .../dwarf5-subprogram-multiple-ranges.test | 2 +- .../dwarf5-subprogram-single-gc-ranges.test | 2 +- .../X86/dwarf5-subprogram-single-ranges.test | 2 +- bolt/test/X86/dwarf5-two-loclists.test | 4 +- bolt/test/X86/dwarf5-two-rnglists.test | 4 +- .../dwarf5-types-backward-cross-reference.s | 4 +- .../dwarf5-types-forward-cross-reference.s | 6 +- bolt/test/X86/dynrelocs.s | 46 +- bolt/test/X86/exceptions-args.test | 4 +- bolt/test/X86/fallthrough-to-noop.test | 14 +- bolt/test/X86/false-jump-table.s | 4 +- bolt/test/X86/fatal-error.s | 6 +- bolt/test/X86/fragment-lite-reverse.s | 2 +- bolt/test/X86/fragment-lite.s | 2 +- bolt/test/X86/fragmented-symbols.s | 4 +- bolt/test/X86/frame-opt-lea.s | 6 +- bolt/test/X86/function-order-lite.s | 4 +- bolt/test/X86/gdbindex.test | 18 +- bolt/test/X86/high_pc_udata.s | 4 +- bolt/test/X86/icp-inline.s | 6 +- .../X86/ignored-interprocedural-reference.s | 12 +- bolt/test/X86/indirect-goto-pie.test | 8 +- bolt/test/X86/indirect-goto.test | 4 +- bolt/test/X86/inlined-function-mixed.test | 4 +- bolt/test/X86/insert-addr-rnglists_base.s | 4 +- bolt/test/X86/insert-debug-info-entry.test | 2 +- bolt/test/X86/internal-call-instrument-so.s | 2 +- bolt/test/X86/internal-call-instrument.s | 2 +- .../X86/interprocedural-ref-entry-point.s | 8 +- bolt/test/X86/is-strip.s | 2 +- bolt/test/X86/issue20.s | 6 +- bolt/test/X86/issue20.test | 6 +- bolt/test/X86/issue26.s | 6 +- bolt/test/X86/issue26.test | 2 +- bolt/test/X86/jmp-optimization.test | 6 +- bolt/test/X86/jmpjmp.test | 4 +- bolt/test/X86/jt-symbol-disambiguation-3.s | 20 +- bolt/test/X86/jump-table-fixed-ref-pic.test | 4 +- .../X86/jump-table-footprint-reduction.test | 4 +- bolt/test/X86/jump-table-icp.test | 4 +- bolt/test/X86/jump-table-pic-conflict.s | 36 +- bolt/test/X86/jump-table-pic-order.test | 6 +- bolt/test/X86/jump-table-reference.test | 2 +- bolt/test/X86/layout-heuristic.test | 10 +- bolt/test/X86/line-number.test | 12 +- bolt/test/X86/lit.local.cfg | 2 +- bolt/test/X86/log.test | 8 +- bolt/test/X86/loop-inversion-pass.s | 6 +- bolt/test/X86/loop-nest.test | 2 +- bolt/test/X86/merge-fdata-bat-mode.test | 4 +- bolt/test/X86/merge-fdata-nobat-mode.test | 2 +- bolt/test/X86/merge-fdata-output.test | 4 +- bolt/test/X86/no-entry-reordering.test | 4 +- bolt/test/X86/no-output.test | 2 +- bolt/test/X86/nolbr.s | 6 +- bolt/test/X86/patch-entries.test | 18 +- bolt/test/X86/pre-aggregated-perf.test | 20 +- bolt/test/X86/pt_gnu_relro.s | 4 +- bolt/test/X86/reader-stale-yaml-std.test | 28 +- bolt/test/X86/reader-stale-yaml.test | 40 +- bolt/test/X86/reader.test | 2 +- .../X86/register-fragments-bolt-symbols.s | 16 +- bolt/test/X86/relaxed-tailcall.test | 2 +- bolt/test/X86/remove-unused.test | 6 +- bolt/test/X86/rodata-simpl-loads.test | 6 +- bolt/test/X86/sctc-bug.test | 2 +- bolt/test/X86/sctc-bug2.test | 2 +- bolt/test/X86/sctc-bug3.test | 6 +- bolt/test/X86/sctc-bug4.test | 4 +- bolt/test/X86/shared_object_entry.s | 2 +- bolt/test/X86/shorten-mov.test | 4 +- bolt/test/X86/shrinkwrapping-and-rsp.s | 12 +- bolt/test/X86/shrinkwrapping-critedge.s | 4 +- .../X86/shrinkwrapping-do-not-pessimize.s | 26 +- bolt/test/X86/shrinkwrapping-insertcfi.s | 12 +- bolt/test/X86/shrinkwrapping-lea.s | 6 +- bolt/test/X86/shrinkwrapping-mov.s | 6 +- bolt/test/X86/shrinkwrapping-pop-order.s | 16 +- bolt/test/X86/shrinkwrapping-popf.s | 4 +- .../X86/shrinkwrapping-restore-position.s | 12 +- bolt/test/X86/shrinkwrapping.test | 10 +- bolt/test/X86/split-all-lptrampoline.s | 6 +- bolt/test/X86/split-all.s | 2 +- bolt/test/X86/split-func-icf.s | 22 +- ...lit-func-jump-table-fragment-bidirection.s | 22 +- .../split-func-jump-table-fragment-noparent.s | 18 +- .../split-func-jump-table-fragment-reverse.s | 18 +- .../test/X86/split-func-jump-table-fragment.s | 10 +- bolt/test/X86/split-func-jump-table-unknown.s | 14 +- bolt/test/X86/split-landing-pad.s | 44 +- bolt/test/X86/split-random.s | 2 +- bolt/test/X86/static-exe.test | 2 +- bolt/test/X86/symtab-secondary-entries.test | 4 +- bolt/test/X86/tail-duplication-cache.s | 4 +- bolt/test/X86/tail-duplication-cacheline.s | 4 +- bolt/test/X86/tail-duplication-complex.s | 12 +- bolt/test/X86/tail-duplication-jt.s | 4 +- bolt/test/X86/tail-duplication-pass.s | 2 +- bolt/test/X86/tail-duplication-prop-bug.s | 2 +- bolt/test/X86/tailcall-traps.test | 2 +- bolt/test/X86/tailcall.test | 4 +- bolt/test/X86/unclaimed-jt-entries.s | 4 +- bolt/test/X86/unreachable-jmp.s | 10 +- bolt/test/X86/unreachable.test | 2 +- bolt/test/X86/vararg.test | 6 +- bolt/test/X86/yaml-multiple-profiles.test | 4 +- bolt/test/X86/zero-sized-object.s | 4 +- bolt/test/bad-exe.test | 8 +- bolt/test/bolt-icf.test | 2 +- bolt/test/bolt-info.test | 6 +- bolt/test/heatmap.test | 2 +- bolt/test/invalid-profile.test | 6 +- bolt/test/keep-aranges.test | 4 +- bolt/test/lit.local.cfg | 2 +- bolt/test/lsda-section-name.cpp | 8 +- bolt/test/no-relocs.test | 6 +- bolt/test/non-empty-debug-line.test | 8 +- bolt/test/pie.test | 6 +- bolt/test/re-optimize.test | 6 +- bolt/test/runtime/X86/asm-dump.c | 2 +- bolt/test/shared-object.test | 6 +- .../modernize/UseStdFormatCheck.cpp | 14 +- .../clang-tidy/modernize/UseStdPrintCheck.cpp | 4 + .../readability/ContainerSizeEmptyCheck.cpp | 4 +- .../utils/FormatStringConverter.cpp | 8 +- clang-tools-extra/clang-tidy/utils/Matchers.h | 8 + .../clangd/refactor/tweaks/DefineOutline.cpp | 150 +- .../clangd/unittests/ReplayPeambleTests.cpp | 10 +- .../unittests/tweaks/DefineOutlineTests.cpp | 73 +- clang-tools-extra/docs/ReleaseNotes.rst | 9 + .../modernize/use-std-format-custom.cpp | 18 +- .../modernize/use-std-print-custom.cpp | 26 +- .../readability/container-size-empty.cpp | 28 + clang/README.txt | 2 +- clang/cmake/caches/Fuchsia-stage2.cmake | 1 - clang/cmake/caches/Fuchsia.cmake | 7 - clang/cmake/caches/VectorEngine.cmake | 4 +- clang/docs/ClangFormatStyleOptions.rst | 70 +- clang/docs/ReleaseNotes.rst | 11 + clang/docs/UsersManual.rst | 6 +- clang/docs/analyzer/checkers.rst | 62 +- .../include/clang/APINotes/APINotesManager.h | 2 +- clang/include/clang/AST/RecursiveASTVisitor.h | 10 +- clang/include/clang/AST/TemplateName.h | 4 + clang/include/clang/AST/TextNodeDumper.h | 3 +- .../clang/Analysis/FlowSensitive/ASTOps.h | 47 + .../include/clang/Basic/ASTSourceDescriptor.h | 52 + clang/include/clang/Basic/Attr.td | 48 +- clang/include/clang/Basic/AttrDocs.td | 17 +- .../clang/Basic/CustomizableOptional.h | 8 - clang/include/clang/Basic/DiagnosticGroups.td | 3 + .../clang/Basic/DiagnosticParseKinds.td | 4 + .../clang/Basic/DiagnosticSemaKinds.td | 7 + clang/include/clang/Basic/Module.h | 26 - clang/include/clang/Driver/Options.td | 2 + .../Serialization/SymbolGraphSerializer.h | 1 - clang/include/clang/Format/Format.h | 68 +- .../clang/Lex/DependencyDirectivesScanner.h | 3 +- clang/include/clang/Sema/Attr.h | 36 + clang/include/clang/Sema/Sema.h | 218 +- clang/include/clang/Sema/SemaAMDGPU.h | 68 + clang/include/clang/Sema/SemaARM.h | 63 + clang/include/clang/Sema/SemaBPF.h | 28 + clang/include/clang/Sema/SemaBase.h | 3 + clang/include/clang/Sema/SemaHLSL.h | 1 + clang/include/clang/Sema/SemaHexagon.h | 29 + clang/include/clang/Sema/SemaInternal.h | 4 - clang/include/clang/Sema/SemaLoongArch.h | 30 + clang/include/clang/Sema/SemaMIPS.h | 33 + clang/include/clang/Sema/SemaNVPTX.h | 30 + clang/include/clang/Sema/SemaPPC.h | 58 + clang/include/clang/Sema/SemaSystemZ.h | 28 + clang/include/clang/Sema/SemaWasm.h | 52 + clang/include/clang/Serialization/ASTReader.h | 5 + clang/include/clang/Serialization/ASTWriter.h | 1 - .../clang/Serialization/ModuleManager.h | 1 - .../clang/StaticAnalyzer/Checkers/Checkers.td | 8 +- .../DependencyScanningFilesystem.h | 3 +- clang/lib/APINotes/APINotesManager.cpp | 1 + clang/lib/AST/ASTContext.cpp | 2 +- clang/lib/AST/ASTDumper.cpp | 1 - clang/lib/AST/Decl.cpp | 8 +- clang/lib/AST/DeclBase.cpp | 3 +- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/AST/QualTypeNames.cpp | 5 +- clang/lib/AST/TextNodeDumper.cpp | 43 +- clang/lib/Analysis/FlowSensitive/ASTOps.cpp | 114 +- .../FlowSensitive/DataflowEnvironment.cpp | 37 +- clang/lib/Basic/ASTSourceDescriptor.cpp | 33 + clang/lib/Basic/CMakeLists.txt | 1 + clang/lib/Basic/Module.cpp | 15 - clang/lib/Basic/Targets/AArch64.cpp | 1 + clang/lib/Basic/Targets/X86.cpp | 31 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/BackendUtil.cpp | 17 - clang/lib/CodeGen/CGBuiltin.cpp | 6 +- clang/lib/CodeGen/CGCUDANV.cpp | 10 +- clang/lib/CodeGen/CGDebugInfo.h | 3 +- clang/lib/CodeGen/CGExprAgg.cpp | 7 +- clang/lib/CodeGen/CGObjCGNU.cpp | 9 +- clang/lib/CodeGen/CodeGenModule.cpp | 17 +- clang/lib/CodeGen/CodeGenModule.h | 1 - clang/lib/Driver/ToolChains/Arch/X86.cpp | 2 + clang/lib/Driver/ToolChains/SPIRV.cpp | 12 +- clang/lib/ExtractAPI/API.cpp | 1 - clang/lib/Format/FormatToken.h | 23 + clang/lib/Format/TokenAnnotator.cpp | 6 +- clang/lib/Format/UnwrappedLineParser.cpp | 18 +- clang/lib/Frontend/FrontendActions.cpp | 11 +- clang/lib/Headers/cuda_wrappers/algorithm | 2 +- clang/lib/Headers/intrin.h | 19 + clang/lib/Headers/ptrauth.h | 13 + clang/lib/Lex/DependencyDirectivesScanner.cpp | 22 +- clang/lib/Parse/ParseExprCXX.cpp | 26 +- clang/lib/Parse/ParseOpenMP.cpp | 65 +- clang/lib/Sema/CMakeLists.txt | 10 + clang/lib/Sema/Sema.cpp | 24 + clang/lib/Sema/SemaAMDGPU.cpp | 311 ++ clang/lib/Sema/SemaARM.cpp | 1088 ++++++ clang/lib/Sema/SemaAvailability.cpp | 24 +- clang/lib/Sema/SemaBPF.cpp | 174 + clang/lib/Sema/SemaBase.cpp | 4 + clang/lib/Sema/SemaCast.cpp | 7 +- clang/lib/Sema/SemaChecking.cpp | 3064 +---------------- clang/lib/Sema/SemaDecl.cpp | 14 +- clang/lib/Sema/SemaDeclAttr.cpp | 445 +-- clang/lib/Sema/SemaDeclObjC.cpp | 38 +- clang/lib/Sema/SemaExprCXX.cpp | 3 +- clang/lib/Sema/SemaExprObjC.cpp | 10 +- clang/lib/Sema/SemaHLSL.cpp | 297 ++ clang/lib/Sema/SemaHexagon.cpp | 290 ++ clang/lib/Sema/SemaLoongArch.cpp | 515 +++ clang/lib/Sema/SemaMIPS.cpp | 240 ++ clang/lib/Sema/SemaNVPTX.cpp | 35 + clang/lib/Sema/SemaOpenACC.cpp | 72 + clang/lib/Sema/SemaOpenMP.cpp | 18 +- clang/lib/Sema/SemaOverload.cpp | 2 +- clang/lib/Sema/SemaPPC.cpp | 439 +++ clang/lib/Sema/SemaSystemZ.cpp | 94 + clang/lib/Sema/SemaTemplate.cpp | 2 +- clang/lib/Sema/SemaTemplateDeduction.cpp | 29 +- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 +- clang/lib/Sema/SemaWasm.cpp | 341 ++ clang/lib/Serialization/ASTReader.cpp | 16 + clang/lib/Serialization/ASTReaderDecl.cpp | 6 +- clang/lib/Serialization/ASTWriter.cpp | 4 +- clang/lib/Serialization/ASTWriterDecl.cpp | 2 +- .../DependencyScanningFilesystem.cpp | 4 +- .../DependencyScanningWorker.cpp | 9 +- clang/lib/Tooling/JSONCompilationDatabase.cpp | 5 +- clang/test/AST/ast-dump-ctad-alias.cpp | 6 +- clang/test/AST/ast-dump-template-decls.cpp | 14 +- clang/test/AST/ast-dump-template-name.cpp | 6 + clang/test/AST/ast-dump-using-template.cpp | 18 +- .../test/Analysis/analyzer-enabled-checkers.c | 1 + .../test/Analysis/block-in-critical-section.c | 2 +- .../Analysis/block-in-critical-section.cpp | 33 +- .../test/Analysis/block-in-critical-section.m | 2 +- clang/test/Analysis/builtin_signbit.cpp | 36 +- clang/test/Analysis/cfg-openmp.cpp | 17 +- ...c-library-functions-arg-enabled-checkers.c | 1 + clang/test/C/C11/n1464.c | 22 + clang/test/CXX/drs/cwg0xx.cpp | 3 +- clang/test/CXX/drs/cwg1xx.cpp | 40 + clang/test/CXX/drs/cwg24xx.cpp | 14 +- clang/test/CXX/drs/cwg2630.cpp | 12 +- clang/test/CXX/drs/cwg26xx.cpp | 16 +- clang/test/CXX/drs/cwg27xx.cpp | 14 +- clang/test/CXX/drs/cwg28xx.cpp | 95 +- clang/test/CodeGen/X86/ms-x86-intrinsics.c | 25 + .../CodeGen/X86/x86_64-instrument-functions.c | 39 +- .../aarch64-sme-intrinsics/acle_sme_add-i64.c | 10 +- .../acle_sme_mopa-za64.c | 10 +- .../acle_sme_mops-za64.c | 10 +- .../aarch64-sme2-attrs.cpp | 2 +- .../aarch64-sme2-intrinsics/acle_sme2_add.c | 10 +- .../acle_sme2_add_sub_za16.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_bmop.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_clamp.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_cvt.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_cvtn.c | 10 +- .../acle_sme2_fmlas16.c | 10 +- .../acle_sme2_fp_dots.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_frint.c | 10 +- .../acle_sme2_int_dots.c | 10 +- .../acle_sme2_luti2_lane_zt.c | 6 +- .../acle_sme2_luti2_lane_zt_x2.c | 6 +- .../acle_sme2_luti2_lane_zt_x4.c | 6 +- .../acle_sme2_luti4_lane_zt.c | 6 +- .../acle_sme2_luti4_lane_zt_x2.c | 6 +- .../acle_sme2_luti4_lane_zt_x4.c | 6 +- .../aarch64-sme2-intrinsics/acle_sme2_max.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_maxnm.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_min.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_minnm.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mla.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mlal.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mlall.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mls.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mlsl.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_mop.c | 10 +- .../acle_sme2_mopa_nonwide.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_read.c | 6 +- .../acle_sme2_reinterpret_svcount_svbool.c | 12 +- .../acle_sme2_sqdmulh.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_sub.c | 10 +- .../acle_sme2_unpkx2.c | 12 +- .../acle_sme2_unpkx4.c | 12 +- .../aarch64-sme2-intrinsics/acle_sme2_vdot.c | 10 +- .../acle_sme2_vector_add.c | 10 +- .../acle_sme2_vector_qrshr.c | 10 +- .../acle_sme2_vector_rshl.c | 10 +- .../acle_sme2_vector_selx2.c | 10 +- .../acle_sme2_vector_selx4.c | 10 +- .../acle_sme2_vector_uzpx2.c | 10 +- .../acle_sme2_vector_uzpx4.c | 10 +- .../acle_sme2_vector_zipx2.c | 10 +- .../acle_sme2_vector_zipx4.c | 10 +- .../aarch64-sme2-intrinsics/acle_sme2_write.c | 10 +- .../acle_sme2p1_zero.c | 6 +- .../acle_sve_create2-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_create2.c | 8 +- .../acle_sve_create3-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_create3.c | 8 +- .../acle_sve_create4-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_create4.c | 8 +- .../acle_sve_get2-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_get2.c | 8 +- .../acle_sve_get3-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_get3.c | 8 +- .../acle_sve_get4-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_get4.c | 8 +- .../acle_sve_set2-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_set2.c | 8 +- .../acle_sve_set3-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_set3.c | 8 +- .../acle_sve_set4-bfloat.c | 8 +- .../aarch64-sve-intrinsics/acle_sve_set4.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_aba.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_abalb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_abalt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_abdlb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_abdlt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_adalp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_adclb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_adclt.c | 8 +- .../acle_sve2_addhnb.c | 8 +- .../acle_sve2_addhnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_addlb.c | 8 +- .../acle_sve2_addlbt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_addlt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_addp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_addwb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_addwt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_aesd.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_aese.c | 8 +- .../acle_sve2_aesimc.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_aesmc.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bcax.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bdep.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bext.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bgrp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bsl.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bsl1n.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_bsl2n.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cadd.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cdot.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cmla.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cvtlt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cvtnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_cvtx.c | 8 +- .../acle_sve2_cvtxnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_eor3.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_eorbt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_eortb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_hadd.c | 8 +- .../acle_sve2_histcnt.c | 8 +- .../acle_sve2_histseg.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_hsub.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_hsubr.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_ldnt1.c | 8 +- .../acle_sve2_ldnt1sb.c | 8 +- .../acle_sve2_ldnt1sh.c | 8 +- .../acle_sve2_ldnt1sw.c | 8 +- .../acle_sve2_ldnt1ub.c | 8 +- .../acle_sve2_ldnt1uh.c | 8 +- .../acle_sve2_ldnt1uw.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_logb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_match.c | 8 +- .../acle_sve2_maxnmp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_maxp.c | 8 +- .../acle_sve2_minnmp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_minp.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mla.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mlalb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mlalt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mls.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mlslb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mlslt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_movlb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_movlt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mul.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mullb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_mullt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_nbsl.c | 8 +- .../acle_sve2_nmatch.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_pmul.c | 8 +- .../acle_sve2_pmullb.c | 8 +- .../acle_sve2_pmullb_128.c | 8 +- .../acle_sve2_pmullt.c | 8 +- .../acle_sve2_pmullt_128.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qabs.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qadd.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qcadd.c | 8 +- .../acle_sve2_qdmlalb.c | 8 +- .../acle_sve2_qdmlalbt.c | 8 +- .../acle_sve2_qdmlalt.c | 8 +- .../acle_sve2_qdmlslb.c | 8 +- .../acle_sve2_qdmlslbt.c | 8 +- .../acle_sve2_qdmlslt.c | 8 +- .../acle_sve2_qdmulh.c | 8 +- .../acle_sve2_qdmullb.c | 8 +- .../acle_sve2_qdmullt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qneg.c | 8 +- .../acle_sve2_qrdcmlah.c | 8 +- .../acle_sve2_qrdmlah.c | 8 +- .../acle_sve2_qrdmlsh.c | 8 +- .../acle_sve2_qrdmulh.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qrshl.c | 8 +- .../acle_sve2_qrshrnb.c | 8 +- .../acle_sve2_qrshrnt.c | 8 +- .../acle_sve2_qrshrunb.c | 8 +- .../acle_sve2_qrshrunt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qshl.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qshlu.c | 8 +- .../acle_sve2_qshrnb.c | 8 +- .../acle_sve2_qshrnt.c | 8 +- .../acle_sve2_qshrunb.c | 8 +- .../acle_sve2_qshrunt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qsub.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qsubr.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qxtnb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_qxtnt.c | 8 +- .../acle_sve2_qxtunb.c | 8 +- .../acle_sve2_qxtunt.c | 8 +- .../acle_sve2_raddhnb.c | 8 +- .../acle_sve2_raddhnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_rax1.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_recpe.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_revd.c | 12 +- .../aarch64-sve2-intrinsics/acle_sve2_rhadd.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_rshl.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_rshr.c | 8 +- .../acle_sve2_rshrnb.c | 8 +- .../acle_sve2_rshrnt.c | 8 +- .../acle_sve2_rsqrte.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_rsra.c | 8 +- .../acle_sve2_rsubhnb.c | 8 +- .../acle_sve2_rsubhnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sbclb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sbclt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_shllb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_shllt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_shrnb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_shrnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sli.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sm4e.c | 8 +- .../acle_sve2_sm4ekey.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sqadd.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sra.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sri.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_stnt1.c | 8 +- .../acle_sve2_stnt1b.c | 8 +- .../acle_sve2_stnt1h.c | 8 +- .../acle_sve2_stnt1w.c | 8 +- .../acle_sve2_subhnb.c | 8 +- .../acle_sve2_subhnt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sublb.c | 8 +- .../acle_sve2_sublbt.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_sublt.c | 8 +- .../acle_sve2_subltb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_subwb.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_subwt.c | 8 +- .../acle_sve2_tbl2-bfloat.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_tbl2.c | 8 +- .../acle_sve2_tbx-bfloat.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_tbx.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_uqadd.c | 8 +- .../acle_sve2_whilege.c | 8 +- .../acle_sve2_whilegt.c | 8 +- .../acle_sve2_whilerw-bfloat.c | 8 +- .../acle_sve2_whilerw.c | 8 +- .../acle_sve2_whilewr-bfloat.c | 8 +- .../acle_sve2_whilewr.c | 8 +- .../aarch64-sve2-intrinsics/acle_sve2_xar.c | 8 +- .../acle_sve2p1_bfadd.c | 12 +- .../acle_sve2p1_bfclamp.c | 10 +- .../acle_sve2p1_bfmax.c | 12 +- .../acle_sve2p1_bfmaxnm.c | 12 +- .../acle_sve2p1_bfmin.c | 12 +- .../acle_sve2p1_bfminnm.c | 12 +- .../acle_sve2p1_bfmla.c | 12 +- .../acle_sve2p1_bfmla_lane.c | 10 +- .../acle_sve2p1_bfmls.c | 12 +- .../acle_sve2p1_bfmls_lane.c | 10 +- .../acle_sve2p1_bfmlsl.c | 22 +- .../acle_sve2p1_bfmul.c | 12 +- .../acle_sve2p1_bfmul_lane.c | 10 +- .../acle_sve2p1_bfsub.c | 12 +- .../acle_sve2p1_cntp.c | 20 +- .../acle_sve2p1_create2_bool.c | 16 +- .../acle_sve2p1_create4_bool.c | 22 +- .../acle_sve2p1_dot.c | 22 +- .../acle_sve2p1_dupq.c | 10 +- .../acle_sve2p1_extq.c | 10 +- .../acle_sve2p1_fclamp.c | 20 +- .../acle_sve2p1_fp_reduce.c | 10 +- .../acle_sve2p1_get2_bool.c | 22 +- .../acle_sve2p1_get4_bool.c | 16 +- .../acle_sve2p1_int_reduce.c | 10 +- .../acle_sve2p1_ld1.c | 22 +- .../acle_sve2p1_ld1_single.c | 10 +- .../acle_sve2p1_ldnt1.c | 18 +- .../acle_sve2p1_loads.c | 10 +- .../acle_sve2p1_pext.c | 18 +- .../acle_sve2p1_pfalse.c | 18 +- .../acle_sve2p1_pmov_to_pred.c | 10 +- .../acle_sve2p1_pmov_to_vector.c | 10 +- .../acle_sve2p1_psel.c | 26 +- .../acle_sve2p1_psel_svcount.c | 26 +- .../acle_sve2p1_ptrue.c | 14 +- .../acle_sve2p1_qcvtn.c | 22 +- .../acle_sve2p1_qrshr.c | 14 +- .../acle_sve2p1_sclamp.c | 28 +- .../acle_sve2p1_set2_bool.c | 22 +- .../acle_sve2p1_set4_bool.c | 22 +- .../acle_sve2p1_st1.c | 18 +- .../acle_sve2p1_st1_single.c | 10 +- .../acle_sve2p1_stnt1.c | 18 +- .../acle_sve2p1_store.c | 10 +- .../acle_sve2p1_tblq.c | 10 +- .../acle_sve2p1_tbxq.c | 10 +- .../acle_sve2p1_uclamp.c | 28 +- .../acle_sve2p1_undef_bool.c | 10 +- .../acle_sve2p1_uzpq1.c | 10 +- .../acle_sve2p1_uzpq2.c | 10 +- .../acle_sve2p1_while_pn.c | 14 +- .../acle_sve2p1_while_x2.c | 18 +- .../acle_sve2p1_zipq1.c | 10 +- .../acle_sve2p1_zipq2.c | 10 +- .../CodeGen/arm-vector_type-params-returns.c | 8 +- .../catch-nullptr-and-nonzero-offset.c | 62 +- clang/test/CodeGen/constantexpr-fneg.c | 3 +- clang/test/CodeGen/instrument-objc-method.m | 32 +- clang/test/CodeGen/lto-newpm-pipeline.c | 6 +- clang/test/CodeGen/mcount-aix.c | 24 +- clang/test/CodeGen/mcount.c | 84 +- clang/test/CodeGen/object-size.c | 2 +- clang/test/CodeGen/preserve-call-conv.c | 6 +- ...initializer-stdinitializerlist-pr12086.cpp | 8 +- ...nitializer-stdinitializerlist-startend.cpp | 1 - .../cxx0x-initializer-stdinitializerlist.cpp | 1 - clang/test/CodeGenCXX/cxx11-thread-local.cpp | 20 +- .../test/CodeGenCXX/debug-info-ptr-to-ptr.cpp | 8 +- .../test/CodeGenCXX/ubsan-nullability-arg.cpp | 3 +- clang/test/CodeGenCXX/weak-external.cpp | 15 +- clang/test/CodeGenHLSL/cbuf.hlsl | 4 +- clang/test/Driver/aarch64-outliner.c | 1 - clang/test/Driver/amdgcn-gz-options.cl | 2 +- clang/test/Driver/amdgpu-hip-system-arch.c | 2 - clang/test/Driver/amdgpu-invalid-target-id.s | 3 - clang/test/Driver/amdgpu-macros.cl | 2 +- clang/test/Driver/amdgpu-mcpu.cl | 2 + .../Driver/amdgpu-openmp-system-arch-fail.c | 2 - clang/test/Driver/amdgpu-openmp-toolchain.c | 2 - .../test/Driver/arm-float-abi-runtime-path.c | 2 - clang/test/Driver/arm-float-abi.c | 1 - clang/test/Driver/arm-machine-outliner.c | 1 - clang/test/Driver/cl-options.cu | 3 - .../test/Driver/clang-offload-bundler-zlib.c | 1 - .../test/Driver/clang-offload-bundler-zstd.c | 1 - clang/test/Driver/compress-noias.c | 1 - clang/test/Driver/cuda-arch-translation.cu | 3 - clang/test/Driver/cuda-bad-arch.cu | 3 - clang/test/Driver/cuda-bail-out.cu | 3 - clang/test/Driver/cuda-bindings.cu | 3 - clang/test/Driver/cuda-constructor-alias.cu | 3 - clang/test/Driver/cuda-cross-compiling.c | 2 - clang/test/Driver/cuda-detect-path.cu | 2 - clang/test/Driver/cuda-detect.cu | 3 - clang/test/Driver/cuda-external-tools.cu | 3 - clang/test/Driver/cuda-macosx.cu | 3 - clang/test/Driver/cuda-march.cu | 3 - .../cuda-omp-unsupported-debug-options.cu | 2 - clang/test/Driver/cuda-openmp-driver.cu | 3 - clang/test/Driver/cuda-options.cu | 2 - clang/test/Driver/cuda-output-asm.cu | 3 - clang/test/Driver/cuda-phases.cu | 3 - clang/test/Driver/cuda-ptxas-path.cu | 3 - clang/test/Driver/cuda-version-check.cu | 3 - clang/test/Driver/cuda-windows.cu | 3 - clang/test/Driver/debug-options.c | 5 +- clang/test/Driver/driverkit-arm64.c | 1 - clang/test/Driver/driverkit-arm64e.c | 1 - clang/test/Driver/driverkit-cplusplus.cpp | 1 - clang/test/Driver/driverkit-exceptions.cpp | 1 - clang/test/Driver/driverkit-path.c | 1 - clang/test/Driver/driverkit-rtti.cpp | 1 - clang/test/Driver/driverkit-target-cpu.c | 1 - .../test/Driver/dwarf-target-version-clamp.cu | 3 - clang/test/Driver/elfiamcu-header-search.c | 2 - clang/test/Driver/global-isel.c | 2 - clang/test/Driver/gpu-libc-headers.c | 3 - clang/test/Driver/hexagon-toolchain-elf.c | 1 - clang/test/Driver/hip-autolink.hip | 3 - clang/test/Driver/hip-binding.hip | 3 - clang/test/Driver/hip-code-object-version.hip | 3 - clang/test/Driver/hip-cuid-hash.hip | 3 - clang/test/Driver/hip-cuid.hip | 3 - clang/test/Driver/hip-default-gpu-arch.hip | 3 - clang/test/Driver/hip-device-compile.hip | 3 - clang/test/Driver/hip-device-libs.hip | 3 - clang/test/Driver/hip-fpie-option.hip | 2 +- .../test/Driver/hip-gsplit-dwarf-options.hip | 2 +- clang/test/Driver/hip-gz-options.hip | 2 +- clang/test/Driver/hip-host-cpu-features.hip | 3 - clang/test/Driver/hip-include-path.hip | 2 - clang/test/Driver/hip-inputs.hip | 3 - clang/test/Driver/hip-invalid-target-id.hip | 3 - clang/test/Driver/hip-launch-api.hip | 3 - clang/test/Driver/hip-link-bc-to-bc.hip | 2 - clang/test/Driver/hip-link-bundle-archive.hip | 2 - clang/test/Driver/hip-link-save-temps.hip | 3 - clang/test/Driver/hip-link-static-library.hip | 3 - clang/test/Driver/hip-no-device-libs.hip | 3 - clang/test/Driver/hip-offload-arch.hip | 2 - .../test/Driver/hip-offload-compress-zlib.hip | 2 - .../test/Driver/hip-offload-compress-zstd.hip | 2 - clang/test/Driver/hip-options.hip | 5 +- clang/test/Driver/hip-output-file-name.hip | 3 - clang/test/Driver/hip-phases.hip | 3 - clang/test/Driver/hip-printf.hip | 3 - clang/test/Driver/hip-rdc-device-only.hip | 3 - clang/test/Driver/hip-sanitize-options.hip | 2 - clang/test/Driver/hip-save-temps.hip | 3 - clang/test/Driver/hip-std.hip | 3 - clang/test/Driver/hip-syntax-only.hip | 3 - clang/test/Driver/hip-target-id.hip | 3 - .../test/Driver/hip-toolchain-device-only.hip | 2 - clang/test/Driver/hip-toolchain-dwarf.hip | 3 - clang/test/Driver/hip-toolchain-features.hip | 3 - clang/test/Driver/hip-toolchain-mllvm.hip | 3 - clang/test/Driver/hip-toolchain-no-rdc.hip | 3 - clang/test/Driver/hip-toolchain-opt.hip | 3 - .../Driver/hip-toolchain-rdc-separate.hip | 3 - .../Driver/hip-toolchain-rdc-static-lib.hip | 3 - clang/test/Driver/hip-toolchain-rdc.hip | 3 - clang/test/Driver/hip-unbundle-preproc.hipi | 2 - clang/test/Driver/hip-wavefront-size.hip | 2 - clang/test/Driver/hip-windows-filename.hip | 2 +- clang/test/Driver/hipspv-device-libs.hip | 1 - clang/test/Driver/hipspv-pass-plugin.hip | 1 - clang/test/Driver/hipspv-toolchain-rdc.hip | 1 - clang/test/Driver/hipspv-toolchain.hip | 14 +- clang/test/Driver/indirect-tls-seg-refs.c | 2 - clang/test/Driver/invalid-offload-options.cpp | 1 - clang/test/Driver/invalid-target-id.cl | 3 - clang/test/Driver/linker-wrapper-image.c | 100 +- clang/test/Driver/lto.cu | 3 - clang/test/Driver/m68k-features.cpp | 1 - clang/test/Driver/mbackchain.c | 1 - clang/test/Driver/mips-abi.c | 2 - clang/test/Driver/mips-abicalls-warning.c | 1 - clang/test/Driver/mips-cs.cpp | 2 - clang/test/Driver/mips-fsf.cpp | 2 - clang/test/Driver/mips-gpopt-warning.c | 1 - clang/test/Driver/mips-img-v2.cpp | 2 - clang/test/Driver/mips-img.cpp | 2 - clang/test/Driver/mips-indirect-branch.c | 1 - clang/test/Driver/mips-mti-linux.c | 1 - clang/test/Driver/msan.c | 2 - clang/test/Driver/nvptx-cuda-system-arch.c | 2 - .../test/Driver/offloading-interoperability.c | 5 +- clang/test/Driver/openmp-offload-gpu.c | 6 +- clang/test/Driver/openmp-offload-headers.c | 3 - clang/test/Driver/openmp-offload-infer.c | 4 - clang/test/Driver/openmp-offload-jit.c | 4 - clang/test/Driver/openmp-offload.c | 4 - clang/test/Driver/openmp-system-arch.c | 3 - clang/test/Driver/ppc-dependent-options.cpp | 1 - clang/test/Driver/ppc-float-abi-warning.cpp | 1 - clang/test/Driver/ppc-unsupported.c | 1 - clang/test/Driver/riscv32-toolchain-extra.c | 2 +- clang/test/Driver/riscv64-toolchain-extra.c | 2 +- clang/test/Driver/rocm-detect.cl | 2 - clang/test/Driver/rocm-detect.hip | 2 - clang/test/Driver/rocm-device-libs.cl | 1 - clang/test/Driver/save-temps.c | 3 - clang/test/Driver/spirv-toolchain.cl | 10 + clang/test/Driver/sysroot.c | 5 +- clang/test/Driver/target-id-macros.cl | 3 - clang/test/Driver/target-id.cl | 3 - clang/test/Driver/thinlto.cu | 3 - clang/test/Driver/tsan.c | 2 - clang/test/Driver/ve-toolchain.c | 1 - clang/test/Driver/ve-toolchain.cpp | 1 - .../Driver/x86-apx-inline-asm-use-gpr32.cpp | 3 + clang/test/Frontend/gnu-mcount.c | 64 +- clang/test/Headers/cuda_wrapper_algorithm.cu | 48 + clang/test/Import/builtin-template/test.cpp | 11 +- clang/test/Interpreter/incremental-mode.cpp | 2 + clang/test/Misc/target-invalid-cpu-note.c | 2 +- clang/test/Modules/cxx20-decls.cppm | 35 + clang/test/Modules/pr93859.cppm | 146 + clang/test/OpenMP/for_private_codegen.cpp | 2 +- clang/test/OpenMP/for_reduction_codegen.cpp | 78 +- .../test/OpenMP/for_reduction_codegen_UDR.cpp | 252 +- .../nvptx_target_cuda_mode_messages.cpp | 18 - clang/test/OpenMP/parallel_copyin_codegen.cpp | 154 +- ...l_master_taskloop_firstprivate_codegen.cpp | 316 +- ...el_master_taskloop_lastprivate_codegen.cpp | 334 +- ...ter_taskloop_simd_firstprivate_codegen.cpp | 316 +- ...ster_taskloop_simd_lastprivate_codegen.cpp | 370 +- .../OpenMP/sections_lastprivate_codegen.cpp | 28 +- .../test/OpenMP/sections_private_codegen.cpp | 12 +- .../OpenMP/sections_reduction_codegen.cpp | 32 +- clang/test/OpenMP/single_private_codegen.cpp | 2 +- .../test/OpenMP/target_reduction_codegen.cpp | 231 -- .../test/OpenMP/target_reduction_messages.cpp | 304 -- clang/test/OpenMP/target_vla_messages.cpp | 6 - clang/test/OpenMP/threadprivate_codegen.cpp | 104 +- .../test/Preprocessor/riscv-target-features.c | 18 +- clang/test/Preprocessor/x86_target_features.c | 5 + .../Sema/aarch64-incompat-sm-builtin-calls.c | 2 +- clang/test/Sema/aarch64-sme-func-attrs.c | 4 +- .../acle_sme2_b16b16.cpp | 2 +- .../aarch64-sme2-intrinsics/acle_sme2_imm.cpp | 2 +- clang/test/Sema/aarch64-sme2p1-diagnostics.c | 2 +- .../acle_sve2_bfloat.cpp | 2 +- .../acle_sve2_imm_n.cpp | 4 +- .../acle_sve2p1_imm.cpp | 2 +- .../Sema/warn-cast-function-type-strict.c | 9 + clang/test/Sema/warn-cast-function-type.c | 9 + .../cxx1y-variable-templates_in_class.cpp | 6 +- .../test/SemaCXX/incomplete-array-extent.cpp | 5 + .../test/SemaCXX/template-specialization.cpp | 2 +- .../warn-cast-function-type-strict.cpp | 9 + .../test/SemaCXX/warn-cast-function-type.cpp | 9 + .../attr-availability-compute.hlsl | 19 +- .../Availability/attr-availability-mesh.hlsl | 19 +- .../Availability/attr-availability-pixel.hlsl | 6 +- .../avail-diag-default-compute.hlsl | 119 + .../Availability/avail-diag-default-lib.hlsl | 130 + .../avail-diag-relaxed-compute.hlsl | 119 + .../Availability/avail-diag-relaxed-lib.hlsl | 130 + .../avail-lib-multiple-stages.hlsl | 57 + .../SemaHLSL/WaveBuiltinAvailability.hlsl | 9 +- clang/test/SemaObjCXX/block-capture.mm | 18 + .../compute-construct-async-clause.c | 5 + .../compute-construct-attach-clause.c | 5 + .../compute-construct-copy-clause.c | 13 + .../compute-construct-copyin-clause.c | 13 + .../compute-construct-copyout-clause.c | 13 + .../compute-construct-create-clause.c | 13 + .../compute-construct-default-clause.c | 5 + .../compute-construct-device_type-clause.c | 7 + .../compute-construct-deviceptr-clause.c | 5 + .../compute-construct-firstprivate-clause.c | 5 + .../SemaOpenACC/compute-construct-if-clause.c | 5 + .../compute-construct-no_create-clause.c | 5 + .../compute-construct-num_gangs-clause.c | 5 + .../compute-construct-num_workers-clause.c | 5 + .../compute-construct-present-clause.c | 5 + .../compute-construct-private-clause.c | 5 + .../compute-construct-reduction-clause.c | 5 + .../compute-construct-self-clause.c | 5 + .../compute-construct-vector_length-clause.c | 5 + .../compute-construct-wait-clause.c | 5 + .../aggregate-deduction-candidate.cpp | 4 +- clang/test/SemaTemplate/concepts-lambda.cpp | 12 + clang/test/SemaTemplate/concepts.cpp | 22 + clang/test/SemaTemplate/deduction-guide.cpp | 22 +- clang/test/SemaTemplate/dependent-names.cpp | 6 +- clang/test/SemaTemplate/make_integer_seq.cpp | 50 +- clang/test/SemaTemplate/template-id-expr.cpp | 36 +- .../SemaTemplate/template-id-printing.cpp | 13 - clang/test/SemaTemplate/type_pack_element.cpp | 34 +- clang/test/lit.site.cfg.py.in | 1 + clang/tools/scan-build/bin/set-xcode-analyzer | 2 +- clang/unittests/Format/FormatTest.cpp | 9 +- clang/unittests/Format/TokenAnnotatorTest.cpp | 43 +- .../Interpreter/CodeCompletionTest.cpp | 228 +- .../InterpreterExceptionTest.cpp | 14 +- .../Interpreter/IncrementalProcessingTest.cpp | 24 +- .../Interpreter/InterpreterExtensionsTest.cpp | 67 +- .../unittests/Interpreter/InterpreterTest.cpp | 101 +- .../Interpreter/InterpreterTestFixture.h | 59 + .../Lex/DependencyDirectivesScannerTest.cpp | 82 +- .../Lex/PPDependencyDirectivesTest.cpp | 3 +- .../Tooling/CompilationDatabaseTest.cpp | 1 - clang/utils/TableGen/MveEmitter.cpp | 9 +- clang/utils/analyzer/entrypoint.py | 2 +- clang/utils/check_cfc/check_cfc.py | 4 +- clang/www/analyzer/alpha_checks.html | 33 - clang/www/c_status.html | 2 +- clang/www/cxx_dr_status.html | 62 +- compiler-rt/cmake/config-ix.cmake | 15 - compiler-rt/lib/msan/msan.cpp | 2 +- .../symbolizer/scripts/build_symbolizer.sh | 1 - compiler-rt/lib/xray/tests/CMakeLists.txt | 5 - .../test/asan/TestCases/debug_double_free.cpp | 4 +- .../test/asan/TestCases/debug_report.cpp | 4 +- ...anitizer_coverage_allowlist_ignorelist.cpp | 4 +- flang/docs/Extensions.md | 18 + flang/examples/FeatureList/FeatureList.cpp | 5 +- flang/include/flang/Common/Fortran-features.h | 10 +- flang/include/flang/Evaluate/integer.h | 2 +- flang/include/flang/Evaluate/tools.h | 5 +- .../include/flang/Lower/ConvertExprToHLFIR.h | 9 +- .../flang/Optimizer/Builder/HLFIRTools.h | 19 +- .../flang/Optimizer/Builder/IntrinsicCall.h | 5 +- .../flang/Optimizer/Builder/Runtime/Support.h | 4 + .../flang/Optimizer/CodeGen/FIROpPatterns.h | 6 + .../flang/Optimizer/CodeGen/TypeConverter.h | 6 + .../include/flang/Optimizer/Dialect/FIROps.td | 31 +- .../flang/Optimizer/Dialect/FIROpsSupport.h | 1 + .../flang/Optimizer/Transforms/Passes.h | 8 +- .../flang/Optimizer/Transforms/Passes.td | 5 +- flang/include/flang/Parser/dump-parse-tree.h | 5 +- flang/include/flang/Parser/parse-tree.h | 36 +- flang/include/flang/Runtime/support.h | 3 + flang/include/flang/Semantics/symbol.h | 1 + flang/include/flang/Tools/CLOptions.inc | 5 +- flang/lib/Evaluate/check-expression.cpp | 10 +- flang/lib/Evaluate/fold-real.cpp | 7 +- flang/lib/Evaluate/intrinsics.cpp | 61 +- flang/lib/Evaluate/tools.cpp | 8 +- flang/lib/Lower/Allocatable.cpp | 2 +- flang/lib/Lower/Bridge.cpp | 207 +- flang/lib/Lower/ConvertCall.cpp | 88 +- flang/lib/Lower/ConvertExprToHLFIR.cpp | 10 +- flang/lib/Lower/ConvertVariable.cpp | 3 +- flang/lib/Lower/OpenACC.cpp | 27 +- .../lib/Optimizer/Analysis/AliasAnalysis.cpp | 12 +- flang/lib/Optimizer/Builder/HLFIRTools.cpp | 54 +- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 11 +- .../lib/Optimizer/Builder/Runtime/Support.cpp | 10 + flang/lib/Optimizer/CodeGen/CodeGen.cpp | 42 +- flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp | 31 + flang/lib/Optimizer/CodeGen/TypeConverter.cpp | 9 +- flang/lib/Optimizer/Dialect/FIROps.cpp | 24 + .../HLFIR/Transforms/BufferizeHLFIR.cpp | 5 + .../lib/Optimizer/Transforms/AddDebugInfo.cpp | 7 +- .../Transforms/AssumedRankOpConversion.cpp | 26 + .../Transforms/OMPFunctionFiltering.cpp | 4 - .../Transforms/OMPMapInfoFinalization.cpp | 30 +- .../Transforms/OMPMarkDeclareTarget.cpp | 7 - flang/lib/Parser/executable-parsers.cpp | 4 + flang/lib/Parser/expr-parsers.cpp | 24 +- flang/lib/Parser/openacc-parsers.cpp | 28 +- flang/lib/Parser/preprocessor.cpp | 19 +- flang/lib/Parser/prescan.cpp | 54 +- flang/lib/Parser/prescan.h | 7 +- flang/lib/Parser/program-parsers.cpp | 4 +- flang/lib/Parser/unparse.cpp | 22 +- flang/lib/Semantics/check-acc-structure.cpp | 40 +- flang/lib/Semantics/check-call.cpp | 94 +- flang/lib/Semantics/check-cuda.cpp | 22 +- flang/lib/Semantics/check-declarations.cpp | 37 +- flang/lib/Semantics/check-do-forall.cpp | 64 +- flang/lib/Semantics/data-to-inits.cpp | 4 +- flang/lib/Semantics/expression.cpp | 19 +- flang/lib/Semantics/resolve-labels.cpp | 28 +- flang/lib/Semantics/resolve-names-utils.cpp | 12 +- flang/lib/Semantics/resolve-names.cpp | 179 +- flang/runtime/external-unit.cpp | 11 +- flang/runtime/file.cpp | 6 +- flang/runtime/io-api-common.h | 8 +- flang/runtime/pseudo-unit.cpp | 6 +- flang/runtime/reduction-templates.h | 8 +- flang/runtime/support.cpp | 5 + flang/runtime/unit.h | 2 +- flang/test/Driver/exec.f90 | 2 +- flang/test/Evaluate/signed-mult-opd.f90 | 12 + flang/test/Fir/convert-to-llvm.fir | 37 + flang/test/Fir/fir-ops.fir | 11 + flang/test/Fir/invalid.fir | 8 + flang/test/Fir/is_assumed_size-codegen.fir | 25 + flang/test/Fir/tbaa.fir | 34 +- flang/test/HLFIR/bufferize01.fir | 28 + flang/test/HLFIR/c_ptr_byvalue.f90 | 4 +- flang/test/HLFIR/maxloc-elemental.fir | 10 +- flang/test/HLFIR/minloc-elemental.fir | 20 +- flang/test/Lower/CUDA/cuda-device-proc.cuf | 8 +- flang/test/Lower/HLFIR/assumed-rank-iface.f90 | 4 +- .../test/Lower/HLFIR/bindc-value-derived.f90 | 2 +- flang/test/Lower/HLFIR/block_bindc_pocs.f90 | 2 +- .../call-sequence-associated-descriptors.f90 | 8 +- .../calls-character-singleton-result.f90 | 2 +- .../HLFIR/convert-variable-assumed-rank.f90 | 58 + .../Lower/HLFIR/elemental-result-length.f90 | 95 + .../Lower/HLFIR/ignore-type-assumed-shape.f90 | 8 +- flang/test/Lower/HLFIR/select-rank.f90 | 826 +++++ flang/test/Lower/Intrinsics/associated.f90 | 23 + flang/test/Lower/Intrinsics/ieee_flag.f90 | 3 +- .../test/Lower/OpenMP/debug_info_conflict.f90 | 16 + .../OpenMP/threadprivate-default-clause.f90 | 4 +- flang/test/Lower/block.f90 | 2 +- flang/test/Lower/call-bindc.f90 | 21 + flang/test/Preprocessing/args.h | 1 + flang/test/Preprocessing/include-args.F90 | 6 + flang/test/Semantics/bind-c02.f90 | 1 + flang/test/Semantics/bind-c16.f90 | 86 + flang/test/Semantics/call03.f90 | 8 +- flang/test/Semantics/call10.f90 | 6 +- flang/test/Semantics/call30.f90 | 45 +- flang/test/Semantics/call40.f90 | 15 +- flang/test/Semantics/elemental01.f90 | 2 +- flang/test/Semantics/label05.f90 | 32 + flang/test/Semantics/null01.f90 | 13 + flang/test/Semantics/resolve09.f90 | 7 + flang/test/Semantics/resolve118.f90 | 23 + flang/test/Semantics/resolve123.f90 | 79 + flang/test/Semantics/resolve124.f90 | 89 + flang/test/Semantics/resolve55.f90 | 19 +- flang/test/Semantics/stmt-func01.f90 | 10 +- flang/unittests/Runtime/Support.cpp | 11 + .../cmake/modules/CheckCompilerFeatures.cmake | 6 +- libc/cmake/modules/LLVMLibCLibraryRules.cmake | 6 + .../compiler_features/check_float16.cpp | 5 + .../modules/prepare_libc_gpu_build.cmake | 52 +- libc/config/config.json | 10 + libc/config/linux/aarch64/entrypoints.txt | 12 + libc/config/linux/x86_64/entrypoints.txt | 15 + libc/docs/configure.rst | 3 + libc/docs/math/index.rst | 12 +- libc/hdr/types/CMakeLists.txt | 9 + libc/hdr/types/pid_t.h | 22 + libc/include/CMakeLists.txt | 1 + libc/include/llvm-libc-macros/CMakeLists.txt | 6 + .../include/llvm-libc-macros/float16-macros.h | 17 + libc/include/llvm-libc-types/CMakeLists.txt | 6 +- libc/include/llvm-libc-types/cnd_t.h | 4 +- .../llvm-libc-types/pthread_rwlockattr_t.h | 1 + libc/include/math.h.def | 1 + libc/include/pthread.h.def | 5 + libc/spec/posix.td | 10 + libc/spec/spec.td | 1 + libc/spec/stdc.td | 12 + libc/src/__support/CPP/algorithm.h | 15 + .../CPP/type_traits/is_floating_point.h | 16 +- libc/src/__support/FPUtil/FPBits.h | 2 +- .../FPUtil/NearestIntegerOperations.h | 21 +- libc/src/__support/FPUtil/sqrt.h | 3 +- libc/src/__support/FPUtil/x86_64/PolyEval.h | 85 - libc/src/__support/FPUtil/x86_64/sqrt.h | 5 +- libc/src/__support/File/dir.h | 16 +- libc/src/__support/File/file.h | 9 +- .../__support/OSUtil/baremetal/CMakeLists.txt | 2 +- libc/src/__support/OSUtil/baremetal/exit.cpp | 18 + libc/src/__support/OSUtil/exit.h | 18 + libc/src/__support/OSUtil/gpu/CMakeLists.txt | 2 +- .../OSUtil/gpu/{quick_exit.cpp => exit.cpp} | 10 +- .../src/__support/OSUtil/linux/CMakeLists.txt | 2 +- .../OSUtil/linux/{quick_exit.cpp => exit.cpp} | 10 +- libc/src/__support/libc_assert.h | 6 +- .../macros/properties/CMakeLists.txt | 1 + libc/src/__support/macros/properties/types.h | 29 +- libc/src/__support/threads/CndVar.h | 14 +- libc/src/__support/threads/fork_callbacks.cpp | 5 +- libc/src/__support/threads/gpu/mutex.h | 2 +- .../__support/threads/linux/CMakeLists.txt | 26 + libc/src/__support/threads/linux/CndVar.cpp | 5 +- libc/src/__support/threads/linux/mutex.h | 135 +- libc/src/__support/threads/linux/raw_mutex.h | 130 + libc/src/__support/threads/thread.cpp | 8 +- libc/src/math/CMakeLists.txt | 6 + .../quick_exit.cpp => math/ceilf16.h} | 12 +- libc/src/math/fabsf16.h | 20 + libc/src/math/floorf16.h | 20 + libc/src/math/generic/CMakeLists.txt | 78 + libc/src/math/generic/ceilf16.cpp | 17 + libc/src/math/generic/fabsf16.cpp | 17 + libc/src/math/generic/floorf16.cpp | 17 + libc/src/math/generic/roundevenf16.cpp | 19 + libc/src/math/generic/roundf16.cpp | 17 + libc/src/math/generic/truncf16.cpp | 17 + libc/src/math/roundevenf16.h | 20 + libc/src/math/roundf16.h | 20 + libc/src/math/truncf16.h | 20 + libc/src/pthread/CMakeLists.txt | 21 + libc/src/pthread/pthread_mutex_init.cpp | 5 +- libc/src/pthread/pthread_mutexattr.h | 5 + .../pthread/pthread_rwlockattr_getkind_np.cpp | 24 + .../pthread/pthread_rwlockattr_getkind_np.h | 21 + libc/src/pthread/pthread_rwlockattr_init.cpp | 1 + .../pthread/pthread_rwlockattr_setkind_np.cpp | 30 + .../pthread/pthread_rwlockattr_setkind_np.h | 20 + libc/src/stdlib/CMakeLists.txt | 10 + libc/src/stdlib/_Exit.cpp | 4 +- libc/src/stdlib/atexit.cpp | 3 +- libc/src/stdlib/exit.cpp | 4 +- libc/src/stdlib/quick_exit.cpp | 22 + .../{__support/OSUtil => stdlib}/quick_exit.h | 10 +- libc/src/string/memory_utils/op_x86.h | 4 +- libc/src/string/memory_utils/utils.h | 2 +- libc/src/threads/linux/CMakeLists.txt | 1 + libc/src/threads/mtx_init.cpp | 3 +- libc/src/unistd/_exit.cpp | 4 +- libc/test/IntegrationTest/test.h | 10 +- libc/test/UnitTest/LibcTest.cpp | 47 +- libc/test/UnitTest/LibcTest.h | 12 +- libc/test/UnitTest/LibcTestMain.cpp | 38 +- .../__support/threads/thread_detach_test.cpp | 3 +- libc/test/src/__support/CMakeLists.txt | 1 + libc/test/src/__support/CPP/CMakeLists.txt | 10 + .../test/src/__support/CPP/algorithm_test.cpp | 47 + .../test/src/__support/threads/CMakeLists.txt | 4 + .../__support/threads/linux/CMakeLists.txt | 13 + .../threads/linux/raw_mutex_test.cpp | 86 + libc/test/src/fenv/getenv_and_setenv_test.cpp | 2 +- libc/test/src/math/smoke/CMakeLists.txt | 72 + libc/test/src/math/smoke/CeilTest.h | 8 +- libc/test/src/math/smoke/FloorTest.h | 8 +- libc/test/src/math/smoke/RoundEvenTest.h | 8 +- libc/test/src/math/smoke/RoundTest.h | 8 +- libc/test/src/math/smoke/TruncTest.h | 8 +- libc/test/src/math/smoke/ceilf16_test.cpp | 13 + libc/test/src/math/smoke/fabsf16_test.cpp | 13 + libc/test/src/math/smoke/floorf16_test.cpp | 13 + .../test/src/math/smoke/roundevenf16_test.cpp | 13 + libc/test/src/math/smoke/roundf16_test.cpp | 13 + libc/test/src/math/smoke/truncf16_test.cpp | 13 + libc/test/src/pthread/CMakeLists.txt | 2 + .../src/pthread/pthread_rwlockattr_test.cpp | 29 +- libc/test/src/stdlib/CMakeLists.txt | 13 + libc/test/src/stdlib/quick_exit_test.cpp | 16 + libc/test/utils/UnitTest/testfilter_test.cpp | 30 +- libc/utils/gpu/loader/Loader.h | 13 +- libc/utils/gpu/loader/amdgpu/Loader.cpp | 5 +- libc/utils/gpu/loader/nvptx/Loader.cpp | 6 +- libcxx/CMakeLists.txt | 17 +- libcxx/include/__config | 10 +- libcxx/include/__configuration/abi.h | 2 + .../__locale_dir/locale_base_api/android.h | 14 +- .../__locale_dir/locale_base_api/ibm.h | 10 +- .../__locale_dir/locale_base_api/musl.h | 19 +- .../__locale_dir/locale_base_api/openbsd.h | 12 +- .../include/__string/constexpr_c_functions.h | 2 +- .../__support/xlocale/__nop_locale_mgmt.h | 16 +- .../__support/xlocale/__posix_l_fallback.h | 74 +- .../__support/xlocale/__strtonum_fallback.h | 25 +- libcxx/include/__type_traits/remove_pointer.h | 5 + libcxx/include/__utility/pair.h | 37 +- libcxx/include/bitset | 3 + libcxx/include/locale | 4 +- libcxx/src/atomic.cpp | 9 +- .../configs/llvm-libc++-android-ndk.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-mingw.cfg.in | 2 +- .../configs/llvm-libc++-shared-clangcl.cfg.in | 2 +- .../configs/llvm-libc++-shared-gcc.cfg.in | 2 +- libcxx/test/configs/llvm-libc++-shared.cfg.in | 2 +- .../configs/llvm-libc++-static-clangcl.cfg.in | 2 +- .../libcxx/atomics/atomics.syn/wait.pass.cpp | 32 + .../filesystems/convert_file_time.pass.cpp | 2 +- .../alg.merge/inplace_merge.pass.cpp | 2 - ...pass.cpp => member_types.compile.pass.cpp} | 2 - ...s.cpp => totally_ordered.compile.pass.cpp} | 35 +- .../totally_ordered_with.compile.pass.cpp | 681 ++++ .../totally_ordered_with.pass.cpp | 1141 ------ ...ss.cpp => floating_point.compile.pass.cpp} | 4 +- ...ral.pass.cpp => integral.compile.pass.cpp} | 4 +- ...s.cpp => signed_integral.compile.pass.cpp} | 16 +- ...cpp => unsigned_integral.compile.pass.cpp} | 22 +- ...ss.cpp => gcc_workaround.compile.pass.cpp} | 6 +- ...cpp => default_recursive.compile.pass.cpp} | 17 +- ...cpp => default_recursive.compile.pass.cpp} | 17 +- ...ss.cpp => gcc_workaround.compile.pass.cpp} | 2 - ...pass.cpp => iter_value_t.compile.pass.cpp} | 6 +- .../facet.num.get.members/get_double.pass.cpp | 61 + .../facet.num.get.members/get_float.pass.cpp | 60 + .../get_long_double.pass.cpp | 60 + ...pe.pass.cpp => user_type.compile.pass.cpp} | 2 - ...ass.cpp => nothing_to_do.compile.pass.cpp} | 2 - ...ass.cpp => nothing_to_do.compile.pass.cpp} | 2 - ...ass.cpp => nothing_to_do.compile.pass.cpp} | 2 - ...ass.cpp => nothing_to_do.compile.pass.cpp} | 2 - .../wait_for_pred.pass.cpp | 8 +- .../nonmembers/comparison.pass.cpp | 4 +- .../monadic/transform.pass.cpp | 2 +- .../monadic/transform_error.pass.cpp | 2 +- .../monadic/transform_error.pass.cpp | 2 +- .../formatter.char_array.pass.cpp | 2 +- .../optional.object.assign/emplace.pass.cpp | 19 +- .../optional.object.mod/reset.pass.cpp | 27 +- .../tuple.tuple/tuple.cnstr/PR31384.pass.cpp | 3 + .../visit_return_type.pass.cpp | 3 + libcxx/test/support/count_new.h | 4 + libcxx/test/support/test_macros.h | 2 +- .../header_exportable_declarations.cpp | 2 - libcxxabi/CMakeLists.txt | 13 +- .../catch_member_function_pointer_02.pass.cpp | 2 +- libunwind/CMakeLists.txt | 13 +- lld/CMakeLists.txt | 2 + lld/ELF/Arch/AArch64.cpp | 2 + lld/ELF/LinkerScript.cpp | 33 +- lld/ELF/LinkerScript.h | 4 +- lld/ELF/Writer.cpp | 121 +- lld/MachO/Driver.cpp | 11 +- lld/cmake/modules/AddLLD.cmake | 2 - lld/test/CMakeLists.txt | 5 +- lld/test/ELF/aarch64-fpic-got.s | 41 +- lld/test/ELF/fatlto/fatlto.test | 78 +- lld/test/ELF/linkerscript/addr.test | 64 +- .../ELF/linkerscript/expr-invalid-sec.test | 9 - lld/test/ELF/linkerscript/expr-sections.test | 24 - lld/test/ELF/linkerscript/memory-err.s | 4 +- lld/test/ELF/linkerscript/orphan-align.s | 28 - lld/test/ELF/linkerscript/orphan.s | 130 +- lld/test/ELF/linkerscript/orphans.s | 31 - .../linkerscript/parse-section-in-addr.test | 10 - .../linkerscript/section-not-converge.test | 37 + lld/test/ELF/loongarch-relax-emit-relocs.s | 4 +- lld/test/MachO/start-lib.s | 5 + lld/unittests/CMakeLists.txt | 2 - lldb/cmake/modules/LLDBConfig.cmake | 16 +- lldb/docs/resources/build.rst | 1 - lldb/include/lldb/API/SBCommandInterpreter.h | 11 +- .../lldb/Interpreter/CommandInterpreter.h | 8 +- lldb/include/lldb/Target/Statistics.h | 1 + .../Python/lldbsuite/test/builders/builder.py | 7 +- .../Python/lldbsuite/test/configuration.py | 1 + lldb/packages/Python/lldbsuite/test/dotest.py | 11 +- .../Python/lldbsuite/test/dotest_args.py | 15 + lldb/source/Commands/CommandCompletions.cpp | 57 +- lldb/source/Commands/CommandObjectStats.cpp | 3 + lldb/source/Commands/Options.td | 4 + lldb/source/Core/CMakeLists.txt | 3 - lldb/source/Core/Mangled.cpp | 12 +- lldb/source/DataFormatters/FormatManager.cpp | 18 +- .../DataFormatters/ValueObjectPrinter.cpp | 27 +- lldb/source/Expression/IRInterpreter.cpp | 2 +- .../source/Interpreter/CommandInterpreter.cpp | 19 +- .../Plugins/ExpressionParser/Clang/ASTUtils.h | 8 +- .../Clang/ClangExternalASTSourceCallbacks.cpp | 1 + .../Clang/ClangExternalASTSourceCallbacks.h | 8 +- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 4 + .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp | 12 + .../SymbolFile/DWARF/DWARFDebugInfo.cpp | 11 +- .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h | 3 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 7 +- .../SymbolFile/DWARF/SymbolFileDWARFDwo.cpp | 2 +- .../SymbolFile/DWARF/UniqueDWARFASTType.cpp | 12 +- lldb/source/Target/Statistics.cpp | 33 + lldb/source/Utility/UriParser.cpp | 2 +- .../commands/session/save/TestSessionSave.py | 5 +- .../commands/statistics/basic/TestStats.py | 47 + .../TestBreakpointSetRestart.py | 3 +- .../completion/TestCompletion.py | 37 + .../synthcapping/TestSyntheticCapping.py | 11 + .../synthcapping/fooSynthProvider.py | 15 +- lldb/test/API/lang/c/non-mangled/Makefile | 4 + .../API/lang/c/non-mangled/TestCNonMangled.py | 24 + lldb/test/API/lang/c/non-mangled/main.c | 8 + .../address_range/TestAddressRange.py | 20 +- .../python_api/debugger/TestDebuggerAPI.py | 1 - .../interpreter/TestCommandInterpreterAPI.py | 67 +- .../python_api/run_locker/TestRunLocker.py | 7 + .../lldb-dap/variables/children/Makefile | 3 + .../children/TestDAP_variables_children.py | 42 + .../lldb-dap/variables/children/formatter.py | 42 + .../lldb-dap/variables/children/main.cpp | 8 + .../lldb-server/TestGdbRemotePlatformFile.py | 25 +- .../TestGdbRemoteLibrariesSvr4Support.py | 1 + .../Breakpad/symtab-sorted-by-size.test | 6 +- .../DWARF/x86/Inputs/debug-types-basic.cpp | 9 + .../DWARF/x86/debug-types-basic.test | 9 +- lldb/test/requirements.txt | 6 + lldb/tools/lldb-dap/JSONUtils.cpp | 45 +- lldb/unittests/Core/MangledTest.cpp | 4 +- llvm-libgcc/CMakeLists.txt | 13 +- llvm/CMakeLists.txt | 2 - llvm/cmake/config-ix.cmake | 10 - llvm/cmake/modules/FindLibEdit.cmake | 7 +- llvm/cmake/modules/FindTerminfo.cmake | 55 - llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +- llvm/cmake/modules/LLVMConfig.cmake.in | 5 - .../modules/LLVMExternalProjectUtils.cmake | 2 +- llvm/docs/AMDGPUUsage.rst | 15 +- llvm/docs/DirectXUsage.rst | 1 + llvm/docs/LangRef.rst | 14 +- llvm/docs/RISCVUsage.rst | 4 +- llvm/docs/ReleaseNotes.rst | 5 + llvm/docs/RemoveDIsDebugInfo.md | 213 +- llvm/docs/Security.rst | 5 +- .../docs/convergence-both-diverged-nested.png | Bin llvm/docs/convergence-closed-path.png | Bin llvm/docs/convergence-divergent-inside.png | Bin llvm/docs/convergence-divergent-outside.png | Bin llvm/docs/convergence-natural-loop.png | Bin llvm/include/llvm/ADT/FunctionExtras.h | 3 +- llvm/include/llvm/ADT/STLExtras.h | 6 - llvm/include/llvm/Analysis/TargetFolder.h | 2 +- llvm/include/llvm/BinaryFormat/ELF.h | 3 +- llvm/include/llvm/Bitcode/BitcodeWriter.h | 4 +- llvm/include/llvm/Bitstream/BitstreamWriter.h | 167 +- llvm/include/llvm/CodeGen/FinalizeISel.h | 23 + .../llvm/CodeGen/GlobalISel/CallLowering.h | 10 +- .../llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 + .../GlobalISel/GIMatchTableExecutorImpl.h | 8 +- .../GlobalISel/LegalizationArtifactCombiner.h | 14 +- llvm/include/llvm/CodeGen/GlobalMerge.h | 2 + llvm/include/llvm/CodeGen/ISDOpcodes.h | 5 + llvm/include/llvm/CodeGen/SelectionDAG.h | 75 +- llvm/include/llvm/CodeGen/SelectionDAGISel.h | 43 +- llvm/include/llvm/CodeGen/StackProtector.h | 2 + llvm/include/llvm/CodeGen/TargetLowering.h | 24 +- llvm/include/llvm/Config/config.h.cmake | 3 - llvm/include/llvm/DWARFLinker/Utils.h | 65 +- llvm/include/llvm/Frontend/OpenMP/OMP.td | 1 - llvm/include/llvm/IR/ConstantFolder.h | 2 +- llvm/include/llvm/IR/Function.h | 5 +- llvm/include/llvm/IR/GEPNoWrapFlags.h | 2 + llvm/include/llvm/IR/IntrinsicsAMDGPU.td | 45 +- llvm/include/llvm/IR/PatternMatch.h | 6 +- llvm/include/llvm/IR/RuntimeLibcalls.def | 3 + llvm/include/llvm/InitializePasses.h | 1 + llvm/include/llvm/LinkAllPasses.h | 1 + llvm/include/llvm/Passes/CodeGenPassBuilder.h | 10 +- .../llvm/Passes/MachinePassRegistry.def | 2 +- .../llvm/ProfileData/InstrProfReader.h | 4 + llvm/include/llvm/ProfileData/MemProf.h | 83 +- .../llvm/ProfileData/PGOCtxProfWriter.h | 2 +- llvm/include/llvm/Support/Errc.h | 4 + llvm/include/llvm/Support/WindowsError.h | 1 + llvm/include/llvm/Support/raw_ostream.h | 10 +- .../include/llvm/Target/GlobalISel/Combine.td | 11 +- llvm/include/llvm/TargetParser/TargetParser.h | 3 +- llvm/include/llvm/Transforms/Utils.h | 9 + llvm/lib/Analysis/BranchProbabilityInfo.cpp | 13 +- llvm/lib/Analysis/ConstantFolding.cpp | 19 +- llvm/lib/Analysis/ScalarEvolution.cpp | 59 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 71 +- llvm/lib/CodeGen/BasicBlockPathCloning.cpp | 10 + llvm/lib/CodeGen/FinalizeISel.cpp | 32 +- llvm/lib/CodeGen/GlobalISel/CallLowering.cpp | 2 + .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 40 +- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 18 +- llvm/lib/CodeGen/GlobalMerge.cpp | 22 +- llvm/lib/CodeGen/MachineCopyPropagation.cpp | 5 +- llvm/lib/CodeGen/MachineOutliner.cpp | 24 +- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 127 +- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 21 + .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 175 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 80 +- .../SelectionDAG/SelectionDAGBuilder.h | 6 +- .../SelectionDAG/SelectionDAGDumper.cpp | 2 + .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 249 +- .../CodeGen/SelectionDAG/TargetLowering.cpp | 65 +- llvm/lib/CodeGen/TargetLoweringBase.cpp | 4 + llvm/lib/CodeGen/TargetPassConfig.cpp | 3 + llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 6 +- .../Parallel/DWARFLinkerCompileUnit.cpp | 6 +- .../ExecutionEngine/Interpreter/Execution.cpp | 41 +- llvm/lib/IR/Attributes.cpp | 9 +- llvm/lib/IR/ConstantFold.cpp | 209 +- llvm/lib/IR/Constants.cpp | 8 - llvm/lib/MC/MCExpr.cpp | 12 +- llvm/lib/MC/MCPseudoProbe.cpp | 10 +- llvm/lib/Object/ELFObjectFile.cpp | 2 + llvm/lib/Object/MachOObjectFile.cpp | 32 +- llvm/lib/ObjectYAML/ELFYAML.cpp | 1 + llvm/lib/Passes/PassBuilder.cpp | 1 + llvm/lib/Passes/PassBuilderPipelines.cpp | 6 + llvm/lib/ProfileData/InstrProf.cpp | 94 +- llvm/lib/ProfileData/InstrProfReader.cpp | 38 +- llvm/lib/ProfileData/InstrProfWriter.cpp | 94 +- llvm/lib/ProfileData/MemProf.cpp | 101 +- llvm/lib/Support/CMakeLists.txt | 14 +- llvm/lib/Support/ErrorHandling.cpp | 35 + llvm/lib/Support/PrettyStackTrace.cpp | 7 +- llvm/lib/Support/Unix/Process.inc | 60 +- llvm/lib/Support/Windows/Path.inc | 8 +- llvm/lib/Support/raw_ostream.cpp | 6 +- llvm/lib/Target/AArch64/AArch64.h | 2 +- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 132 + .../Target/AArch64/AArch64CallingConvention.h | 3 + .../AArch64/AArch64CallingConvention.td | 30 + .../AArch64/AArch64ExpandPseudoInsts.cpp | 71 +- .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 19 +- .../Target/AArch64/AArch64ISelLowering.cpp | 177 +- llvm/lib/Target/AArch64/AArch64ISelLowering.h | 12 + llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 17 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 82 + .../Target/AArch64/AArch64RegisterBanks.td | 4 +- .../Target/AArch64/AArch64RegisterInfo.cpp | 12 +- .../lib/Target/AArch64/AArch64RegisterInfo.td | 5 +- .../Target/AArch64/AArch64StackTagging.cpp | 4 +- .../Target/AArch64/AArch64TargetMachine.cpp | 2 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 27 + .../AArch64/GISel/AArch64CallLowering.cpp | 101 +- .../AArch64/GISel/AArch64GlobalISelUtils.cpp | 29 + .../AArch64/GISel/AArch64GlobalISelUtils.h | 6 + .../AArch64/GISel/AArch64LegalizerInfo.cpp | 33 +- .../GISel/AArch64PostLegalizerCombiner.cpp | 7 + .../GISel/AArch64PreLegalizerCombiner.cpp | 6 +- .../AArch64/GISel/AArch64RegisterBankInfo.cpp | 12 +- llvm/lib/Target/AMDGPU/AMDGPU.h | 2 +- llvm/lib/Target/AMDGPU/AMDGPU.td | 4 + .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp | 8 +- .../Target/AMDGPU/AMDGPUCombinerHelper.cpp | 8 +- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 64 +- llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.h | 28 +- llvm/lib/Target/AMDGPU/AMDGPUInstrInfo.h | 2 +- .../AMDGPU/AMDGPUInstructionSelector.cpp | 4 +- .../AMDGPU/AMDGPULowerKernelArguments.cpp | 1 - llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def | 6 + .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 3 +- llvm/lib/Target/AMDGPU/BUFInstructions.td | 6 + llvm/lib/Target/AMDGPU/DSInstructions.td | 2 + llvm/lib/Target/AMDGPU/FLATInstructions.td | 4 + llvm/lib/Target/AMDGPU/GCNProcessors.td | 7 +- .../MCTargetDesc/AMDGPUTargetStreamer.cpp | 5 + llvm/lib/Target/AMDGPU/R600ISelDAGToDAG.cpp | 13 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 39 +- llvm/lib/Target/AMDGPU/SIISelLowering.h | 3 +- llvm/lib/Target/AMDGPU/SIInstrFormats.td | 2 +- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 65 +- llvm/lib/Target/AMDGPU/SIInstrInfo.td | 9 +- llvm/lib/Target/AMDGPU/SIInstructions.td | 4 +- .../Target/AMDGPU/SILoadStoreOptimizer.cpp | 16 +- .../lib/Target/AMDGPU/SIMachineFunctionInfo.h | 5 +- llvm/lib/Target/AMDGPU/SMInstructions.td | 2 + llvm/lib/Target/AMDGPU/SOPInstructions.td | 10 + llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h | 1 + llvm/lib/Target/AMDGPU/VOPInstructions.td | 6 + llvm/lib/Target/ARC/ARC.h | 2 +- llvm/lib/Target/ARC/ARCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARC/ARCTargetMachine.cpp | 2 +- llvm/lib/Target/ARM/ARM.h | 2 +- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 5 +- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 18 +- llvm/lib/Target/ARM/ARMISelLowering.cpp | 54 +- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 2 +- llvm/lib/Target/AVR/AVR.h | 2 +- llvm/lib/Target/AVR/AVRISelDAGToDAG.cpp | 18 +- llvm/lib/Target/AVR/AVRTargetMachine.cpp | 2 +- llvm/lib/Target/BPF/BPF.h | 2 +- llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 17 +- llvm/lib/Target/BPF/BPFTargetMachine.cpp | 2 +- llvm/lib/Target/CSKY/CSKY.h | 2 +- llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp | 19 +- llvm/lib/Target/CSKY/CSKYTargetMachine.cpp | 2 +- .../DirectX/DXILWriter/DXILBitcodeWriter.cpp | 7 +- .../DirectX/DXILWriter/DXILBitcodeWriter.h | 2 +- llvm/lib/Target/Hexagon/Hexagon.h | 2 +- .../Target/Hexagon/HexagonISelDAGToDAG.cpp | 11 +- llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h | 12 +- .../Target/Hexagon/HexagonTargetMachine.cpp | 2 +- llvm/lib/Target/Lanai/Lanai.h | 2 +- llvm/lib/Target/Lanai/LanaiISelDAGToDAG.cpp | 21 +- llvm/lib/Target/Lanai/LanaiTargetMachine.cpp | 2 +- llvm/lib/Target/LoongArch/LoongArch.h | 2 +- .../LoongArch/LoongArchISelDAGToDAG.cpp | 11 +- .../Target/LoongArch/LoongArchISelDAGToDAG.h | 10 +- .../LoongArch/LoongArchISelLowering.cpp | 20 + .../Target/LoongArch/LoongArchInstrInfo.td | 5 +- .../LoongArch/LoongArchTargetMachine.cpp | 2 +- .../MCTargetDesc/LoongArchAsmBackend.cpp | 34 +- llvm/lib/Target/M68k/M68k.h | 2 +- llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp | 17 +- llvm/lib/Target/M68k/M68kTargetMachine.cpp | 2 +- llvm/lib/Target/MSP430/MSP430.h | 2 +- llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 18 +- .../lib/Target/MSP430/MSP430TargetMachine.cpp | 2 +- llvm/lib/Target/Mips/Mips.h | 2 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp | 6 +- llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h | 5 + llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp | 12 +- llvm/lib/Target/Mips/MipsISelDAGToDAG.h | 13 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 10 +- llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h | 8 +- llvm/lib/Target/Mips/MipsTargetMachine.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTX.h | 2 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 13 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h | 9 +- llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 2 +- llvm/lib/Target/PowerPC/PPC.h | 2 +- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 18 +- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 4 +- llvm/lib/Target/PowerPC/PPCInstrP10.td | 588 ++-- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp | 2 +- llvm/lib/Target/RISCV/RISCV.h | 2 +- llvm/lib/Target/RISCV/RISCVFeatures.td | 4 +- .../RISCV/RISCVGatherScatterLowering.cpp | 21 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 11 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 11 +- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 91 +- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 32 +- .../Target/RISCV/RISCVInstrInfoVPseudos.td | 255 +- llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td | 2 +- llvm/lib/Target/RISCV/RISCVSchedSiFiveP600.td | 2 +- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 2 +- llvm/lib/Target/SPIRV/CMakeLists.txt | 1 + llvm/lib/Target/SPIRV/SPIRV.h | 1 + llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 19 + llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 99 +- llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 2 +- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 2 +- .../SPIRV/SPIRVMergeRegionExitTargets.cpp | 281 ++ llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 5 + llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp | 5 + llvm/lib/Target/Sparc/Sparc.h | 2 +- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp | 18 +- llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 2 +- llvm/lib/Target/SystemZ/SystemZ.h | 2 +- .../Target/SystemZ/SystemZISelDAGToDAG.cpp | 19 +- .../Target/SystemZ/SystemZTargetMachine.cpp | 2 +- llvm/lib/Target/VE/VE.h | 2 +- llvm/lib/Target/VE/VEISelDAGToDAG.cpp | 17 +- llvm/lib/Target/VE/VETargetMachine.cpp | 2 +- llvm/lib/Target/WebAssembly/WebAssembly.h | 2 +- .../WebAssembly/WebAssemblyISelDAGToDAG.cpp | 20 +- .../WebAssembly/WebAssemblyISelLowering.cpp | 3 + .../WebAssembly/WebAssemblyISelLowering.h | 4 - .../WebAssembly/WebAssemblyInstrSIMD.td | 11 +- .../WebAssembly/WebAssemblyTargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86.h | 2 +- llvm/lib/Target/X86/X86.td | 3 + llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 13 +- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 28 +- llvm/lib/Target/X86/X86ISelDAGToDAG.h | 25 + llvm/lib/Target/X86/X86ISelLowering.cpp | 105 +- llvm/lib/Target/X86/X86ISelLowering.h | 5 - llvm/lib/Target/X86/X86InstrInfo.cpp | 96 +- llvm/lib/Target/X86/X86LowerTileCopy.cpp | 14 +- llvm/lib/Target/X86/X86PassRegistry.def | 19 + llvm/lib/Target/X86/X86TargetMachine.cpp | 2 +- llvm/lib/Target/X86/X86TargetMachine.h | 3 + llvm/lib/Target/XCore/XCore.h | 2 +- llvm/lib/Target/XCore/XCoreISelDAGToDAG.cpp | 19 +- llvm/lib/Target/XCore/XCoreTargetMachine.cpp | 2 +- llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp | 25 +- llvm/lib/TargetParser/RISCVISAInfo.cpp | 4 +- llvm/lib/TargetParser/TargetParser.cpp | 6 + .../IPO/MemProfContextDisambiguation.cpp | 4 +- .../InstCombine/InstCombineAddSub.cpp | 18 + .../InstCombine/InstCombineInternal.h | 2 +- .../InstCombine/InstCombineShifts.cpp | 17 +- llvm/lib/Transforms/Scalar/Reassociate.cpp | 93 +- llvm/lib/Transforms/Scalar/Scalar.cpp | 1 + .../Utils/EntryExitInstrumenter.cpp | 35 + llvm/lib/Transforms/Utils/LoopPeel.cpp | 86 +- .../Transforms/Vectorize/LoopVectorize.cpp | 125 +- .../Transforms/Vectorize/SLPVectorizer.cpp | 6 +- llvm/lib/Transforms/Vectorize/VPlan.cpp | 39 +- llvm/lib/Transforms/Vectorize/VPlan.h | 76 +- .../Transforms/Vectorize/VPlanAnalysis.cpp | 6 + .../lib/Transforms/Vectorize/VPlanRecipes.cpp | 39 +- .../Transforms/Vectorize/VPlanTransforms.cpp | 22 +- .../Transforms/Vectorize/VPlanVerifier.cpp | 107 +- llvm/runtimes/CMakeLists.txt | 10 + .../LoopAccessAnalysis/symbolic-stride.ll | 39 + .../backedge-taken-count-guard-info.ll | 8 +- .../2007-04-25-AssemblerFoldExternWeak.ll | 9 - llvm/test/Assembler/ConstantExprFold.ll | 4 +- llvm/test/Assembler/ConstantExprNoFold.ll | 41 - llvm/test/Assembler/getelementptr.ll | 15 +- llvm/test/Assembler/getelementptr_vec_ce.ll | 2 +- llvm/test/Assembler/vector-cmp.ll | 2 +- .../AArch64/GlobalISel/combine-op-trunc.mir | 315 ++ .../AArch64/GlobalISel/combine-select.mir | 30 +- .../AArch64/GlobalISel/legalize-min-max.mir | 60 +- .../AArch64/GlobalISel/legalize-select.mir | 15 +- .../prelegalizercombiner-hoist-same-hands.mir | 7 +- .../AArch64/GlobalISel/sve-load-store.ll | 50 + llvm/test/CodeGen/AArch64/O0-pipeline.ll | 1 + llvm/test/CodeGen/AArch64/O3-pipeline.ll | 1 + .../CodeGen/AArch64/arm64-reg-copy-noneon.ll | 25 +- ...ranch-target-enforcement-indirect-calls.ll | 4 +- .../AArch64/dynamic-regmask-preserve-none.ll | 88 + llvm/test/CodeGen/AArch64/fdiv-const.ll | 150 + .../AArch64/large-offset-ldr-merge.mir | 0 .../CodeGen/AArch64/lower-ptrmask-arm64_32.ll | 12 + .../AArch64/machine-outliner-overlap.mir | 12 +- llvm/test/CodeGen/AArch64/preserve.ll | 9 +- llvm/test/CodeGen/AArch64/preserve_nonecc.ll | 92 + .../CodeGen/AArch64/preserve_nonecc_call.ll | 337 ++ .../AArch64/preserve_nonecc_musttail.ll | 11 + .../CodeGen/AArch64/preserve_nonecc_swift.ll | 16 + llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll | 105 + .../CodeGen/AArch64/ptrauth-call-rv-marker.ll | 154 + llvm/test/CodeGen/AArch64/ptrauth-call.ll | 272 ++ llvm/test/CodeGen/AArch64/ptrauth-invoke.ll | 276 ++ ...treaming-mode-fixed-length-bit-counting.ll | 2332 ++++++++----- ...streaming-mode-fixed-length-masked-load.ll | 12 +- .../sve-streaming-mode-test-register-mov.ll | 3 +- .../CodeGen/AArch64/windows-extern-weak.ll | 27 +- llvm/test/CodeGen/AMDGPU/GlobalISel/fshl.ll | 191 +- llvm/test/CodeGen/AMDGPU/GlobalISel/fshr.ll | 195 +- .../inst-select-load-global.s96.mir | 12 + .../AMDGPU/GlobalISel/lds-zero-initializer.ll | 34 +- .../AMDGPU/GlobalISel/legalize-saddo.mir | 3 +- .../AMDGPU/GlobalISel/legalize-ssubo.mir | 3 +- .../test/CodeGen/AMDGPU/GlobalISel/uaddsat.ll | 10 +- .../test/CodeGen/AMDGPU/GlobalISel/usubsat.ll | 10 +- llvm/test/CodeGen/AMDGPU/GlobalISel/xnor.ll | 20 +- .../CodeGen/AMDGPU/add_sub_u64_pseudos.mir | 2 + .../AMDGPU/buffer-atomic-fadd.f32-no-rtn.ll | 4 + .../AMDGPU/buffer-atomic-fadd.f32-rtn.ll | 5 +- .../CodeGen/AMDGPU/buffer-atomic-fadd.f64.ll | 2 + .../AMDGPU/buffer-atomic-fadd.v2f16-no-rtn.ll | 3 + .../AMDGPU/buffer-atomic-fadd.v2f16-rtn.ll | 2 + .../AMDGPU/buffer-intrinsics-mmo-offsets.ll | 1 + .../CodeGen/AMDGPU/bug-v4f64-subvector.ll | 1 + .../test/CodeGen/AMDGPU/carryout-selection.ll | 1 + .../CodeGen/AMDGPU/dagcombine-fma-crash.ll | 1 + .../CodeGen/AMDGPU/directive-amdgcn-target.ll | 2 + .../CodeGen/AMDGPU/divergence-driven-abs.ll | 2 + .../AMDGPU/divergence-driven-bitreverse.ll | 1 + .../AMDGPU/divergence-driven-ctlz-cttz.ll | 1 + .../CodeGen/AMDGPU/divergence-driven-ctpop.ll | 1 + .../AMDGPU/divergence-driven-min-max.ll | 1 + .../divergence-driven-negsubinlineconst.ll | 2 + .../AMDGPU/divergence-driven-not-isel.ll | 1 + .../CodeGen/AMDGPU/divergence-driven-xnor.ll | 2 + .../CodeGen/AMDGPU/elf-header-flags-mach.ll | 2 + .../AMDGPU/extract_subvector_vec4_vec3.ll | 1 + .../CodeGen/AMDGPU/flat-atomic-fadd.f32.ll | 2 + .../CodeGen/AMDGPU/flat-atomic-fadd.f64.ll | 2 + .../fneg-fabs-divergence-driven-isel.ll | 2 + .../AMDGPU/generic-targets-require-v6.ll | 3 + .../AMDGPU/global-atomic-fadd.v2f16-no-rtn.ll | 3 + .../AMDGPU/global-atomic-fadd.v2f16-rtn.ll | 2 + .../AMDGPU/hsa-generic-target-features.ll | 2 + llvm/test/CodeGen/AMDGPU/img-nouse-adjust.ll | 1 + llvm/test/CodeGen/AMDGPU/implicit-def-muse.ll | 1 + ...e92561-restore-undef-scc-verifier-error.ll | 160 + .../CodeGen/AMDGPU/lds-zero-initializer.ll | 24 +- .../AMDGPU/legalize-fp-load-invariant.ll | 1 + llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 5 + .../AMDGPU/llvm.amdgcn.make.buffer.rsrc.ll | 1 + .../AMDGPU/llvm.amdgcn.wave.reduce.umax.mir | 1 + .../AMDGPU/llvm.amdgcn.wave.reduce.umin.mir | 1 + .../CodeGen/AMDGPU/load-store-opt-addc0.mir | 26 + .../AMDGPU/lower-ctor-dtor-constexpr-alias.ll | 3 +- llvm/test/CodeGen/AMDGPU/lower-ctor-dtor.ll | 3 +- llvm/test/CodeGen/AMDGPU/lower-kernargs.ll | 29 +- ...ect-extern-uses-max-reachable-alignment.ll | 2 +- .../AMDGPU/lower-multiple-ctor-dtor.ll | 3 +- llvm/test/CodeGen/AMDGPU/opencl-printf.ll | 8 +- .../AMDGPU/preload-kernargs-IR-lowering.ll | 122 +- llvm/test/CodeGen/AMDGPU/preload-kernargs.ll | 64 +- .../AMDGPU/promote-constOffset-to-imm.mir | 80 +- .../ARM/GlobalISel/arm-legalize-exts.mir | 5 +- llvm/test/CodeGen/ARM/O3-pipeline.ll | 1 + llvm/test/CodeGen/ARM/vdiv_combine.ll | 437 ++- llvm/test/CodeGen/LoongArch/O0-pipeline.ll | 1 + llvm/test/CodeGen/LoongArch/alsl.ll | 6 +- .../LoongArch/atomicrmw-uinc-udec-wrap.ll | 4 +- .../CodeGen/LoongArch/ir-instruction/add.ll | 18 +- .../CodeGen/LoongArch/ir-instruction/and.ll | 2 +- .../CodeGen/LoongArch/ir-instruction/call.ll | 2 +- .../LoongArch/ir-instruction/load-store.ll | 4 +- .../CodeGen/LoongArch/ir-instruction/sub.ll | 2 +- llvm/test/CodeGen/LoongArch/opt-pipeline.ll | 1 + .../CodeGen/LoongArch/select-to-shiftand.ll | 5 +- llvm/test/CodeGen/LoongArch/sextw-removal.ll | 29 +- llvm/test/CodeGen/M68k/pipeline.ll | 1 + .../Mips/GlobalISel/legalizer/constants.mir | 6 +- .../Mips/GlobalISel/llvm-ir/rem_and_div.ll | 32 +- .../GlobalISel/llvm-ir/sitofp_and_uitofp.ll | 16 +- .../CodeGen/Mips/call-site-info-output.ll | 9 + llvm/test/CodeGen/NVPTX/combine-mad.ll | 2 +- llvm/test/CodeGen/PowerPC/O0-pipeline.ll | 1 + llvm/test/CodeGen/PowerPC/O3-pipeline.ll | 1 + .../CodeGen/PowerPC/aix-tls-gd-longlong.ll | 85 +- .../PowerPC/aix-tls-le-xcoff-reloc-large32.ll | 2 +- .../PowerPC/aix-tls-xcoff-reloc-large.ll | 6 +- llvm/test/CodeGen/PowerPC/pr44183.ll | 7 +- llvm/test/CodeGen/PowerPC/pr85066.ll | 45 + .../RISCV/GlobalISel/alu-roundtrip-rv64.ll | 10 + .../test/CodeGen/RISCV/GlobalISel/combine.mir | 20 + .../CodeGen/RISCV/GlobalISel/jumptable.ll | 3 - .../legalizer/legalize-abs-rv32.mir | 32 +- .../legalizer/legalize-abs-rv64.mir | 44 +- .../legalize-jump-table-brjt-rv64.mir | 3 +- llvm/test/CodeGen/RISCV/O0-pipeline.ll | 1 + llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 + .../RISCV/atomic-cmpxchg-branch-on-result.ll | 2 +- llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll | 4 +- llvm/test/CodeGen/RISCV/atomic-rmw.ll | 8 +- llvm/test/CodeGen/RISCV/attributes.ll | 4 +- .../global-merge-minsize-smalldata-nonzero.ll | 48 + .../global-merge-minsize-smalldata-zero.ll | 49 + .../CodeGen/RISCV/global-merge-minsize.ll | 40 + llvm/test/CodeGen/RISCV/pr94145.ll | 20 + .../RISCV/rvv/fixed-vectors-trunc-sat-clip.ll | 184 +- .../RISCV/rvv/fixed-vectors-vmul-vp.ll | 282 ++ .../CodeGen/RISCV/rvv/fpclamptosat_vec.ll | 68 +- .../RISCV/rvv/rvv-peephole-vmerge-vops.ll | 6 +- .../CodeGen/RISCV/rvv/strided-load-store.ll | 76 + .../RISCV/rvv/tail-agnostic-impdef-copy.mir | 1 + .../RISCV/rvv/trunc-sat-clip-sdnode.ll | 196 +- llvm/test/CodeGen/RISCV/rvv/vfredmax.ll | 60 +- llvm/test/CodeGen/RISCV/rvv/vfredmin.ll | 60 +- llvm/test/CodeGen/RISCV/rvv/vfredosum.ll | 60 +- llvm/test/CodeGen/RISCV/rvv/vfredusum.ll | 60 +- llvm/test/CodeGen/RISCV/rvv/vfwredosum.ll | 44 +- llvm/test/CodeGen/RISCV/rvv/vfwredusum.ll | 44 +- llvm/test/CodeGen/RISCV/rvv/vmul-vp.ll | 257 ++ llvm/test/CodeGen/RISCV/rvv/vredand.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredmax.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredmaxu.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredmin.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredminu.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredor.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredsum.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vredxor.ll | 84 +- llvm/test/CodeGen/RISCV/rvv/vsub.ll | 352 ++ llvm/test/CodeGen/RISCV/rvv/vwredsum.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vwredsumu.ll | 72 +- .../RISCV/select-optimize-multiple.mir | 4 + .../test/CodeGen/SPIRV/event-wait-ptr-type.ll | 28 + .../SPIRV/structurizer/merge-exit-break.ll | 84 + .../merge-exit-convergence-in-break.ll | 94 + .../structurizer/merge-exit-multiple-break.ll | 103 + .../merge-exit-simple-white-identity.ll | 49 + .../SPIRV/transcoding/OpBitReverse_i2.ll | 21 + llvm/test/CodeGen/SystemZ/debuginstr-02.mir | 2 + llvm/test/CodeGen/SystemZ/multiselect-02.mir | 2 + llvm/test/CodeGen/Thumb2/mve-tp-loop.mir | 1 + .../CodeGen/WebAssembly/half-precision.ll | 54 + llvm/test/CodeGen/X86/AMX/amx-tile-basic.ll | 42 +- llvm/test/CodeGen/X86/O0-pipeline.ll | 1 + .../CodeGen/X86/apx/asm-constraint-1-jr.ll | 28 + .../CodeGen/X86/apx/asm-constraint-2-jR.ll | 17 + llvm/test/CodeGen/X86/apx/asm-constraint.ll | 19 +- llvm/test/CodeGen/X86/apx/memfold-nd2rmw.mir | 225 ++ llvm/test/CodeGen/X86/apx/no-rex2-general.ll | 2 + .../CodeGen/X86/apx/no-rex2-pseudo-amx.ll | 1 + .../CodeGen/X86/apx/no-rex2-pseudo-x87.ll | 1 + llvm/test/CodeGen/X86/apx/no-rex2-special.ll | 1 + .../basic-block-sections-cloning-invalid.ll | 27 +- .../test/CodeGen/X86/call-site-info-output.ll | 1 + .../X86/instrument-function-inlined.ll | 27 + llvm/test/CodeGen/X86/opt-pipeline.ll | 1 + .../X86/sjlj-shadow-stack-liveness.mir | 1 + llvm/test/CodeGen/X86/vselect-pcmp.ll | 276 ++ llvm/test/CodeGen/X86/widen_load-3.ll | 4 +- llvm/test/DebugInfo/dpvalue-print-nocrash.ll | 0 .../MemorySanitizer/check-constant-shadow.ll | 3 +- .../SanitizerBinaryMetadata/atomics.ll | 12 +- llvm/test/Linker/comdat-largest.ll | 2 +- .../test/MC/AArch64/arm64ec-disallowed-regs.s | 91 + .../MC/LoongArch/Relocations/relax-addsub.s | 2 +- .../MC/LoongArch/Relocations/relax-align.s | 12 +- llvm/test/MC/RISCV/rvzabha-invalid.s | 4 +- llvm/test/MC/RISCV/rvzabha-valid.s | 12 +- llvm/test/MC/RISCV/rvzabha-zacas-valid.s | 16 +- llvm/test/MC/WebAssembly/simd-encodings.s | 18 + .../Object/AMDGPU/elf-header-flags-mach.yaml | 7 + .../rebase-bind-table-trailing-opcode.yaml | 395 +++ ...-rebase-bind-trailing-opcode-boundary.test | 16 + llvm/test/Other/new-pass-manager.ll | 5 +- llvm/test/Other/new-pm-O0-defaults.ll | 6 +- llvm/test/Other/new-pm-defaults.ll | 1 + .../Other/new-pm-thinlto-prelink-defaults.ll | 3 +- .../new-pm-thinlto-prelink-pgo-defaults.ll | 1 + ...w-pm-thinlto-prelink-samplepgo-defaults.ll | 1 + .../Attributor/cb_liveness_disabled.ll | 3 - .../Attributor/cb_liveness_enabled.ll | 3 - .../Transforms/Attributor/value-simplify.ll | 7 +- .../gather-scatter-opt-inseltpoison.ll | 2 +- .../AArch64/gather-scatter-opt.ll | 2 +- .../X86/gather-scatter-opt-inseltpoison.ll | 2 +- .../CodeGenPrepare/X86/gather-scatter-opt.ll | 2 +- .../pre-inliner-instrumentation.ll | 46 + .../GlobalOpt/globalsra-opaque-ptr.ll | 10 +- llvm/test/Transforms/GlobalSplit/basic.ll | 4 +- ...count-expansion-loop-guard-preserve-nsw.ll | 3 +- .../AMDGPU/infer-address-space.ll | 2 +- .../AMDGPU/infer-getelementptr.ll | 8 +- .../old-pass-regressions-inseltpoison.ll | 2 +- .../AMDGPU/old-pass-regressions.ll | 2 +- .../InferAddressSpaces/NVPTX/bug31948.ll | 4 +- .../Transforms/InferAlignment/gep-array.ll | 8 +- .../InstCombine/StoreToNull-DbgCheck.ll | 37 + .../Transforms/InstCombine/apint-shift.ll | 17 +- .../binop-select-cast-of-select-cond.ll | 2 +- .../constant-fold-address-space-pointer.ll | 6 +- .../InstCombine/fold-ext-eq-c-with-op.ll | 58 + .../test/Transforms/InstCombine/gep-vector.ll | 6 +- .../Transforms/InstCombine/getelementptr.ll | 14 +- ...hoist-xor-by-constant-from-xor-by-value.ll | 3 +- .../InstCombine/icmp-of-trunc-ext.ll | 14 + llvm/test/Transforms/InstCombine/lshr.ll | 123 +- llvm/test/Transforms/InstCombine/pr33453.ll | 2 +- llvm/test/Transforms/InstCombine/pr83947.ll | 4 +- llvm/test/Transforms/InstCombine/rem.ll | 4 +- .../Transforms/InstCombine/select-and-or.ll | 4 +- .../InstCombine/select-safe-transforms.ll | 4 +- .../InstSimplify/ConstProp/bitcast.ll | 9 +- .../InstSimplify/ConstProp/icmp-global.ll | 54 +- .../InstSimplify/ConstProp/vectorgep-crash.ll | 2 +- .../InstSimplify/bitcast-vector-fold.ll | 3 +- llvm/test/Transforms/InstSimplify/compare.ll | 114 +- .../Transforms/InstSimplify/past-the-end.ll | 6 +- llvm/test/Transforms/InstSimplify/uscmp.ll | 98 + .../Transforms/InstSimplify/vector_gep.ll | 2 +- .../JumpThreading/constant-fold-status.ll | 3 +- .../peel-loop-min-max-intrinsics.ll | 356 ++ .../AArch64/clamped-trip-count.ll | 92 +- .../LoopVectorize/AArch64/induction-costs.ll | 6 +- .../AArch64/loop-vectorization-factors.ll | 2 +- .../AArch64/sve-tail-folding-forced.ll | 2 +- .../LoopVectorize/RISCV/low-trip-count.ll | 54 +- .../RISCV/riscv-vector-reverse.ll | 4 +- .../LoopVectorize/RISCV/short-trip-count.ll | 14 +- .../LoopVectorize/X86/strided_load_cost.ll | 429 +++ .../first-order-recurrence-chains.ll | 56 +- ...-order-recurrence-sink-replicate-region.ll | 2 +- .../LoopVectorize/first-order-recurrence.ll | 24 +- .../interleave-and-scalarize-only.ll | 4 +- .../scalable-first-order-recurrence.ll | 12 +- .../LoopVectorize/vplan-dot-printing.ll | 2 +- .../vplan-printing-before-execute.ll | 4 +- .../LoopVectorize/vplan-printing.ll | 7 +- .../vplan-sink-scalars-and-merge.ll | 20 +- .../LowerTypeTests/cfi-direct-call1.ll | 10 +- .../LowerTypeTests/function-weak.ll | 74 +- .../NewGVN/2007-07-26-InterlockingLoops.ll | 2 +- .../available_externally_functions.ll | 17 + .../PGOProfile/declarations_only.ll | 13 + .../PGOProfile/global_variables_only.ll | 9 + .../Reassociate/reassoc_bool_vec.ll | 17 +- llvm/test/Transforms/Reassociate/repeats.ll | 45 +- .../test/Transforms/SCCP/conditions-ranges.ll | 9 +- .../SimplifyCFG/branch-fold-threshold.ll | 4 +- .../phi-to-select-constexpr-icmp.ll | 2 +- llvm/test/tools/llc/new-pm/start-stop.ll | 4 +- .../tools/llvm-mca/RISCV/SiFiveP400/load.s | 56 + .../tools/llvm-mca/RISCV/SiFiveP600/load.s | 64 + .../llvm-objdump/ELF/AMDGPU/subtarget.ll | 5 + .../X86/source-interleave-x86_64.test | 2 +- .../llvm-readobj/ELF/AMDGPU/elf-headers.test | 3 + .../llvm-reduce/mir/reduce-register-defs.mir | 2 +- .../tools/llvm-symbolizer/get-input-file.test | 6 +- llvm/tools/llc/llc.cpp | 1 + llvm/tools/llvm-readobj/ELFDumper.cpp | 3 +- .../tools/llvm-symbolizer/llvm-symbolizer.cpp | 8 + llvm/tools/opt/optdriver.cpp | 1 + .../Bitstream/BitstreamWriterTest.cpp | 80 + .../DWARFLinkerParallel/DWARFLinkerTest.cpp | 28 + .../DebugInfo/CodeView/GUIDFormatTest.cpp | 0 .../Frontend/OpenMPDecompositionTest.cpp | 8 +- llvm/unittests/IR/FunctionTest.cpp | 23 + .../AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp | 0 .../TargetParser/RISCVISAInfoTest.cpp | 2 +- .../Transforms/Vectorize/VPlanHCFGTest.cpp | 2 +- .../Transforms/Vectorize/VPlanTestBase.h | 14 +- llvm/utils/TableGen/AsmMatcherEmitter.cpp | 4 +- .../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +- llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 5 +- .../TableGen/Common/CodeGenDAGPatterns.cpp | 3 +- .../TableGen/Common/CodeGenRegisters.cpp | 2 +- .../utils/TableGen/Common/CodeGenSchedule.cpp | 2 +- llvm/utils/TableGen/Common/CodeGenTarget.cpp | 6 +- .../GlobalISelMatchTableExecutorEmitter.cpp | 4 +- llvm/utils/TableGen/DFAEmitter.cpp | 5 +- llvm/utils/TableGen/FastISelEmitter.cpp | 3 +- llvm/utils/TableGen/GlobalISelEmitter.cpp | 5 +- llvm/utils/TableGen/InstrInfoEmitter.cpp | 4 +- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 9 +- .../utils/TableGen/X86InstrMappingEmitter.cpp | 21 + llvm/utils/UpdateTestChecks/asm.py | 3 +- llvm/utils/emacs/llvm-mode.el | 2 + llvm/utils/gn/README.rst | 2 +- llvm/utils/gn/build/libs/terminfo/BUILD.gn | 12 - llvm/utils/gn/build/libs/terminfo/enable.gni | 4 - .../gn/secondary/clang/lib/Basic/BUILD.gn | 1 + .../gn/secondary/clang/lib/Sema/BUILD.gn | 10 + llvm/utils/gn/secondary/clang/test/BUILD.gn | 2 + llvm/utils/gn/secondary/libcxx/src/BUILD.gn | 2 +- .../utils/gn/secondary/libcxxabi/src/BUILD.gn | 2 +- .../utils/gn/secondary/libunwind/src/BUILD.gn | 2 +- .../llvm/include/llvm/Config/BUILD.gn | 7 - .../gn/secondary/llvm/lib/Support/BUILD.gn | 1 - .../secondary/llvm/tools/llvm-config/BUILD.gn | 6 +- .../gn/secondary/llvm/unittests/BUILD.gn | 1 + .../Transforms/Instrumentation/BUILD.gn | 14 + llvm/utils/vim/syntax/llvm.vim | 3 + .../vscode/llvm/syntaxes/ll.tmLanguage.yaml | 3 +- .../GPUToLLVMSPV/GPUToLLVMSPVPass.h | 27 + mlir/include/mlir/Conversion/Passes.h | 1 + mlir/include/mlir/Conversion/Passes.td | 18 + .../include/mlir/Dialect/Arith/IR/ArithOps.td | 16 +- .../Bufferization/IR/BufferizationOps.td | 9 +- mlir/include/mlir/Dialect/IRDL/IRDLSymbols.h | 37 + .../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 21 + mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 9 +- mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td | 37 - .../Dialect/Linalg/IR/LinalgStructuredOps.td | 1 + .../mlir/Dialect/Polynomial/IR/Polynomial.td | 15 +- .../Polynomial/IR/PolynomialAttributes.td | 33 +- .../SCF/Transforms/TileUsingInterface.h | 14 + .../Dialect/Tensor/Transforms/Transforms.h | 10 +- .../include/mlir/Dialect/Tensor/Utils/Utils.h | 13 + .../Vector/TransformOps/VectorTransformOps.td | 14 + .../Vector/Transforms/LoweringPatterns.h | 9 + .../mlir/Interfaces/TilingInterface.td | 66 +- mlir/lib/Bindings/Python/IRCore.cpp | 35 +- mlir/lib/Bindings/Python/IRModule.h | 7 + .../Conversion/ArithToEmitC/ArithToEmitC.cpp | 62 + mlir/lib/Conversion/CMakeLists.txt | 1 + .../Conversion/GPUToLLVMSPV/CMakeLists.txt | 12 + .../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 329 ++ mlir/lib/Conversion/GPUToSPIRV/CMakeLists.txt | 1 + .../Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp | 2 + .../VectorToArmSME/VectorToArmSME.cpp | 32 +- .../VectorToLLVM/ConvertVectorToLLVM.cpp | 68 +- .../VectorToLLVM/ConvertVectorToLLVMPass.cpp | 1 + .../Bufferization/IR/BufferizationOps.cpp | 18 + mlir/lib/Dialect/IRDL/CMakeLists.txt | 1 + mlir/lib/Dialect/IRDL/IR/IRDL.cpp | 7 +- mlir/lib/Dialect/IRDL/IR/IRDLOps.cpp | 10 +- mlir/lib/Dialect/IRDL/IRDLLoading.cpp | 3 +- mlir/lib/Dialect/IRDL/IRDLSymbols.cpp | 38 + mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 38 +- mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp | 23 +- mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp | 48 - mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | 28 + .../Linalg/Transforms/TilingInterfaceImpl.cpp | 104 +- .../IR/PolynomialCanonicalization.td | 42 +- .../Dialect/Polynomial/IR/PolynomialOps.cpp | 119 +- .../SCF/Transforms/TileUsingInterface.cpp | 407 +++ .../Transforms/SparseReinterpretMap.cpp | 4 +- .../Transforms/Utils/LoopEmitter.cpp | 3 +- .../Tensor/IR/TensorTilingInterfaceImpl.cpp | 100 + .../Tensor/Transforms/ReshapePatterns.cpp | 46 +- .../SwapExtractSliceWithProducerPatterns.cpp | 23 + mlir/lib/Dialect/Tensor/Utils/Utils.cpp | 13 +- .../TransformOps/VectorTransformOps.cpp | 5 + .../Dialect/Vector/Transforms/CMakeLists.txt | 1 + .../Vector/Transforms/LowerVectorBitCast.cpp | 96 + mlir/lib/Target/LLVM/NVVM/Target.cpp | 9 +- .../ArithToEmitC/arith-to-emitc.mlir | 39 + .../GPUToLLVMSPV/gpu-to-llvm-spv.mlir | 209 ++ .../VectorToLLVM/vector-to-llvm.mlir | 32 + mlir/test/Dialect/Arith/invalid.mlir | 4 +- mlir/test/Dialect/Bufferization/invalid.mlir | 13 +- mlir/test/Dialect/Bufferization/ops.mlir | 7 +- .../Dialect/GPU/dynamic-shared-memory.mlir | 126 +- mlir/test/Dialect/IRDL/cmath.irdl.mlir | 8 +- mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir | 12 +- mlir/test/Dialect/IRDL/invalid.irdl.mlir | 9 +- mlir/test/Dialect/IRDL/testd.irdl.mlir | 12 +- .../test/Dialect/LLVMIR/constant-folding.mlir | 68 + .../Dialect/LLVMIR/inlining-alias-scopes.mlir | 59 +- mlir/test/Dialect/LLVMIR/rocdl.mlir | 24 - mlir/test/Dialect/Linalg/canonicalize.mlir | 45 + .../Dialect/Polynomial/canonicalization.mlir | 49 +- mlir/test/Dialect/Polynomial/ops.mlir | 18 +- mlir/test/Dialect/Polynomial/ops_errors.mlir | 38 +- .../test/Dialect/SparseTensor/conversion.mlir | 2 +- .../SparseTensor/sparse_fill_zero.mlir | 4 +- .../SparseTensor/specifier_to_llvm.mlir | 12 +- .../Tensor/fold-reassociative-reshapes.mlir | 102 +- .../vector-bitcast-lowering-transforms.mlir | 53 + mlir/test/Examples/transform/ChH/full.mlir | 12 +- mlir/test/IR/invalid-ops.mlir | 4 +- ...test-0-d-vectors.mlir => 0-d-vectors.mlir} | 0 .../{test-mulf-full.mlir => mulf-full.mlir} | 0 .../CPU/AMX/{test-mulf.mlir => mulf.mlir} | 0 .../AMX/{test-muli-ext.mlir => muli-ext.mlir} | 0 .../{test-muli-full.mlir => muli-full.mlir} | 0 .../CPU/AMX/{test-muli.mlir => muli.mlir} | 0 ...ilezero-block.mlir => tilezero-block.mlir} | 0 .../AMX/{test-tilezero.mlir => tilezero.mlir} | 0 ...-load-vertical.mlir => load-vertical.mlir} | 0 ...anspose.mlir => multi-tile-transpose.mlir} | 0 ...16f32.mlir => outerproduct-f16f16f32.mlir} | 0 ...product-f32.mlir => outerproduct-f32.mlir} | 0 ...product-f64.mlir => outerproduct-f64.mlir} | 0 ...i8i8i32.mlir => outerproduct-i8i8i32.mlir} | 0 .../CPU/ArmSME/{test-ssve.mlir => ssve.mlir} | 0 .../ArmSME/{tile_fill.mlir => tile-fill.mlir} | 0 ...fer-read-2d.mlir => transfer-read-2d.mlir} | 0 ...r-write-2d.mlir => transfer-write-2d.mlir} | 0 .../{test-transpose.mlir => transpose.mlir} | 0 .../Emulated/test-scalable-deinterleave.mlir | 30 + ...test-contraction.mlir => contraction.mlir} | 0 ...terleave.mlir => scalable-interleave.mlir} | 0 .../CPU/ArmSVE/{test-sve.mlir => sve.mlir} | 0 .../CPU/X86Vector/{test-dot.mlir => dot.mlir} | 0 ...512.mlir => inline-asm-vector-avx512.mlir} | 0 ...-mask-compress.mlir => mask-compress.mlir} | 0 .../X86Vector/{test-rsqrt.mlir => rsqrt.mlir} | 0 ...t-product.mlir => sparse-dot-product.mlir} | 0 ...tersect-i32.mlir => vp2intersect-i32.mlir} | 0 .../{test-broadcast.mlir => broadcast.mlir} | 0 .../CPU/{test-compress.mlir => compress.mlir} | 0 ...-constant-mask.mlir => constant-mask.mlir} | 0 ...test-contraction.mlir => contraction.mlir} | 0 ...e-mask-v4i1.mlir => create-mask-v4i1.mlir} | 0 ...test-create-mask.mlir => create-mask.mlir} | 0 .../CPU/{test-expand.mlir => expand.mlir} | 0 ...-slice.mlir => extract-strided-slice.mlir} | 0 ...spose-col.mlir => flat-transpose-col.mlir} | 0 ...spose-row.mlir => flat-transpose-row.mlir} | 0 .../Vector/CPU/{test-fma.mlir => fma.mlir} | 0 .../CPU/{test-gather.mlir => gather.mlir} | 0 ...-index-vectors.mlir => index-vectors.mlir} | 0 ...d-slice.mlir => insert-strided-slice.mlir} | 0 .../{test-interleave.mlir => interleave.mlir} | 0 .../{test-maskedload.mlir => maskedload.mlir} | 0 ...test-maskedstore.mlir => maskedstore.mlir} | 0 ...iply-col.mlir => matrix-multiply-col.mlir} | 0 ...iply-row.mlir => matrix-multiply-row.mlir} | 0 ...product-f32.mlir => outerproduct-f32.mlir} | 0 ...product-i64.mlir => outerproduct-i64.mlir} | 0 .../CPU/{test-print-fp.mlir => print-fp.mlir} | 0 .../{test-print-int.mlir => print-int.mlir} | 0 .../{test-print-str.mlir => print-str.mlir} | 0 .../CPU/{test-realloc.mlir => realloc.mlir} | 0 ...assoc.mlir => reductions-f32-reassoc.mlir} | 0 ...eductions-f32.mlir => reductions-f32.mlir} | 0 ...assoc.mlir => reductions-f64-reassoc.mlir} | 0 ...eductions-f64.mlir => reductions-f64.mlir} | 0 ...eductions-i32.mlir => reductions-i32.mlir} | 0 ...-reductions-i4.mlir => reductions-i4.mlir} | 0 ...eductions-i64.mlir => reductions-i64.mlir} | 0 ...eductions-si4.mlir => reductions-si4.mlir} | 0 ...eductions-ui4.mlir => reductions-ui4.mlir} | 0 ...w-types.mlir => rewrite-narrow-types.mlir} | 0 .../Vector/CPU/{test-scan.mlir => scan.mlir} | 0 .../CPU/{test-scatter.mlir => scatter.mlir} | 0 .../{test-shape-cast.mlir => shape-cast.mlir} | 0 .../CPU/{test-shuffle.mlir => shuffle.mlir} | 0 ...st-shuffle16x16.mlir => shuffle16x16.mlir} | 0 ...dot-matvec.mlir => sparse-dot-matvec.mlir} | 0 ...c.mlir => sparse-saxpy-jagged-matvec.mlir} | 0 .../Dialect/Vector/CPU/test-deinterleave.mlir | 18 + ...fer-read-1d.mlir => transfer-read-1d.mlir} | 0 ...fer-read-2d.mlir => transfer-read-2d.mlir} | 0 ...fer-read-3d.mlir => transfer-read-3d.mlir} | 0 ...-transfer-read.mlir => transfer-read.mlir} | 0 ...r-to-loops.mlir => transfer-to-loops.mlir} | 0 ...ransfer-write.mlir => transfer-write.mlir} | 0 .../{test-transpose.mlir => transpose.mlir} | 0 .../tile-and-fuse-consumer.mlir | 317 ++ ...arget-constant-indexing-device-region.mlir | 2 +- ...target-fortran-allocatable-types-host.mlir | 8 +- mlir/test/Target/LLVMIR/rocdl.mlir | 25 - .../TestTilingInterfaceTransformOps.cpp | 53 + .../TestTilingInterfaceTransformOps.td | 19 + .../mlir-vulkan-runner/vector-interleave.mlir | 79 + .../mlir-vulkan-runner/vector-shuffle.mlir | 79 + mlir/test/python/live_operations.py | 46 + offload/DeviceRTL/include/Utils.h | 2 + offload/DeviceRTL/src/Mapping.cpp | 24 +- offload/DeviceRTL/src/Utils.cpp | 15 +- offload/plugins-nextgen/amdgpu/src/rtl.cpp | 37 +- offload/test/api/omp_device_memory.c | 2 +- .../test/offloading/ompx_bare_ballot_sync.c | 26 +- .../offloading/ompx_bare_shfl_down_sync.cpp | 66 + openmp/runtime/src/include/ompx.h.var | 68 +- utils/bazel/.bazelrc | 3 - .../llvm-project-overlay/libc/BUILD.bazel | 108 +- .../lldb/source/Plugins/BUILD.bazel | 1 + .../llvm/include/llvm/Config/config.h | 3 - .../llvm/unittests/BUILD.bazel | 2 + .../llvm-project-overlay/mlir/BUILD.bazel | 28 + utils/bazel/llvm_configs/config.h.cmake | 3 - 2102 files changed, 37750 insertions(+), 17746 deletions(-) create mode 100644 bolt/docs/generate_doc.py delete mode 100644 bolt/test/Inputs/lsda.ldscript create mode 100644 bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s create mode 100644 bolt/test/X86/Inputs/dwarf4-subprogram-multiple-ranges-other.s create mode 100644 bolt/test/X86/Inputs/dwarf5-subprogram-multiple-ranges-other.s create mode 100644 bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test create mode 100644 bolt/test/X86/dwarf4-subprogram-multiple-ranges-cus.test create mode 100644 bolt/test/X86/dwarf5-subprogram-multiple-ranges-cus.test create mode 100644 clang/include/clang/Basic/ASTSourceDescriptor.h create mode 100644 clang/include/clang/Sema/Attr.h create mode 100644 clang/include/clang/Sema/SemaAMDGPU.h create mode 100644 clang/include/clang/Sema/SemaARM.h create mode 100644 clang/include/clang/Sema/SemaBPF.h create mode 100644 clang/include/clang/Sema/SemaHexagon.h create mode 100644 clang/include/clang/Sema/SemaLoongArch.h create mode 100644 clang/include/clang/Sema/SemaMIPS.h create mode 100644 clang/include/clang/Sema/SemaNVPTX.h create mode 100644 clang/include/clang/Sema/SemaPPC.h create mode 100644 clang/include/clang/Sema/SemaSystemZ.h create mode 100644 clang/include/clang/Sema/SemaWasm.h create mode 100644 clang/lib/Basic/ASTSourceDescriptor.cpp create mode 100644 clang/lib/Sema/SemaAMDGPU.cpp create mode 100644 clang/lib/Sema/SemaARM.cpp create mode 100644 clang/lib/Sema/SemaBPF.cpp create mode 100644 clang/lib/Sema/SemaHexagon.cpp create mode 100644 clang/lib/Sema/SemaLoongArch.cpp create mode 100644 clang/lib/Sema/SemaMIPS.cpp create mode 100644 clang/lib/Sema/SemaNVPTX.cpp create mode 100644 clang/lib/Sema/SemaPPC.cpp create mode 100644 clang/lib/Sema/SemaSystemZ.cpp create mode 100644 clang/lib/Sema/SemaWasm.cpp create mode 100644 clang/test/C/C11/n1464.c create mode 100644 clang/test/Driver/x86-apx-inline-asm-use-gpr32.cpp create mode 100644 clang/test/Headers/cuda_wrapper_algorithm.cu create mode 100644 clang/test/Modules/cxx20-decls.cppm create mode 100644 clang/test/Modules/pr93859.cppm delete mode 100644 clang/test/OpenMP/target_reduction_codegen.cpp delete mode 100644 clang/test/OpenMP/target_reduction_messages.cpp create mode 100644 clang/test/SemaCXX/incomplete-array-extent.cpp create mode 100644 clang/test/SemaHLSL/Availability/avail-diag-default-compute.hlsl create mode 100644 clang/test/SemaHLSL/Availability/avail-diag-default-lib.hlsl create mode 100644 clang/test/SemaHLSL/Availability/avail-diag-relaxed-compute.hlsl create mode 100644 clang/test/SemaHLSL/Availability/avail-diag-relaxed-lib.hlsl create mode 100644 clang/test/SemaHLSL/Availability/avail-lib-multiple-stages.hlsl create mode 100644 clang/unittests/Interpreter/InterpreterTestFixture.h create mode 100644 flang/test/Evaluate/signed-mult-opd.f90 create mode 100644 flang/test/Fir/is_assumed_size-codegen.fir create mode 100644 flang/test/Lower/HLFIR/elemental-result-length.f90 create mode 100644 flang/test/Lower/HLFIR/select-rank.f90 create mode 100644 flang/test/Lower/OpenMP/debug_info_conflict.f90 create mode 100644 flang/test/Lower/call-bindc.f90 create mode 100644 flang/test/Preprocessing/args.h create mode 100644 flang/test/Preprocessing/include-args.F90 create mode 100644 flang/test/Semantics/bind-c16.f90 create mode 100644 flang/test/Semantics/resolve123.f90 create mode 100644 flang/test/Semantics/resolve124.f90 create mode 100644 libc/cmake/modules/compiler_features/check_float16.cpp create mode 100644 libc/hdr/types/pid_t.h create mode 100644 libc/include/llvm-libc-macros/float16-macros.h delete mode 100644 libc/src/__support/FPUtil/x86_64/PolyEval.h create mode 100644 libc/src/__support/OSUtil/baremetal/exit.cpp create mode 100644 libc/src/__support/OSUtil/exit.h rename libc/src/__support/OSUtil/gpu/{quick_exit.cpp => exit.cpp} (77%) rename libc/src/__support/OSUtil/linux/{quick_exit.cpp => exit.cpp} (77%) create mode 100644 libc/src/__support/threads/linux/raw_mutex.h rename libc/src/{__support/OSUtil/baremetal/quick_exit.cpp => math/ceilf16.h} (55%) create mode 100644 libc/src/math/fabsf16.h create mode 100644 libc/src/math/floorf16.h create mode 100644 libc/src/math/generic/ceilf16.cpp create mode 100644 libc/src/math/generic/fabsf16.cpp create mode 100644 libc/src/math/generic/floorf16.cpp create mode 100644 libc/src/math/generic/roundevenf16.cpp create mode 100644 libc/src/math/generic/roundf16.cpp create mode 100644 libc/src/math/generic/truncf16.cpp create mode 100644 libc/src/math/roundevenf16.h create mode 100644 libc/src/math/roundf16.h create mode 100644 libc/src/math/truncf16.h create mode 100644 libc/src/pthread/pthread_rwlockattr_getkind_np.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_getkind_np.h create mode 100644 libc/src/pthread/pthread_rwlockattr_setkind_np.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_setkind_np.h create mode 100644 libc/src/stdlib/quick_exit.cpp rename libc/src/{__support/OSUtil => stdlib}/quick_exit.h (62%) create mode 100644 libc/test/src/__support/CPP/algorithm_test.cpp create mode 100644 libc/test/src/__support/threads/CMakeLists.txt create mode 100644 libc/test/src/__support/threads/linux/CMakeLists.txt create mode 100644 libc/test/src/__support/threads/linux/raw_mutex_test.cpp create mode 100644 libc/test/src/math/smoke/ceilf16_test.cpp create mode 100644 libc/test/src/math/smoke/fabsf16_test.cpp create mode 100644 libc/test/src/math/smoke/floorf16_test.cpp create mode 100644 libc/test/src/math/smoke/roundevenf16_test.cpp create mode 100644 libc/test/src/math/smoke/roundf16_test.cpp create mode 100644 libc/test/src/math/smoke/truncf16_test.cpp create mode 100644 libc/test/src/stdlib/quick_exit_test.cpp create mode 100644 libcxx/test/libcxx/atomics/atomics.syn/wait.pass.cpp rename libcxx/test/std/atomics/atomics.ref/{member_types.pass.cpp => member_types.compile.pass.cpp} (99%) rename libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/{totally_ordered.pass.cpp => totally_ordered.compile.pass.cpp} (85%) create mode 100644 libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.compile.pass.cpp delete mode 100644 libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered_with.pass.cpp rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{floating_point.pass.cpp => floating_point.compile.pass.cpp} (97%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{integral.pass.cpp => integral.compile.pass.cpp} (97%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{signed_integral.pass.cpp => signed_integral.compile.pass.cpp} (87%) rename libcxx/test/std/concepts/concepts.lang/concepts.arithmetic/{unsigned_integral.pass.cpp => unsigned_integral.compile.pass.cpp} (82%) rename libcxx/test/std/containers/associative/map/{gcc_workaround.pass.cpp => gcc_workaround.compile.pass.cpp} (88%) rename libcxx/test/std/containers/associative/map/map.cons/{default_recursive.pass.cpp => default_recursive.compile.pass.cpp} (60%) rename libcxx/test/std/containers/associative/multimap/multimap.cons/{default_recursive.pass.cpp => default_recursive.compile.pass.cpp} (59%) rename libcxx/test/std/containers/associative/set/{gcc_workaround.pass.cpp => gcc_workaround.compile.pass.cpp} (93%) rename libcxx/test/std/iterators/iterator.requirements/iterator.assoc.types/readable.traits/{iter_value_t.pass.cpp => iter_value_t.compile.pass.cpp} (96%) rename libcxx/test/std/numerics/numbers/{user_type.pass.cpp => user_type.compile.pass.cpp} (96%) rename libcxx/test/std/strings/char.traits/char.traits.require/{nothing_to_do.pass.cpp => nothing_to_do.compile.pass.cpp} (90%) rename libcxx/test/std/strings/char.traits/char.traits.typedefs/{nothing_to_do.pass.cpp => nothing_to_do.compile.pass.cpp} (90%) rename libcxx/test/std/strings/string.view/string.view.synop/{nothing_to_do.pass.cpp => nothing_to_do.compile.pass.cpp} (91%) rename libcxx/test/std/strings/strings.general/{nothing_to_do.pass.cpp => nothing_to_do.compile.pass.cpp} (90%) delete mode 100644 lld/test/ELF/linkerscript/expr-invalid-sec.test delete mode 100644 lld/test/ELF/linkerscript/expr-sections.test delete mode 100644 lld/test/ELF/linkerscript/orphan-align.s delete mode 100644 lld/test/ELF/linkerscript/orphans.s delete mode 100644 lld/test/ELF/linkerscript/parse-section-in-addr.test create mode 100644 lld/test/ELF/linkerscript/section-not-converge.test create mode 100644 lldb/test/API/lang/c/non-mangled/Makefile create mode 100644 lldb/test/API/lang/c/non-mangled/TestCNonMangled.py create mode 100644 lldb/test/API/lang/c/non-mangled/main.c create mode 100644 lldb/test/API/tools/lldb-dap/variables/children/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py create mode 100644 lldb/test/API/tools/lldb-dap/variables/children/formatter.py create mode 100644 lldb/test/API/tools/lldb-dap/variables/children/main.cpp create mode 100644 lldb/test/requirements.txt delete mode 100644 llvm/cmake/modules/FindTerminfo.cmake mode change 100755 => 100644 llvm/docs/convergence-both-diverged-nested.png mode change 100755 => 100644 llvm/docs/convergence-closed-path.png mode change 100755 => 100644 llvm/docs/convergence-divergent-inside.png mode change 100755 => 100644 llvm/docs/convergence-divergent-outside.png mode change 100755 => 100644 llvm/docs/convergence-natural-loop.png create mode 100644 llvm/include/llvm/CodeGen/FinalizeISel.h create mode 100644 llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp create mode 100644 llvm/lib/Target/X86/X86ISelDAGToDAG.h create mode 100644 llvm/lib/Target/X86/X86PassRegistry.def delete mode 100644 llvm/test/Assembler/2007-04-25-AssemblerFoldExternWeak.ll create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-op-trunc.mir create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/sve-load-store.ll create mode 100644 llvm/test/CodeGen/AArch64/dynamic-regmask-preserve-none.ll create mode 100644 llvm/test/CodeGen/AArch64/fdiv-const.ll mode change 100755 => 100644 llvm/test/CodeGen/AArch64/large-offset-ldr-merge.mir create mode 100644 llvm/test/CodeGen/AArch64/lower-ptrmask-arm64_32.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_call.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_musttail.ll create mode 100644 llvm/test/CodeGen/AArch64/preserve_nonecc_swift.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll create mode 100644 llvm/test/CodeGen/AMDGPU/issue92561-restore-undef-scc-verifier-error.ll create mode 100644 llvm/test/CodeGen/AMDGPU/load-store-opt-addc0.mir create mode 100644 llvm/test/CodeGen/PowerPC/pr85066.ll create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/combine.mir create mode 100644 llvm/test/CodeGen/RISCV/global-merge-minsize-smalldata-nonzero.ll create mode 100644 llvm/test/CodeGen/RISCV/global-merge-minsize-smalldata-zero.ll create mode 100644 llvm/test/CodeGen/RISCV/global-merge-minsize.ll create mode 100644 llvm/test/CodeGen/RISCV/pr94145.ll create mode 100644 llvm/test/CodeGen/SPIRV/event-wait-ptr-type.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-convergence-in-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-multiple-break.ll create mode 100644 llvm/test/CodeGen/SPIRV/structurizer/merge-exit-simple-white-identity.ll create mode 100644 llvm/test/CodeGen/SPIRV/transcoding/OpBitReverse_i2.ll create mode 100644 llvm/test/CodeGen/X86/apx/asm-constraint-1-jr.ll create mode 100644 llvm/test/CodeGen/X86/apx/asm-constraint-2-jR.ll create mode 100644 llvm/test/CodeGen/X86/apx/memfold-nd2rmw.mir create mode 100644 llvm/test/CodeGen/X86/instrument-function-inlined.ll mode change 100755 => 100644 llvm/test/DebugInfo/dpvalue-print-nocrash.ll create mode 100644 llvm/test/MC/AArch64/arm64ec-disallowed-regs.s create mode 100644 llvm/test/Object/Inputs/MachO/rebase-bind-table-trailing-opcode.yaml create mode 100644 llvm/test/Object/macho-rebase-bind-trailing-opcode-boundary.test create mode 100644 llvm/test/Transforms/EntryExitInstrumenter/pre-inliner-instrumentation.ll create mode 100644 llvm/test/Transforms/InstCombine/StoreToNull-DbgCheck.ll create mode 100644 llvm/test/Transforms/InstCombine/fold-ext-eq-c-with-op.ll create mode 100644 llvm/test/Transforms/InstSimplify/uscmp.ll create mode 100644 llvm/test/Transforms/LoopUnroll/peel-loop-min-max-intrinsics.ll create mode 100644 llvm/test/Transforms/PGOProfile/available_externally_functions.ll create mode 100644 llvm/test/Transforms/PGOProfile/declarations_only.ll create mode 100644 llvm/test/Transforms/PGOProfile/global_variables_only.ll create mode 100644 llvm/test/tools/llvm-mca/RISCV/SiFiveP400/load.s create mode 100644 llvm/test/tools/llvm-mca/RISCV/SiFiveP600/load.s mode change 100755 => 100644 llvm/unittests/DebugInfo/CodeView/GUIDFormatTest.cpp mode change 100755 => 100644 llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp delete mode 100644 llvm/utils/gn/build/libs/terminfo/BUILD.gn delete mode 100644 llvm/utils/gn/build/libs/terminfo/enable.gni create mode 100644 llvm/utils/gn/secondary/llvm/unittests/Transforms/Instrumentation/BUILD.gn create mode 100644 mlir/include/mlir/Conversion/GPUToLLVMSPV/GPUToLLVMSPVPass.h create mode 100644 mlir/include/mlir/Dialect/IRDL/IRDLSymbols.h create mode 100644 mlir/lib/Conversion/GPUToLLVMSPV/CMakeLists.txt create mode 100644 mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp create mode 100644 mlir/lib/Dialect/IRDL/IRDLSymbols.cpp create mode 100644 mlir/lib/Dialect/Vector/Transforms/LowerVectorBitCast.cpp create mode 100644 mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir create mode 100644 mlir/test/Dialect/Vector/vector-bitcast-lowering-transforms.mlir rename mlir/test/Integration/Dialect/Vector/CPU/{test-0-d-vectors.mlir => 0-d-vectors.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-mulf-full.mlir => mulf-full.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-mulf.mlir => mulf.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-muli-ext.mlir => muli-ext.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-muli-full.mlir => muli-full.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-muli.mlir => muli.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-tilezero-block.mlir => tilezero-block.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/AMX/{test-tilezero.mlir => tilezero.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-load-vertical.mlir => load-vertical.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-multi-tile-transpose.mlir => multi-tile-transpose.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-outerproduct-f16f16f32.mlir => outerproduct-f16f16f32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-outerproduct-f32.mlir => outerproduct-f32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-outerproduct-f64.mlir => outerproduct-f64.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-outerproduct-i8i8i32.mlir => outerproduct-i8i8i32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-ssve.mlir => ssve.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{tile_fill.mlir => tile-fill.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-transfer-read-2d.mlir => transfer-read-2d.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-transfer-write-2d.mlir => transfer-write-2d.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSME/{test-transpose.mlir => transpose.mlir} (100%) create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/Emulated/test-scalable-deinterleave.mlir rename mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/{test-contraction.mlir => contraction.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/{test-scalable-interleave.mlir => scalable-interleave.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/{test-sve.mlir => sve.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-dot.mlir => dot.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-inline-asm-vector-avx512.mlir => inline-asm-vector-avx512.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-mask-compress.mlir => mask-compress.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-rsqrt.mlir => rsqrt.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-sparse-dot-product.mlir => sparse-dot-product.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/X86Vector/{test-vp2intersect-i32.mlir => vp2intersect-i32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-broadcast.mlir => broadcast.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-compress.mlir => compress.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-constant-mask.mlir => constant-mask.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-contraction.mlir => contraction.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-create-mask-v4i1.mlir => create-mask-v4i1.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-create-mask.mlir => create-mask.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-expand.mlir => expand.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-extract-strided-slice.mlir => extract-strided-slice.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-flat-transpose-col.mlir => flat-transpose-col.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-flat-transpose-row.mlir => flat-transpose-row.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-fma.mlir => fma.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-gather.mlir => gather.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-index-vectors.mlir => index-vectors.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-insert-strided-slice.mlir => insert-strided-slice.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-interleave.mlir => interleave.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-maskedload.mlir => maskedload.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-maskedstore.mlir => maskedstore.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-matrix-multiply-col.mlir => matrix-multiply-col.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-matrix-multiply-row.mlir => matrix-multiply-row.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-outerproduct-f32.mlir => outerproduct-f32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-outerproduct-i64.mlir => outerproduct-i64.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-print-fp.mlir => print-fp.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-print-int.mlir => print-int.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-print-str.mlir => print-str.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-realloc.mlir => realloc.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-f32-reassoc.mlir => reductions-f32-reassoc.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-f32.mlir => reductions-f32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-f64-reassoc.mlir => reductions-f64-reassoc.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-f64.mlir => reductions-f64.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-i32.mlir => reductions-i32.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-i4.mlir => reductions-i4.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-i64.mlir => reductions-i64.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-si4.mlir => reductions-si4.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-reductions-ui4.mlir => reductions-ui4.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-rewrite-narrow-types.mlir => rewrite-narrow-types.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-scan.mlir => scan.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-scatter.mlir => scatter.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-shape-cast.mlir => shape-cast.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-shuffle.mlir => shuffle.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-shuffle16x16.mlir => shuffle16x16.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-sparse-dot-matvec.mlir => sparse-dot-matvec.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-sparse-saxpy-jagged-matvec.mlir => sparse-saxpy-jagged-matvec.mlir} (100%) create mode 100644 mlir/test/Integration/Dialect/Vector/CPU/test-deinterleave.mlir rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-read-1d.mlir => transfer-read-1d.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-read-2d.mlir => transfer-read-2d.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-read-3d.mlir => transfer-read-3d.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-read.mlir => transfer-read.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-to-loops.mlir => transfer-to-loops.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transfer-write.mlir => transfer-write.mlir} (100%) rename mlir/test/Integration/Dialect/Vector/CPU/{test-transpose.mlir => transpose.mlir} (100%) create mode 100644 mlir/test/Interfaces/TilingInterface/tile-and-fuse-consumer.mlir create mode 100644 mlir/test/mlir-vulkan-runner/vector-interleave.mlir create mode 100644 mlir/test/mlir-vulkan-runner/vector-shuffle.mlir create mode 100644 mlir/test/python/live_operations.py create mode 100644 offload/test/offloading/ompx_bare_shfl_down_sync.cpp diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index bb7d2117e277..033ab804b165 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -56,7 +56,6 @@ function compute-projects-to-test() { isForWindows=$1 shift projects=${@} - echo "isForWindows : $isForWindows ; projects: $projects " >&2 for project in ${projects}; do echo "${project}" case ${project} in diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml index 0aa7f761ee0a..b3e2c8243a01 100644 --- a/.github/new-prs-labeler.yml +++ b/.github/new-prs-labeler.yml @@ -717,6 +717,16 @@ backend:AMDGPU: - '**/*amdgpu*/**' - '**/*AMDGPU*/**' +backend:NVPTX: + - 'llvm/**/*nvvm*' + - 'llvm/**/*NVVM*' + - 'llvm/**/*nvptx*' + - 'llvm/**/*NVPTX*' + - 'llvm/**/*nvvm*/**' + - 'llvm/**/*NVVM*/**' + - 'llvm/**/*nvptx*/**' + - 'llvm/**/*NVPTX*/**' + backend:RISC-V: - clang/**/*riscv* - clang/**/*RISCV* @@ -749,6 +759,8 @@ backend:ARM: - clang/lib/CodeGen/Targets/ARM.cpp - clang/include/clang/Basic/BuiltinsARM* - llvm/test/MC/DisasemblerARM/** + - clang/include/clang/Sema/SemaARM.h + - clang/lib/Sema/SemaARM.cpp backend:AArch64: - llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -760,6 +772,8 @@ backend:AArch64: - clang/lib/CodeGen/Targets/AArch64.cpp - clang/include/clang/Basic/BuiltinsAArch64* - llvm/test/MC/Disassembler/AArch64/** + - clang/include/clang/Sema/SemaARM.h + - clang/lib/Sema/SemaARM.cpp backend:loongarch: - llvm/include/llvm/IR/IntrinsicsLoongArch.td @@ -770,6 +784,8 @@ backend:loongarch: - clang/lib/Driver/ToolChains/Arch/LoongArch.* - clang/lib/CodeGen/Targets/LoongArch.cpp - clang/include/clang/Basic/BuiltinsLoongArch* + - clang/include/clang/Sema/SemaLoongArch.h + - clang/lib/Sema/SemaLoongArch.cpp backend:MSP430: - llvm/include/llvm/IR/IntrinsicsMSP430.td @@ -817,6 +833,8 @@ backend:WebAssembly: - llvm/unittests/Target/WebAssembly/** - llvm/test/DebugInfo/WebAssembly/** - llvm/test/MC/WebAssembly/** + - clang/include/clang/Sema/SemaWasm.h + - clang/lib/Sema/SemaLoongWasm.cpp backend:X86: - llvm/include/llvm/IR/IntrinsicsX86.td @@ -836,6 +854,8 @@ backend:X86: - llvm/include/llvm/TargetParser/X86* - llvm/lib/TargetParser/X86* - llvm/utils/TableGen/X86* + - clang/include/clang/Sema/SemaX86.h + - clang/lib/Sema/SemaX86.cpp backend:PowerPC: - llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC* @@ -860,6 +880,8 @@ backend:PowerPC: - clang/lib/Driver/ToolChains/AIX* - clang/lib/Driver/ToolChains/Arch/PPC.* - clang/test/CodeGen/PowerPC/** + - clang/include/clang/Sema/SemaPPC.h + - clang/lib/Sema/SemaPPC.cpp backend:SystemZ: - llvm/include/llvm/BinaryFormat/ELFRelocs/SystemZ* @@ -880,6 +902,8 @@ backend:SystemZ: - clang/lib/Driver/ToolChains/ZOS* - clang/lib/Driver/ToolChains/Arch/SystemZ.* - clang/test/CodeGen/SystemZ/** + - clang/include/clang/Sema/SemaSystemZ.h + - clang/lib/Sema/SemaSystemZ.cpp third-party:unittests: - third-party/unittests/** diff --git a/.github/workflows/restart-preempted-libcxx-jobs.yaml b/.github/workflows/restart-preempted-libcxx-jobs.yaml index 71e27ff2abb9..f8faaf25045b 100644 --- a/.github/workflows/restart-preempted-libcxx-jobs.yaml +++ b/.github/workflows/restart-preempted-libcxx-jobs.yaml @@ -24,7 +24,7 @@ jobs: name: "Restart Job" permissions: statuses: read - checks: read + checks: write actions: write runs-on: ubuntu-latest steps: @@ -35,11 +35,36 @@ jobs: const failure_regex = /Process completed with exit code 1./ const preemption_regex = /The runner has received a shutdown signal/ + const wf_run = context.payload.workflow_run + core.notice(`Running on "${wf_run.display_title}" by @${wf_run.actor.login} (event: ${wf_run.event})\nWorkflow run URL: ${wf_run.html_url}`) + + + async function create_check_run(conclusion, message) { + // Create a check run on the given workflow run to indicate if + // we are restarting the workflow or not. + if (conclusion != 'success' && conclusion != 'skipped' && conclusion != 'neutral') { + core.setFailed('Invalid conclusion: ' + conclusion) + } + await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: 'Restart Preempted Job', + head_sha: wf_run.head_sha, + status: 'completed', + conclusion: conclusion, + output: { + title: 'Restarted Preempted Job', + summary: message + } + }) + } + console.log('Listing check runs for suite') const check_suites = await github.rest.checks.listForSuite({ owner: context.repo.owner, repo: context.repo.repo, - check_suite_id: context.payload.workflow_run.check_suite_id + check_suite_id: context.payload.workflow_run.check_suite_id, + per_page: 100 // FIXME: We don't have 100 check runs yet, but we should handle this better. }) check_run_ids = []; @@ -83,23 +108,27 @@ jobs: if (failure_match != null) { // We only want to restart the workflow if all of the failures were due to preemption. // We don't want to restart the workflow if there were other failures. - console.log('Choosing not to rerun workflow because we found a non-preemption failure'); - console.log('Failure message: ' + annotation.message); + core.notice('Choosing not to rerun workflow because we found a non-preemption failure' + + 'Failure message: "' + annotation.message + '"'); + await create_check_run('skipped', 'Choosing not to rerun workflow because we found a non-preemption failure\n' + + 'Failure message: ' + annotation.message) return; } } } if (!has_preempted_job) { - console.log('No preempted jobs found. Not restarting workflow.'); + core.notice('No preempted jobs found. Not restarting workflow.'); + await create_check_run('neutral', 'No preempted jobs found. Not restarting workflow.') return; } - console.log("Restarted workflow: " + context.payload.workflow_run.id); + core.notice("Restarted workflow: " + context.payload.workflow_run.id); await github.rest.actions.reRunWorkflowFailedJobs({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.payload.workflow_run.id }) + await create_check_run('success', 'Restarted workflow run due to preempted job') diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md index 1951ad5a2dc5..8887d1f5d5bd 100644 --- a/bolt/docs/CommandLineArgumentReference.md +++ b/bolt/docs/CommandLineArgumentReference.md @@ -6,41 +6,37 @@ ## OPTIONS -### Generic options +### Generic options: - `-h` - Alias for `--help` + Alias for --help - `--help` - Display available options (`--help-hidden` for more). + Display available options (--help-hidden for more) - `--help-hidden` - Display all available options. + Display all available options - `--help-list` - Display list of available options (`--help-list-hidden` for more). + Display list of available options (--help-list-hidden for more) - `--help-list-hidden` - Display list of all available options. + Display list of all available options -- `--print-all-options` - - Print all option values after command line parsing. - -- `--print-options` +- `--version` - Print non-default options after command line parsing. + Display the version of this program -- `--version` +### Output options: - Display the version of this program. +- `--bolt-info` -### Output options + Write bolt info section in the output binary - `-o ` @@ -50,7 +46,7 @@ Save recorded profile to a file -### BOLT generic options +### BOLT generic options: - `--align-text=` @@ -89,15 +85,20 @@ - `--data=` - + data file + +- `--data2=` + + data file - `--debug-skeleton-cu` - Prints out offsets for abbrev and debug_info of Skeleton CUs that get patched. + Prints out offsetrs for abbrev and debu_info of Skeleton CUs that get patched. - `--deterministic-debuginfo` - Disables parallel execution of tasks that may produce nondeterministic debug info + Disables parallel execution of tasks that may produce nondeterministic debug + info - `--dot-tooltip-code` @@ -113,7 +114,7 @@ - `--dump-dot-all` - Dump function CFGs to graphviz format after each stage; enable '-print-loops' + Dump function CFGs to graphviz format after each stage;enable '-print-loops' for color-coded blocks - `--dump-orc` @@ -179,8 +180,8 @@ - `--hot-text` Generate hot text symbols. Apply this option to a precompiled binary that - manually calls into hugify, such that at runtime hugify call will put hot - code into 2M pages. This requires relocation. + manually calls into hugify, such that at runtime hugify call will put hot code + into 2M pages. This requires relocation. - `--hot-text-move-sections=` @@ -227,15 +228,15 @@ - `--profile-format=` Format to dump profile output in aggregation mode, default is fdata - - `=fdata`: offset-based plaintext format - - `=yaml`: dense YAML representation + - `fdata`: offset-based plaintext format + - `yaml`: dense YAML representation - `--r11-availability=` Determine the availability of r11 before indirect branches - - `=never`: r11 not available - - `=always`: r11 available before calls and jumps - - `=abi`r11 available before calls but not before jumps + - `never`: r11 not available + - `always`: r11 available before calls and jumps + - `abi`: r11 available before calls but not before jumps - `--relocs` @@ -283,7 +284,8 @@ - `--trap-avx512` - In relocation mode trap upon entry to any function that uses AVX-512 instructions + In relocation mode trap upon entry to any function that uses AVX-512 + instructions - `--trap-old-code` @@ -311,7 +313,7 @@ Output a single dwarf package file (dwp) instead of multiple non-relocatable dwarf object files (dwo). -### BOLT optimization options +### BOLT optimization options: - `--align-blocks` @@ -357,13 +359,14 @@ - `--cg-use-split-hot-size` - Use hot/cold data on basic blocks to determine hot sizes for call graph functions + Use hot/cold data on basic blocks to determine hot sizes for call graph + functions - `--cold-threshold=` Tenths of percents of main entry frequency to use as a threshold when - evaluating whether a basic block is cold (0 means it is only considered - cold if the block has zero samples). Default: 0 + evaluating whether a basic block is cold (0 means it is only considered cold + if the block has zero samples). Default: 0 - `--elim-link-veneers` @@ -375,8 +378,8 @@ - `--equalize-bb-counts` - Use same count for BBs that should have equivalent count (used in non-LBR - and shrink wrapping) + Use same count for BBs that should have equivalent count (used in non-LBR and + shrink wrapping) - `--execution-count-threshold=` @@ -438,8 +441,8 @@ - `--icp-calls-remaining-percent-threshold=` - The percentage threshold against remaining unpromoted indirect call count - for the promotion for calls + The percentage threshold against remaining unpromoted indirect call count for + the promotion for calls - `--icp-calls-topn` @@ -518,22 +521,18 @@ - `--indirect-call-promotion-jump-tables-topn=` - Limit number of targets to consider when doing indirect call promotion on - jump tables. 0 = no limit - -- `--indirect-call-promotion-mispredict-threshold=` - - Misprediction threshold for skipping ICP on an indirect call + Limit number of targets to consider when doing indirect call promotion on jump + tables. 0 = no limit - `--indirect-call-promotion-topn=` - Limit number of targets to consider when doing indirect call promotion. - 0 = no limit + Limit number of targets to consider when doing indirect call promotion. 0 = no + limit - `--indirect-call-promotion-use-mispredicts` Use misprediction frequency for determining whether or not ICP should be - applied at a callsite. The `-indirect-call-promotion-mispredict-threshold` + applied at a callsite. The -indirect-call-promotion-mispredict-threshold value will be used by this heuristic - `--infer-fall-throughs` @@ -566,11 +565,13 @@ - `--inline-small-functions` - Inline functions if increase in size is less than defined by `-inline-small-functions-bytes` + Inline functions if increase in size is less than defined by -inline-small- + functions-bytes - `--inline-small-functions-bytes=` - Max number of bytes for the function to be considered small for inlining purposes + Max number of bytes for the function to be considered small for inlining + purposes - `--instrument` @@ -590,7 +591,7 @@ Make jump tables size smaller at the cost of using more instructions at jump sites -- `-jump-tables=` +- `--jump-tables=` Jump tables support (default=basic) - `none`: do not optimize functions with jump tables @@ -780,23 +781,22 @@ - `--split-strategy=` Strategy used to partition blocks into fragments - - - `profile2`: split each function into a hot and cold fragment using - profiling information + - `profile2`: split each function into a hot and cold fragment using profiling + information - `cdsplit`: split each function into a hot, warm, and cold fragment using profiling information - `random2`: split each function into a hot and cold fragment at a randomly chosen split point (ignoring any available profiling information) - - `randomN`: split each function into N fragments at randomly chosen split + - `randomN`: split each function into N fragments at a randomly chosen split points (ignoring any available profiling information) - - `all`: split all basic blocks of each function into fragments such that - each fragment contains exactly a single basic block + - `all`: split all basic blocks of each function into fragments such that each + fragment contains exactly a single basic block - `--split-threshold=` Split function only if its main size is reduced by more than given amount of - bytes. Default value: 0, i.e. split iff the size is reduced. Note that on - some architectures the size can increase after splitting. + bytes. Default value: 0, i.e. split iff the size is reduced. Note that on some + architectures the size can increase after splitting. - `--stale-matching-max-func-size=` @@ -817,19 +817,20 @@ - `--tail-duplication=` Duplicate unconditional branches that cross a cache line - - - `none` do not apply - - `aggressive` aggressive strategy - - `moderate` moderate strategy - - `cache` cache-aware duplication strategy + - `none`: do not apply + - `aggressive`: aggressive strategy + - `moderate`: moderate strategy + - `cache`: cache-aware duplication strategy - `--tsp-threshold=` - Maximum number of hot basic blocks in a function for which to use a precise TSP solution while re-ordering basic blocks + Maximum number of hot basic blocks in a function for which to use a precise + TSP solution while re-ordering basic blocks - `--use-aggr-reg-reassign` - Use register liveness analysis to try to find more opportunities for -reg-reassign optimization + Use register liveness analysis to try to find more opportunities for -reg- + reassign optimization - `--use-compact-aligner` @@ -847,21 +848,16 @@ Only apply branch boundary alignment in hot code -- `--x86-strip-redundant-address-size` +### BOLT options in relocation mode: - Remove redundant Address-Size override prefix - -### BOLT options in relocation mode - -- `-align-macro-fusion=` +- `--align-macro-fusion=` Fix instruction alignment for macro-fusion (x86 relocation mode) - - `none`: do not insert alignment no-ops for macro-fusion - `hot`: only insert alignment no-ops on hot execution paths (default) - `all`: always align instructions to allow macro-fusion -### BOLT instrumentation options +### BOLT instrumentation options: `llvm-bolt -instrument [-o outputfile] ` @@ -893,72 +889,21 @@ - `--instrumentation-no-counters-clear` - Don't clear counters across dumps (use with `instrumentation-sleep-time` option) + Don't clear counters across dumps (use with instrumentation-sleep-time option) - `--instrumentation-sleep-time=` Interval between profile writes (default: 0 = write only at program end). This is useful for service workloads when you want to dump profile every X - minutes or if you are killing the program and the profile is not being - dumped at the end. + minutes or if you are killing the program and the profile is not being dumped + at the end. - `--instrumentation-wait-forks` Wait until all forks of instrumented process will finish (use with - `instrumentation-sleep-time` option) - -### Data aggregation options (perf2bolt) - -`perf2bolt -p perf.data [-o outputfile] perf.fdata ` - -- `--autofdo` - - Generate autofdo textual data instead of bolt data - -- `--filter-mem-profile` - - If processing a memory profile, filter out stack or heap accesses that won't - be useful for BOLT to reduce profile file size - -- `--ignore-build-id` - - Continue even if build-ids in input binary and perf.data mismatch - -- `--ignore-interrupt-lbr` - - Ignore kernel interrupt LBR that happens asynchronously - -- `--itrace=` - - Generate LBR info with perf itrace argument + instrumentation-sleep-time option) -- `--nl` - - Aggregate basic samples (without LBR info) - -- `--pa` - - Skip perf and read data from a pre-aggregated file format - -- `--perfdata=` - - Data file - -- `--pid=` - - Only use samples from process with specified PID - -- `--time-aggr` - - Time BOLT aggregator - -- `--use-event-pc` - - Use event PC in combination with LBR sampling - -### BOLT printing options - -#### Generic options +### BOLT printing options: - `--print-aliases` @@ -1032,10 +977,10 @@ - `--print-pseudo-probes=` Print pseudo probe info - - `=decode`: decode probes section from binary - - `=address_conversion`: update address2ProbesMap with output block address - - `=encoded_probes`: display the encoded probes in binary section - - `=all`: enable all debugging printout + - `decode`: decode probes section from binary + - `address_conversion`: update address2ProbesMap with output block address + - `encoded_probes`: display the encoded probes in binary section + - `all`: enable all debugging printout - `--print-relocations` @@ -1061,11 +1006,13 @@ Print names of functions with unknown control flow -- `--time-opts` +- `--time-build` - Print time spent in each optimization + Print time spent constructing binary functions + +- `--time-rewrite` -#### Optimization options + Print time spent in rewriting passes - `--print-after-branch-fixup` @@ -1204,10 +1151,14 @@ Print functions after veneer elimination pass -- `--time-build` +- `--time-opts` - Print time spent constructing binary functions + Print time spent in each optimization -- `--time-rewrite` +- `--print-all-options` - Print time spent in rewriting passes + Print all option values after command line parsing + +- `--print-options` + + Print non-default options after command line parsing \ No newline at end of file diff --git a/bolt/docs/generate_doc.py b/bolt/docs/generate_doc.py new file mode 100644 index 000000000000..d8829daf677b --- /dev/null +++ b/bolt/docs/generate_doc.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +# A tool to parse the output of `llvm-bolt --help-hidden` and update the +# documentation in CommandLineArgumentReference.md automatically. +# Run from the directory in which this file is located to update the docs. + +import subprocess +from textwrap import wrap + +LINE_LIMIT = 80 + + +def wrap_text(text, indent, limit=LINE_LIMIT): + wrapped_lines = wrap(text, width=limit - len(indent)) + wrapped_text = ("\n" + indent).join(wrapped_lines) + return wrapped_text + + +def add_info(sections, section, option, description): + indent = " " + wrapped_description = "\n".join( + [ + wrap_text(line, indent) if len(line) > LINE_LIMIT else line + for line in description + ] + ) + sections[section].append((option, indent + wrapped_description)) + + +def parse_bolt_options(output): + section_headers = [ + "Generic options:", + "Output options:", + "BOLT generic options:", + "BOLT optimization options:", + "BOLT options in relocation mode:", + "BOLT instrumentation options:", + "BOLT printing options:", + ] + + sections = {key: [] for key in section_headers} + current_section, prev_section = None, None + option, description = None, [] + + for line in output.split("\n"): + cleaned_line = line.strip() + + if cleaned_line.casefold() in map(str.casefold, section_headers): + if prev_section != None: # Save last option from prev section + add_info(sections, current_section, option, description) + option, description = None, [] + + cleaned_line = cleaned_line.split() + # Apply lowercase to all words except the first one + cleaned_line = [cleaned_line[0]] + [ + word.lower() for word in cleaned_line[1:] + ] + # Join the words back together into a string + cleaned_line = " ".join(cleaned_line) + + current_section = cleaned_line + prev_section = current_section + continue + + if cleaned_line.startswith("-"): + if option and description: + # Join description lines, adding an extra newline for + # sub-options that start with '=' + add_info(sections, current_section, option, description) + option, description = None, [] + + parts = cleaned_line.split(" ", 1) + if len(parts) > 1: + option = parts[0].strip() + descr = parts[1].strip() + descr = descr[2].upper() + descr[3:] + description = [descr] + if option.startswith("--print") or option.startswith("--time"): + current_section = "BOLT printing options:" + elif prev_section != None: + current_section = prev_section + continue + + if cleaned_line.startswith("="): + parts = cleaned_line.split(maxsplit=1) + # Split into two parts: sub-option and description + if len(parts) == 2: + # Rejoin with a single space + cleaned_line = parts[0] + " " + parts[1].rstrip() + description.append(cleaned_line) + elif cleaned_line: # Multiline description continuation + description.append(cleaned_line) + + add_info(sections, current_section, option, description) + return sections + + +def generate_markdown(sections): + markdown_lines = [ + "# BOLT - a post-link optimizer developed to speed up large applications\n", + "## SYNOPSIS\n", + "`llvm-bolt [-o outputfile] .bolt " + "[-data=perf.fdata] [options]`\n", + "## OPTIONS", + ] + + for section, options in sections.items(): + markdown_lines.append(f"\n### {section}") + if section == "BOLT instrumentation options:": + markdown_lines.append( + f"\n`llvm-bolt -instrument" + " [-o outputfile] `" + ) + for option, desc in options: + markdown_lines.append(f"\n- `{option}`\n") + # Split description into lines to handle sub-options + desc_lines = desc.split("\n") + for line in desc_lines: + if line.startswith("="): + # Sub-option: correct formatting with bullet + sub_option, sub_desc = line[1:].split(" ", 1) + markdown_lines.append(f" - `{sub_option}`: {sub_desc[4:]}") + else: + # Regular line of description + if line[2:].startswith("<"): + line = line.replace("<", "").replace(">", "") + markdown_lines.append(f"{line}") + + return "\n".join(markdown_lines) + + +def main(): + try: + help_output = subprocess.run( + ["llvm-bolt", "--help-hidden"], capture_output=True, text=True, check=True + ).stdout + except subprocess.CalledProcessError as e: + print("Failed to execute llvm-bolt --help:") + print(e) + return + + sections = parse_bolt_options(help_output) + markdown = generate_markdown(sections) + + with open("CommandLineArgumentReference.md", "w") as md_file: + md_file.write(markdown) + + +if __name__ == "__main__": + main() diff --git a/bolt/include/bolt/Core/BinaryBasicBlock.h b/bolt/include/bolt/Core/BinaryBasicBlock.h index bc95e2c4de3a..a57b70714fe3 100644 --- a/bolt/include/bolt/Core/BinaryBasicBlock.h +++ b/bolt/include/bolt/Core/BinaryBasicBlock.h @@ -115,7 +115,7 @@ private: unsigned Index{InvalidIndex}; /// Index in the current layout. - mutable unsigned LayoutIndex{InvalidIndex}; + unsigned LayoutIndex{InvalidIndex}; /// Number of pseudo instructions in this block. uint32_t NumPseudos{0}; @@ -891,7 +891,7 @@ public: } /// Set layout index. To be used by BinaryFunction. - void setLayoutIndex(unsigned Index) const { LayoutIndex = Index; } + void setLayoutIndex(unsigned Index) { LayoutIndex = Index; } /// Needed by graph traits. BinaryFunction *getParent() const { return getFunction(); } diff --git a/bolt/include/bolt/Core/FunctionLayout.h b/bolt/include/bolt/Core/FunctionLayout.h index b685a99c79c1..6a13cbec69fe 100644 --- a/bolt/include/bolt/Core/FunctionLayout.h +++ b/bolt/include/bolt/Core/FunctionLayout.h @@ -213,7 +213,8 @@ public: void eraseBasicBlocks(const DenseSet ToErase); /// Make sure fragments' and basic blocks' indices match the current layout. - void updateLayoutIndices(); + void updateLayoutIndices() const; + void updateLayoutIndices(ArrayRef Order) const; /// Replace the current layout with NewLayout. Uses the block's /// self-identifying fragment number to assign blocks to infer function diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index 64113bd02601..a55516d55397 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -21,6 +21,7 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Regex.h" #include #include #include @@ -596,6 +597,9 @@ private: NameResolver NR; + // Regex object matching split function names. + const Regex FunctionFragmentTemplate{"(.*)\\.(cold|warm)(\\.[0-9]+)?"}; + friend class RewriteInstanceDiff; }; diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index c897392f2a57..d13e28999a05 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -3641,8 +3641,8 @@ bool BinaryFunction::forEachEntryPoint(EntryPointCallbackTy Callback) const { BinaryFunction::BasicBlockListType BinaryFunction::dfs() const { BasicBlockListType DFS; - unsigned Index = 0; std::stack Stack; + std::set Visited; // Push entry points to the stack in reverse order. // @@ -3659,17 +3659,13 @@ BinaryFunction::BasicBlockListType BinaryFunction::dfs() const { for (BinaryBasicBlock *const BB : reverse(EntryPoints)) Stack.push(BB); - for (BinaryBasicBlock &BB : blocks()) - BB.setLayoutIndex(BinaryBasicBlock::InvalidIndex); - while (!Stack.empty()) { BinaryBasicBlock *BB = Stack.top(); Stack.pop(); - if (BB->getLayoutIndex() != BinaryBasicBlock::InvalidIndex) + if (Visited.find(BB) != Visited.end()) continue; - - BB->setLayoutIndex(Index++); + Visited.insert(BB); DFS.push_back(BB); for (BinaryBasicBlock *SuccBB : BB->landing_pads()) { diff --git a/bolt/lib/Core/FunctionLayout.cpp b/bolt/lib/Core/FunctionLayout.cpp index 73f4d5247d9a..15e6127ad2e9 100644 --- a/bolt/lib/Core/FunctionLayout.cpp +++ b/bolt/lib/Core/FunctionLayout.cpp @@ -164,15 +164,20 @@ void FunctionLayout::eraseBasicBlocks( updateLayoutIndices(); } -void FunctionLayout::updateLayoutIndices() { +void FunctionLayout::updateLayoutIndices() const { unsigned BlockIndex = 0; - for (FunctionFragment &FF : fragments()) { + for (const FunctionFragment &FF : fragments()) { for (BinaryBasicBlock *const BB : FF) { BB->setLayoutIndex(BlockIndex++); BB->setFragmentNum(FF.getFragmentNum()); } } } +void FunctionLayout::updateLayoutIndices( + ArrayRef Order) const { + for (auto [Index, BB] : llvm::enumerate(Order)) + BB->setLayoutIndex(Index); +} bool FunctionLayout::update(const ArrayRef NewLayout) { const bool EqualBlockOrder = llvm::equal(Blocks, NewLayout); diff --git a/bolt/lib/Passes/IdenticalCodeFolding.cpp b/bolt/lib/Passes/IdenticalCodeFolding.cpp index 87eba10354a3..38e080c9dd62 100644 --- a/bolt/lib/Passes/IdenticalCodeFolding.cpp +++ b/bolt/lib/Passes/IdenticalCodeFolding.cpp @@ -356,7 +356,10 @@ Error IdenticalCodeFolding::runOnFunctions(BinaryContext &BC) { "ICF breakdown", opts::TimeICF); ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) { // Make sure indices are in-order. - BF.getLayout().updateLayoutIndices(); + if (opts::ICFUseDFS) + BF.getLayout().updateLayoutIndices(BF.dfs()); + else + BF.getLayout().updateLayoutIndices(); // Pre-compute hash before pushing into hashtable. // Hash instruction operands to minimize hash collisions. diff --git a/bolt/lib/Profile/YAMLProfileWriter.cpp b/bolt/lib/Profile/YAMLProfileWriter.cpp index cf6b61ddd603..9adbfdc5ff08 100644 --- a/bolt/lib/Profile/YAMLProfileWriter.cpp +++ b/bolt/lib/Profile/YAMLProfileWriter.cpp @@ -74,6 +74,9 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS, llvm::copy(UseDFS ? BF.dfs() : BF.getLayout().blocks(), std::back_inserter(Order)); + const FunctionLayout Layout = BF.getLayout(); + Layout.updateLayoutIndices(Order); + for (const BinaryBasicBlock *BB : Order) { yaml::bolt::BinaryBasicBlockProfile YamlBB; YamlBB.Index = BB->getLayoutIndex(); diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index ab46503621e9..8814ebbd10aa 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -352,7 +352,7 @@ static cl::opt CreateDebugNames( static cl::opt DebugSkeletonCu("debug-skeleton-cu", - cl::desc("prints out offsetrs for abbrev and debu_info of " + cl::desc("prints out offsets for abbrev and debug_info of " "Skeleton CUs that get patched."), cl::ZeroOrMore, cl::Hidden, cl::init(false), cl::cat(BoltCategory)); diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 4b4913dd7a16..e452e956c949 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -55,7 +55,6 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Regex.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/raw_ostream.h" @@ -945,9 +944,6 @@ void RewriteInstance::discoverFileObjects() { BinaryFunction *PreviousFunction = nullptr; unsigned AnonymousId = 0; - // Regex object for matching cold fragments. - const Regex ColdFragment(".*\\.cold(\\.[0-9]+)?"); - const auto SortedSymbolsEnd = LastSymbol == SortedSymbols.end() ? LastSymbol : std::next(LastSymbol); for (auto Iter = SortedSymbols.begin(); Iter != SortedSymbolsEnd; ++Iter) { @@ -1229,7 +1225,7 @@ void RewriteInstance::discoverFileObjects() { } // Check if it's a cold function fragment. - if (ColdFragment.match(SymName)) { + if (FunctionFragmentTemplate.match(SymName)) { static bool PrintedWarning = false; if (!PrintedWarning) { PrintedWarning = true; @@ -1460,10 +1456,10 @@ void RewriteInstance::registerFragments() { for (StringRef Name : Function.getNames()) { StringRef BaseName = NR.restore(Name); const bool IsGlobal = BaseName == Name; - const size_t ColdSuffixPos = BaseName.find(".cold"); - if (ColdSuffixPos == StringRef::npos) + SmallVector Matches; + if (!FunctionFragmentTemplate.match(BaseName, &Matches)) continue; - StringRef ParentName = BaseName.substr(0, ColdSuffixPos); + StringRef ParentName = Matches[1]; const BinaryData *BD = BC->getBinaryDataByName(ParentName); const uint64_t NumPossibleLocalParents = NR.getUniquifiedNameCount(ParentName); diff --git a/bolt/test/AArch64/Inputs/array_end.lld_script b/bolt/test/AArch64/Inputs/array_end.lld_script index 182c13d370a3..bf77c0493a09 100644 --- a/bolt/test/AArch64/Inputs/array_end.lld_script +++ b/bolt/test/AArch64/Inputs/array_end.lld_script @@ -1,4 +1,7 @@ SECTIONS { + .interp : { *(.interp) } + + . = ALIGN(CONSTANT(MAXPAGESIZE)); .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); diff --git a/bolt/test/AArch64/lit.local.cfg b/bolt/test/AArch64/lit.local.cfg index 59fa15a876b5..9432240469c7 100644 --- a/bolt/test/AArch64/lit.local.cfg +++ b/bolt/test/AArch64/lit.local.cfg @@ -1,7 +1,7 @@ if "AArch64" not in config.root.targets: config.unsupported = True -flags = "--target=aarch64-pc-linux -nostartfiles -nostdlib -ffreestanding" +flags = "--target=aarch64-unknown-linux-gnu -nostartfiles -nostdlib -ffreestanding" config.substitutions.insert(0, ("%cflags", f"%cflags {flags}")) config.substitutions.insert(0, ("%cxxflags", f"%cxxflags {flags}")) diff --git a/bolt/test/Inputs/lsda.ldscript b/bolt/test/Inputs/lsda.ldscript deleted file mode 100644 index aa608ecd97e8..000000000000 --- a/bolt/test/Inputs/lsda.ldscript +++ /dev/null @@ -1,7 +0,0 @@ -SECTIONS { - .text : { *(.text*) } - .gcc_except_table.main : { *(.gcc_except_table*) } - . = 0x20000; - .eh_frame : { *(.eh_frame) } - . = 0x80000; -} diff --git a/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s b/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s new file mode 100644 index 000000000000..c04fb521c75d --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf4-df-input-lowpc-ranges-other.s @@ -0,0 +1,710 @@ +## clang++ -fbasic-block-sections=all -ffunction-sections -g2 -gdwarf-4 -gsplit-dwarf -fdebug-compilation-dir='.' +## __attribute__((always_inline)) +## int doStuffOther(int val) { +## if (val) +## ++val; +## return val; +## } +## __attribute__((always_inline)) +## int doStuffOther2(int val) { +## int foo = 3; +## return val + foo; +## } +## +## +## int mainOther(int argc, const char** argv) { +## return doStuffOther(argc) + doStuffOther2(argc);; +## } + + .text + .file "mainOther.cpp" + .section .text._Z12doStuffOtheri,"ax",@progbits + .globl _Z12doStuffOtheri # -- Begin function _Z12doStuffOtheri + .p2align 4, 0x90 + .type _Z12doStuffOtheri,@function +_Z12doStuffOtheri: # @_Z12doStuffOtheri +.Lfunc_begin0: + .file 1 "." "mainOther.cpp" + .loc 1 2 0 # mainOther.cpp:2:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + .loc 1 3 8 prologue_end # mainOther.cpp:3:8 + cmpl $0, -4(%rbp) +.Ltmp1: + .loc 1 3 8 is_stmt 0 # mainOther.cpp:3:8 + je _Z12doStuffOtheri.__part.2 + jmp _Z12doStuffOtheri.__part.1 +.LBB_END0_0: + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,1 +_Z12doStuffOtheri.__part.1: # %if.then + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 4 6 is_stmt 1 # mainOther.cpp:4:6 + movl -4(%rbp), %eax + addl $1, %eax + movl %eax, -4(%rbp) + jmp _Z12doStuffOtheri.__part.2 +.LBB_END0_1: + .size _Z12doStuffOtheri.__part.1, .LBB_END0_1-_Z12doStuffOtheri.__part.1 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,2 +_Z12doStuffOtheri.__part.2: # %if.end + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 5 11 # mainOther.cpp:5:11 + movl -4(%rbp), %eax + .loc 1 5 4 epilogue_begin is_stmt 0 # mainOther.cpp:5:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END0_2: + .size _Z12doStuffOtheri.__part.2, .LBB_END0_2-_Z12doStuffOtheri.__part.2 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits +.Lfunc_end0: + .size _Z12doStuffOtheri, .Lfunc_end0-_Z12doStuffOtheri + # -- End function + .section .text._Z13doStuffOther2i,"ax",@progbits + .globl _Z13doStuffOther2i # -- Begin function _Z13doStuffOther2i + .p2align 4, 0x90 + .type _Z13doStuffOther2i,@function +_Z13doStuffOther2i: # @_Z13doStuffOther2i +.Lfunc_begin1: + .loc 1 8 0 is_stmt 1 # mainOther.cpp:8:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp2: + .loc 1 9 8 prologue_end # mainOther.cpp:9:8 + movl $3, -8(%rbp) + .loc 1 10 11 # mainOther.cpp:10:11 + movl -4(%rbp), %eax + .loc 1 10 15 is_stmt 0 # mainOther.cpp:10:15 + addl -8(%rbp), %eax + .loc 1 10 4 epilogue_begin # mainOther.cpp:10:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END1_0: + .cfi_endproc +.Lfunc_end1: + .size _Z13doStuffOther2i, .Lfunc_end1-_Z13doStuffOther2i + # -- End function + .section .text._Z9mainOtheriPPKc,"ax",@progbits + .globl _Z9mainOtheriPPKc # -- Begin function _Z9mainOtheriPPKc + .p2align 4, 0x90 + .type _Z9mainOtheriPPKc,@function +_Z9mainOtheriPPKc: # @_Z9mainOtheriPPKc +.Lfunc_begin2: + .loc 1 14 0 is_stmt 1 # mainOther.cpp:14:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -16(%rbp) + movq %rsi, -24(%rbp) +.Ltmp3: + .loc 1 15 27 prologue_end # mainOther.cpp:15:27 + movl -16(%rbp), %eax + movl %eax, -12(%rbp) +.Ltmp4: + .loc 1 3 8 # mainOther.cpp:3:8 + cmpl $0, -12(%rbp) +.Ltmp5: + .loc 1 3 8 is_stmt 0 # mainOther.cpp:3:8 + je _Z9mainOtheriPPKc.__part.2 + jmp _Z9mainOtheriPPKc.__part.1 +.LBB_END2_0: + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits,unique,3 +_Z9mainOtheriPPKc.__part.1: # %if.then.i + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 4 6 is_stmt 1 # mainOther.cpp:4:6 + movl -12(%rbp), %eax + addl $1, %eax + movl %eax, -12(%rbp) + jmp _Z9mainOtheriPPKc.__part.2 +.LBB_END2_1: + .size _Z9mainOtheriPPKc.__part.1, .LBB_END2_1-_Z9mainOtheriPPKc.__part.1 + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits,unique,4 +_Z9mainOtheriPPKc.__part.2: # %_Z12doStuffOtheri.exit + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 5 11 # mainOther.cpp:5:11 + movl -12(%rbp), %eax +.Ltmp6: + .loc 1 15 49 # mainOther.cpp:15:49 + movl -16(%rbp), %ecx + movl %ecx, -4(%rbp) +.Ltmp7: + .loc 1 9 8 # mainOther.cpp:9:8 + movl $3, -8(%rbp) + .loc 1 10 11 # mainOther.cpp:10:11 + movl -4(%rbp), %ecx + .loc 1 10 15 is_stmt 0 # mainOther.cpp:10:15 + addl -8(%rbp), %ecx +.Ltmp8: + .loc 1 15 33 is_stmt 1 # mainOther.cpp:15:33 + addl %ecx, %eax + .loc 1 15 6 epilogue_begin is_stmt 0 # mainOther.cpp:15:6 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END2_2: + .size _Z9mainOtheriPPKc.__part.2, .LBB_END2_2-_Z9mainOtheriPPKc.__part.2 + .cfi_endproc + .section .text._Z9mainOtheriPPKc,"ax",@progbits +.Lfunc_end2: + .size _Z9mainOtheriPPKc, .Lfunc_end2-_Z9mainOtheriPPKc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .ascii "\260B" # DW_AT_GNU_dwo_name + .byte 14 # DW_FORM_strp + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .ascii "\262B" # DW_AT_GNU_ranges_base + .byte 23 # DW_FORM_sec_offset + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .ascii "\263B" # DW_AT_GNU_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x29 DW_TAG_compile_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lskel_string0 # DW_AT_comp_dir + # DW_AT_GNU_pubnames + .long .Lskel_string1 # DW_AT_GNU_dwo_name + .quad -1082921489565291703 # DW_AT_GNU_dwo_id + .long .debug_ranges # DW_AT_GNU_ranges_base + .quad 0 # DW_AT_low_pc + .long .Ldebug_ranges3 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_GNU_addr_base +.Ldebug_info_end0: + .section .debug_ranges,"",@progbits +.Ldebug_ranges0: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad 0 + .quad 0 +.Ldebug_ranges1: + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .LBB_END2_2 + .quad .Lfunc_begin2 + .quad .Lfunc_end2 + .quad 0 + .quad 0 +.Ldebug_ranges2: + .quad .Ltmp4 + .quad .Lfunc_end2 + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .Ltmp6 + .quad 0 + .quad 0 +.Ldebug_ranges3: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad .Lfunc_begin1 + .quad .Lfunc_end1 + .quad _Z9mainOtheriPPKc.__part.1 + .quad .LBB_END2_1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .LBB_END2_2 + .quad .Lfunc_begin2 + .quad .Lfunc_end2 + .quad 0 + .quad 0 + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "." # string offset=0 +.Lskel_string1: + .asciz "mainOther.dwo" # string offset=2 + .section .debug_str.dwo,"eMS",@progbits,1 +.Linfo_string0: + .asciz "_Z12doStuffOtheri" # string offset=0 +.Linfo_string1: + .asciz "doStuffOther" # string offset=18 +.Linfo_string2: + .asciz "int" # string offset=31 +.Linfo_string3: + .asciz "val" # string offset=35 +.Linfo_string4: + .asciz "_Z13doStuffOther2i" # string offset=39 +.Linfo_string5: + .asciz "doStuffOther2" # string offset=58 +.Linfo_string6: + .asciz "foo" # string offset=72 +.Linfo_string7: + .asciz "_Z9mainOtheriPPKc" # string offset=76 +.Linfo_string8: + .asciz "mainOther" # string offset=94 +.Linfo_string9: + .asciz "argc" # string offset=104 +.Linfo_string10: + .asciz "argv" # string offset=109 +.Linfo_string11: + .asciz "char" # string offset=114 +.Linfo_string12: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" # string offset=119 +.Linfo_string13: + .asciz "mainOther.cpp" # string offset=223 +.Linfo_string14: + .asciz "mainOther.dwo" # string offset=237 + .section .debug_str_offsets.dwo,"e",@progbits + .long 0 + .long 18 + .long 31 + .long 35 + .long 39 + .long 58 + .long 72 + .long 76 + .long 94 + .long 104 + .long 109 + .long 114 + .long 119 + .long 223 + .long 237 + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0xde DW_TAG_compile_unit + .byte 12 # DW_AT_producer + .short 33 # DW_AT_language + .byte 13 # DW_AT_name + .byte 14 # DW_AT_GNU_dwo_name + .quad -1082921489565291703 # DW_AT_GNU_dwo_id + .byte 2 # Abbrev [2] 0x19:0x14 DW_TAG_subprogram + .long .Ldebug_ranges0-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .long 74 # DW_AT_abstract_origin + .byte 3 # Abbrev [3] 0x24:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 84 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x2d:0x1d DW_TAG_subprogram + .byte 3 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 97 # DW_AT_abstract_origin + .byte 3 # Abbrev [3] 0x39:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 107 # DW_AT_abstract_origin + .byte 5 # Abbrev [5] 0x41:0x8 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .long 115 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x4a:0x13 DW_TAG_subprogram + .byte 0 # DW_AT_linkage_name + .byte 1 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_inline + .byte 7 # Abbrev [7] 0x54:0x8 DW_TAG_formal_parameter + .byte 3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x5d:0x4 DW_TAG_base_type + .byte 2 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x61:0x1b DW_TAG_subprogram + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_inline + .byte 7 # Abbrev [7] 0x6b:0x8 DW_TAG_formal_parameter + .byte 3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 9 # Abbrev [9] 0x73:0x8 DW_TAG_variable + .byte 6 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 10 # Abbrev [10] 0x7c:0x59 DW_TAG_subprogram + .long .Ldebug_ranges1-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_linkage_name + .byte 8 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 93 # DW_AT_type + # DW_AT_external + .byte 11 # Abbrev [11] 0x8b:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 9 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 93 # DW_AT_type + .byte 11 # Abbrev [11] 0x96:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 104 + .byte 10 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 213 # DW_AT_type + .byte 12 # Abbrev [12] 0xa1:0x15 DW_TAG_inlined_subroutine + .long 74 # DW_AT_abstract_origin + .long .Ldebug_ranges2-.debug_ranges # DW_AT_ranges + .byte 1 # DW_AT_call_file + .byte 15 # DW_AT_call_line + .byte 14 # DW_AT_call_column + .byte 3 # Abbrev [3] 0xad:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 116 + .long 84 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 13 # Abbrev [13] 0xb6:0x1e DW_TAG_inlined_subroutine + .long 97 # DW_AT_abstract_origin + .byte 7 # DW_AT_low_pc + .long .Ltmp8-.Ltmp7 # DW_AT_high_pc + .byte 1 # DW_AT_call_file + .byte 15 # DW_AT_call_line + .byte 35 # DW_AT_call_column + .byte 3 # Abbrev [3] 0xc3:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 107 # DW_AT_abstract_origin + .byte 5 # Abbrev [5] 0xcb:0x8 DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .long 115 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 14 # Abbrev [14] 0xd5:0x5 DW_TAG_pointer_type + .long 218 # DW_AT_type + .byte 14 # Abbrev [14] 0xda:0x5 DW_TAG_pointer_type + .long 223 # DW_AT_type + .byte 15 # Abbrev [15] 0xdf:0x5 DW_TAG_const_type + .long 228 # DW_AT_type + .byte 8 # Abbrev [8] 0xe4:0x4 DW_TAG_base_type + .byte 11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end0: + .section .debug_abbrev.dwo,"e",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .ascii "\260B" # DW_AT_GNU_dwo_name + .ascii "\202>" # DW_FORM_GNU_str_index + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 110 # DW_AT_linkage_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 32 # DW_AT_inline + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 14 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 15 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_addr,"",@progbits +.Laddr_table_base0: + .quad _Z12doStuffOtheri.__part.1 + .quad _Z12doStuffOtheri.__part.2 + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .quad _Z9mainOtheriPPKc.__part.1 + .quad _Z9mainOtheriPPKc.__part.2 + .quad .Lfunc_begin2 + .quad .Ltmp7 + .section .debug_gnu_pubnames,"",@progbits + .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info +.LpubNames_start0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 52 # Compilation Unit Length + .long 74 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "doStuffOther" # External Name + .long 97 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "doStuffOther2" # External Name + .long 124 # DIE offset + .byte 48 # Attributes: FUNCTION, EXTERNAL + .asciz "mainOther" # External Name + .long 0 # End Mark +.LpubNames_end0: + .section .debug_gnu_pubtypes,"",@progbits + .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info +.LpubTypes_start0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 52 # Compilation Unit Length + .long 93 # DIE offset + .byte 144 # Attributes: TYPE, STATIC + .asciz "int" # External Name + .long 228 # DIE offset + .byte 144 # Attributes: TYPE, STATIC + .asciz "char" # External Name + .long 0 # End Mark +.LpubTypes_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/Inputs/dwarf4-subprogram-multiple-ranges-other.s b/bolt/test/X86/Inputs/dwarf4-subprogram-multiple-ranges-other.s new file mode 100644 index 000000000000..0745b2f4cef8 --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf4-subprogram-multiple-ranges-other.s @@ -0,0 +1,335 @@ +## clang++ -fbasic-block-sections=all -ffunction-sections -g2 -gdwarf-4 +## int doStuffOther(int val) { +## if (val) +## ++val; +## return val; +## } +## +## int mainOther(int argc, const char** argv) { +## return doStuffOther(argc); +## } + .text + .file "mainOther.cpp" + .section .text._Z12doStuffOtheri,"ax",@progbits + .globl _Z12doStuffOtheri # -- Begin function _Z12doStuffOtheri + .p2align 4, 0x90 + .type _Z12doStuffOtheri,@function +_Z12doStuffOtheri: # @_Z12doStuffOtheri +.Lfunc_begin0: + .file 1 "." "mainOther.cpp" + .loc 1 1 0 # mainOther.cpp:1:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + .loc 1 2 8 prologue_end # mainOther.cpp:2:8 + cmpl $0, -4(%rbp) +.Ltmp1: + .loc 1 2 8 is_stmt 0 # mainOther.cpp:2:8 + je _Z12doStuffOtheri.__part.2 + jmp _Z12doStuffOtheri.__part.1 +.LBB_END0_0: + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,1 +_Z12doStuffOtheri.__part.1: # %if.then + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 3 6 is_stmt 1 # mainOther.cpp:3:6 + movl -4(%rbp), %eax + addl $1, %eax + movl %eax, -4(%rbp) + jmp _Z12doStuffOtheri.__part.2 +.LBB_END0_1: + .size _Z12doStuffOtheri.__part.1, .LBB_END0_1-_Z12doStuffOtheri.__part.1 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,2 +_Z12doStuffOtheri.__part.2: # %if.end + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 1 4 11 # mainOther.cpp:4:11 + movl -4(%rbp), %eax + .loc 1 4 4 epilogue_begin is_stmt 0 # mainOther.cpp:4:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END0_2: + .size _Z12doStuffOtheri.__part.2, .LBB_END0_2-_Z12doStuffOtheri.__part.2 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits +.Lfunc_end0: + .size _Z12doStuffOtheri, .Lfunc_end0-_Z12doStuffOtheri + # -- End function + .section .text._Z9mainOtheriPPKc,"ax",@progbits + .globl _Z9mainOtheriPPKc # -- Begin function _Z9mainOtheriPPKc + .p2align 4, 0x90 + .type _Z9mainOtheriPPKc,@function +_Z9mainOtheriPPKc: # @_Z9mainOtheriPPKc +.Lfunc_begin1: + .loc 1 7 0 is_stmt 1 # mainOther.cpp:7:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp2: + .loc 1 8 27 prologue_end # mainOther.cpp:8:27 + movl -4(%rbp), %edi + .loc 1 8 14 is_stmt 0 # mainOther.cpp:8:14 + callq _Z12doStuffOtheri + .loc 1 8 6 epilogue_begin # mainOther.cpp:8:6 + addq $16, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END1_0: + .cfi_endproc +.Lfunc_end1: + .size _Z9mainOtheriPPKc, .Lfunc_end1-_Z9mainOtheriPPKc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 14 # DW_FORM_strp + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 14 # DW_FORM_strp + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x9b DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 33 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .long .Ldebug_ranges1 # DW_AT_ranges + .byte 2 # Abbrev [2] 0x2a:0x24 DW_TAG_subprogram + .long .Ldebug_ranges0 # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string3 # DW_AT_linkage_name + .long .Linfo_string4 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 136 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x3f:0xe DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long .Linfo_string8 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 136 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x4e:0x3a DW_TAG_subprogram + .quad .Lfunc_begin1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string6 # DW_AT_linkage_name + .long .Linfo_string7 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 136 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x6b:0xe DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long .Linfo_string9 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 136 # DW_AT_type + .byte 3 # Abbrev [3] 0x79:0xe DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .long .Linfo_string10 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 143 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x88:0x7 DW_TAG_base_type + .long .Linfo_string5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x8f:0x5 DW_TAG_pointer_type + .long 148 # DW_AT_type + .byte 6 # Abbrev [6] 0x94:0x5 DW_TAG_pointer_type + .long 153 # DW_AT_type + .byte 7 # Abbrev [7] 0x99:0x5 DW_TAG_const_type + .long 158 # DW_AT_type + .byte 5 # Abbrev [5] 0x9e:0x7 DW_TAG_base_type + .long .Linfo_string11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_ranges,"",@progbits +.Ldebug_ranges0: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad 0 + .quad 0 +.Ldebug_ranges1: + .quad _Z12doStuffOtheri.__part.1 + .quad .LBB_END0_1 + .quad _Z12doStuffOtheri.__part.2 + .quad .LBB_END0_2 + .quad .Lfunc_begin0 + .quad .Lfunc_end0 + .quad .Lfunc_begin1 + .quad .Lfunc_end1 + .quad 0 + .quad 0 + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" # string offset=0 +.Linfo_string1: + .asciz "mainOther.cpp" # string offset=104 +.Linfo_string2: + .asciz "." # string offset=118 +.Linfo_string3: + .asciz "_Z12doStuffOtheri" # string offset=120 +.Linfo_string4: + .asciz "doStuffOther" # string offset=138 +.Linfo_string5: + .asciz "int" # string offset=151 +.Linfo_string6: + .asciz "_Z9mainOtheriPPKc" # string offset=155 +.Linfo_string7: + .asciz "mainOther" # string offset=173 +.Linfo_string8: + .asciz "val" # string offset=183 +.Linfo_string9: + .asciz "argc" # string offset=187 +.Linfo_string10: + .asciz "argv" # string offset=192 +.Linfo_string11: + .asciz "char" # string offset=197 + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym _Z12doStuffOtheri + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/Inputs/dwarf5-subprogram-multiple-ranges-other.s b/bolt/test/X86/Inputs/dwarf5-subprogram-multiple-ranges-other.s new file mode 100644 index 000000000000..6586fc73ed8d --- /dev/null +++ b/bolt/test/X86/Inputs/dwarf5-subprogram-multiple-ranges-other.s @@ -0,0 +1,390 @@ +## clang++ -fbasic-block-sections=all -ffunction-sections -g2 -gdwarf-5 +## int doStuffOther(int val) { +## if (val) +## ++val; +## return val; +## } +## +## int mainOther(int argc, const char** argv) { +## return doStuffOther(argc); +## } + .text + .file "mainOther.cpp" + .section .text._Z12doStuffOtheri,"ax",@progbits + .globl _Z12doStuffOtheri # -- Begin function _Z12doStuffOtheri + .p2align 4, 0x90 + .type _Z12doStuffOtheri,@function +_Z12doStuffOtheri: # @_Z12doStuffOtheri +.Lfunc_begin0: + .file 0 "." "mainOther.cpp" md5 0xe43cc8133fbf67674318eacbcc46a59e + .loc 0 1 0 # mainOther.cpp:1:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp0: + .loc 0 2 8 prologue_end # mainOther.cpp:2:8 + cmpl $0, -4(%rbp) +.Ltmp1: + .loc 0 2 8 is_stmt 0 # mainOther.cpp:2:8 + je _Z12doStuffOtheri.__part.2 + jmp _Z12doStuffOtheri.__part.1 +.LBB_END0_0: + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,1 +_Z12doStuffOtheri.__part.1: # %if.then + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 0 3 6 is_stmt 1 # mainOther.cpp:3:6 + movl -4(%rbp), %eax + addl $1, %eax + movl %eax, -4(%rbp) + jmp _Z12doStuffOtheri.__part.2 +.LBB_END0_1: + .size _Z12doStuffOtheri.__part.1, .LBB_END0_1-_Z12doStuffOtheri.__part.1 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits,unique,2 +_Z12doStuffOtheri.__part.2: # %if.end + .cfi_startproc + .cfi_def_cfa %rbp, 16 + .cfi_offset %rbp, -16 + .loc 0 4 11 # mainOther.cpp:4:11 + movl -4(%rbp), %eax + .loc 0 4 4 epilogue_begin is_stmt 0 # mainOther.cpp:4:4 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END0_2: + .size _Z12doStuffOtheri.__part.2, .LBB_END0_2-_Z12doStuffOtheri.__part.2 + .cfi_endproc + .section .text._Z12doStuffOtheri,"ax",@progbits +.Lfunc_end0: + .size _Z12doStuffOtheri, .Lfunc_end0-_Z12doStuffOtheri + # -- End function + .section .text._Z9mainOtheriPPKc,"ax",@progbits + .globl _Z9mainOtheriPPKc # -- Begin function _Z9mainOtheriPPKc + .p2align 4, 0x90 + .type _Z9mainOtheriPPKc,@function +_Z9mainOtheriPPKc: # @_Z9mainOtheriPPKc +.Lfunc_begin1: + .loc 0 7 0 is_stmt 1 # mainOther.cpp:7:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) +.Ltmp2: + .loc 0 8 27 prologue_end # mainOther.cpp:8:27 + movl -4(%rbp), %edi + .loc 0 8 14 is_stmt 0 # mainOther.cpp:8:14 + callq _Z12doStuffOtheri + .loc 0 8 6 epilogue_begin # mainOther.cpp:8:6 + addq $16, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.LBB_END1_0: + .cfi_endproc +.Lfunc_end1: + .size _Z9mainOtheriPPKc, .Lfunc_end1-_Z9mainOtheriPPKc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 35 # DW_FORM_rnglistx + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 116 # DW_AT_rnglists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 85 # DW_AT_ranges + .byte 35 # DW_FORM_rnglistx + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x76 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .byte 1 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lrnglists_table_base0 # DW_AT_rnglists_base + .byte 2 # Abbrev [2] 0x2b:0x18 DW_TAG_subprogram + .byte 0 # DW_AT_ranges + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_linkage_name + .byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 106 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x37:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 106 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x43:0x27 DW_TAG_subprogram + .byte 3 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 6 # DW_AT_linkage_name + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 106 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x53:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 106 # DW_AT_type + .byte 3 # Abbrev [3] 0x5e:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .long 110 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x6a:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 6 # Abbrev [6] 0x6e:0x5 DW_TAG_pointer_type + .long 115 # DW_AT_type + .byte 6 # Abbrev [6] 0x73:0x5 DW_TAG_pointer_type + .long 120 # DW_AT_type + .byte 7 # Abbrev [7] 0x78:0x5 DW_TAG_const_type + .long 125 # DW_AT_type + .byte 5 # Abbrev [5] 0x7d:0x4 DW_TAG_base_type + .byte 11 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_rnglists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 2 # Offset entry count +.Lrnglists_table_base0: + .long .Ldebug_ranges0-.Lrnglists_table_base0 + .long .Ldebug_ranges1-.Lrnglists_table_base0 +.Ldebug_ranges0: + .byte 3 # DW_RLE_startx_length + .byte 0 # start index + .uleb128 .LBB_END0_1-_Z12doStuffOtheri.__part.1 # length + .byte 3 # DW_RLE_startx_length + .byte 1 # start index + .uleb128 .LBB_END0_2-_Z12doStuffOtheri.__part.2 # length + .byte 3 # DW_RLE_startx_length + .byte 2 # start index + .uleb128 .Lfunc_end0-.Lfunc_begin0 # length + .byte 0 # DW_RLE_end_of_list +.Ldebug_ranges1: + .byte 3 # DW_RLE_startx_length + .byte 0 # start index + .uleb128 .LBB_END0_1-_Z12doStuffOtheri.__part.1 # length + .byte 3 # DW_RLE_startx_length + .byte 1 # start index + .uleb128 .LBB_END0_2-_Z12doStuffOtheri.__part.2 # length + .byte 3 # DW_RLE_startx_length + .byte 2 # start index + .uleb128 .Lfunc_end0-.Lfunc_begin0 # length + .byte 3 # DW_RLE_startx_length + .byte 3 # start index + .uleb128 .Lfunc_end1-.Lfunc_begin1 # length + .byte 0 # DW_RLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_str_offsets,"",@progbits + .long 52 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" # string offset=0 +.Linfo_string1: + .asciz "mainOther.cpp" # string offset=104 +.Linfo_string2: + .asciz "." # string offset=118 +.Linfo_string3: + .asciz "_Z12doStuffOtheri" # string offset=120 +.Linfo_string4: + .asciz "doStuffOther" # string offset=138 +.Linfo_string5: + .asciz "int" # string offset=151 +.Linfo_string6: + .asciz "_Z9mainOtheriPPKc" # string offset=155 +.Linfo_string7: + .asciz "mainOther" # string offset=173 +.Linfo_string8: + .asciz "val" # string offset=183 +.Linfo_string9: + .asciz "argc" # string offset=187 +.Linfo_string10: + .asciz "argv" # string offset=192 +.Linfo_string11: + .asciz "char" # string offset=197 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad _Z12doStuffOtheri.__part.1 + .quad _Z12doStuffOtheri.__part.2 + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .ident "clang version 19.0.0git (git@github.com:llvm/llvm-project.git df542e1ed82bd4e5a9e345d3a3ae63a76893a0cf)" + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym _Z12doStuffOtheri + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/addr32.s b/bolt/test/X86/addr32.s index 1f926c20c7ba..03d626903191 100644 --- a/bolt/test/X86/addr32.s +++ b/bolt/test/X86/addr32.s @@ -1,4 +1,4 @@ -# Check that we don't accidentally strip addr32 prefix +## Check that we don't accidentally strip addr32 prefix # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: ld.lld %t.o -o %t.exe -nostdlib diff --git a/bolt/test/X86/asm-func-debug.test b/bolt/test/X86/asm-func-debug.test index 095ae92da071..3c65051b833d 100644 --- a/bolt/test/X86/asm-func-debug.test +++ b/bolt/test/X86/asm-func-debug.test @@ -1,13 +1,13 @@ -# Verify that we update DW_TAG_compile_unit' ranges and .debug_aranges -# for assembly function that doesn't have corresponding DIE. -# -# The input test case foo() contains nops that we remove. +## Verify that we update DW_TAG_compile_unit' ranges and .debug_aranges +## for assembly function that doesn't have corresponding DIE. +## +## The input test case foo() contains nops that we remove. RUN: %clang %cflags -gdwarf-5 -no-pie %p/../Inputs/asm_foo.s %p/../Inputs/asm_main.c -o %t.exe RUN: llvm-bolt %t.exe -o %t --update-debug-sections RUN: llvm-dwarfdump -all %t | FileCheck %s -# Check ranges were created/updated for asm compile unit +## Check ranges were created/updated for asm compile unit CHECK: 0x0000000c: DW_TAG_compile_unit CHECK-NEXT: DW_AT_stmt_list (0x00000000) CHECK-NEXT: DW_AT_low_pc (0x0000000000000000) @@ -16,11 +16,11 @@ CHECK-NEXT: [0x0000000000[[#%x,ADDR:]], CHECK-SAME: 0x0000000000[[#ADDR+1]])) CHECK-NEXT: DW_AT_name ("{{.*}}asm_foo.s") -# Check .debug_aranges was updated for asm module +## Check .debug_aranges was updated for asm module CHECK: .debug_aranges contents: CHECK-NEXT: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00 CHECK-NEXT: [0x0000000000[[#ADDR]], 0x0000000000[[#ADDR+1]]) -# Check line number info was updated +## Check line number info was updated CHECK: 0x0000000000[[#ADDR]] 13 0 0 0 0 0 is_stmt CHECK-NEXT: 0x0000000000[[#ADDR+1]] 13 0 0 0 0 0 is_stmt end_sequence diff --git a/bolt/test/X86/avx512-trap.test b/bolt/test/X86/avx512-trap.test index 68a0fbc8ff52..93b02f4397cc 100644 --- a/bolt/test/X86/avx512-trap.test +++ b/bolt/test/X86/avx512-trap.test @@ -1,5 +1,5 @@ -# Check that BOLT inserts trap instruction at entry to functions that use AVX-512. -# Check that AVX-512 instruction is updated correctly when -trap-avx512=0 is passed. +## Check that BOLT inserts trap instruction at entry to functions that use AVX-512. +## Check that AVX-512 instruction is updated correctly when -trap-avx512=0 is passed. RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-unknown -o %t.o \ RUN: %S/Inputs/avx512.s @@ -17,11 +17,11 @@ RUN: FileCheck %s --check-prefix=CHECK-DIS-NO-TRAP CHECK: BOLT-WARNING: 1 function will trap on entry -# Check that we have two ud2 instructions - one per entry. +## Check that we have two ud2 instructions - one per entry. CHECK-DIS: use_avx512 CHECK-DIS-NEXT: ud2 CHECK-DIS-NEXT: ud2 -# Check that we generate correct AVX-512 +## Check that we generate correct AVX-512 CHECK-DIS-NO-TRAP: use_avx512 -CHECK-DIS-NO-TRAP: 62 e2 f5 70 2c da vscalefpd +CHECK-DIS-NO-TRAP: 62 e2 f5 70 2c da vscalefpd diff --git a/bolt/test/X86/bb-with-two-tail-calls.s b/bolt/test/X86/bb-with-two-tail-calls.s index 8bbecc498ed7..71807510527f 100644 --- a/bolt/test/X86/bb-with-two-tail-calls.s +++ b/bolt/test/X86/bb-with-two-tail-calls.s @@ -1,5 +1,5 @@ -# This reproduces a bug with dynostats when trying to compute branch stats -# at a block with two tails calls (one conditional and one unconditional). +## This reproduces a bug with dynostats when trying to compute branch stats +## at a block with two tails calls (one conditional and one unconditional). # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ # RUN: %s -o %t.o @@ -17,7 +17,7 @@ # CHECK: {{.*}}: ja {{.*}} # TAILCALL # Offset: 7 # CTCTakenCount: 4 # CHECK-NEXT: {{.*}}: jmp {{.*}} # TAILCALL # Offset: 13 -# Confirm that a deleted basic block is emitted at function end offset (0xe) +## Confirm that a deleted basic block is emitted at function end offset (0xe) # CHECK-BAT: [[#%x,ADDR:]] g .text [[#%x,SIZE:]] _start # CHECK-BAT: Function Address: 0x[[#%x,ADDR]] # CHECK-BAT: 0x[[#%x,SIZE]] diff --git a/bolt/test/X86/block-reordering.test b/bolt/test/X86/block-reordering.test index f3a3390e27cb..526467f996b0 100644 --- a/bolt/test/X86/block-reordering.test +++ b/bolt/test/X86/block-reordering.test @@ -1,5 +1,5 @@ -# Tests whether llvm-bolt is able to reorder blocks and fix branches -# according to the new function layout. +## Tests whether llvm-bolt is able to reorder blocks and fix branches +## according to the new function layout. RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --data %p/Inputs/blarge.fdata \ @@ -46,4 +46,3 @@ CHECK: Exec Count : 0 CHECK: Predecessors: .Ltmp{{.*}} CHECK: {{.*}}: movq %rax, (%rsi) CHECK: {{.*}}: retq - diff --git a/bolt/test/X86/bolt-address-translation-internal-call.test b/bolt/test/X86/bolt-address-translation-internal-call.test index 24cb635e13e9..f20aeb67725f 100644 --- a/bolt/test/X86/bolt-address-translation-internal-call.test +++ b/bolt/test/X86/bolt-address-translation-internal-call.test @@ -1,8 +1,8 @@ -# This checks for an issue with internal calls and BAT (BOLT address -# translation). BAT needs to map every output block back to an input -# block, but passes that introduce new blocks (such as validate -# internal calls) might create new blocks without a mapping to an -# input block. +## This checks for an issue with internal calls and BAT (BOLT address +## translation). BAT needs to map every output block back to an input +## block, but passes that introduce new blocks (such as validate +## internal calls) might create new blocks without a mapping to an +## input block. # REQUIRES: x86_64-linux,bolt-runtime diff --git a/bolt/test/X86/bolt-address-translation-yaml.test b/bolt/test/X86/bolt-address-translation-yaml.test index 8f65eaba891e..3778891c8d91 100644 --- a/bolt/test/X86/bolt-address-translation-yaml.test +++ b/bolt/test/X86/bolt-address-translation-yaml.test @@ -1,11 +1,11 @@ -# Check new BAT format containing hashes for YAML profile. +## Check new BAT format containing hashes for YAML profile. RUN: yaml2obj %p/Inputs/blarge_new.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.out --pa -p %p/Inputs/blarge_new.preagg.txt \ RUN: --reorder-blocks=ext-tsp --split-functions --split-strategy=cdsplit \ RUN: --reorder-functions=cdsort --enable-bat --dyno-stats --skip-funcs=main \ RUN: 2>&1 | FileCheck --check-prefix WRITE-BAT-CHECK %s -# Check that branch with entry in BAT is accounted for. +## Check that branch with entry in BAT is accounted for. RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat_branchentry.preagg.txt \ RUN: -w %t.yaml -o %t.fdata RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o %t.null @@ -15,7 +15,7 @@ BRANCHENTRY-YAML-CHECK: - name: SolveCubic BRANCHENTRY-YAML-CHECK: bid: 0 BRANCHENTRY-YAML-CHECK: hash: 0x700F19D24600000 BRANCHENTRY-YAML-CHECK-NEXT: succ: [ { bid: 7, cnt: 1 } -# Check that the order is correct between BAT YAML and FDATA->YAML. +## Check that the order is correct between BAT YAML and FDATA->YAML. RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat_order.preagg.txt \ RUN: -w %t.yaml -o %t.fdata RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o %t.null @@ -26,16 +26,16 @@ ORDER-YAML-CHECK: bid: 3 ORDER-YAML-CHECK: hash: 0xDDA1DC5F69F900AC ORDER-YAML-CHECK-NEXT: calls: [ { off: 0x26, fid: [[#]], cnt: 20 } ] ORDER-YAML-CHECK-NEXT: succ: [ { bid: 5, cnt: 7 } -# Large profile test +## Large profile test RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat.preagg.txt -w %t.yaml -o %t.fdata \ RUN: 2>&1 | FileCheck --check-prefix READ-BAT-CHECK %s RUN: FileCheck --input-file %t.yaml --check-prefix YAML-BAT-CHECK %s -# Check that YAML converted from fdata matches YAML created directly with BAT. +## Check that YAML converted from fdata matches YAML created directly with BAT. RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null \ RUN: 2>&1 | FileCheck --check-prefix READ-BAT-FDATA-CHECK %s RUN: FileCheck --input-file %t.yaml-fdata --check-prefix YAML-BAT-CHECK %s -# Test resulting YAML profile with the original binary (no-stale mode) +## Test resulting YAML profile with the original binary (no-stale mode) RUN: llvm-bolt %t.exe -data %t.yaml -o %t.null -dyno-stats 2>&1 \ RUN: | FileCheck --check-prefix CHECK-BOLT-YAML %s diff --git a/bolt/test/X86/bolt-address-translation.test b/bolt/test/X86/bolt-address-translation.test index dfdd1eea3233..cdaab1e2d7ef 100644 --- a/bolt/test/X86/bolt-address-translation.test +++ b/bolt/test/X86/bolt-address-translation.test @@ -1,9 +1,9 @@ -# Check a common case for BOLT address translation tables. These tables are used -# to translate profile activity happening in a bolted binary back to the -# original binary, so you can run BOLT again, with updated profile collected -# in a production environment that only runs bolted binaries. As BOLT only -# takes no-bolt binaries as inputs, this translation is necessary to cover -# this scenario. +## Check a common case for BOLT address translation tables. These tables are used +## to translate profile activity happening in a bolted binary back to the +## original binary, so you can run BOLT again, with updated profile collected +## in a production environment that only runs bolted binaries. As BOLT only +## takes no-bolt binaries as inputs, this translation is necessary to cover +## this scenario. # # RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe # RUN: llvm-bolt %t.exe -o %t.out --data %p/Inputs/blarge.fdata \ @@ -11,28 +11,28 @@ # RUN: llvm-bat-dump %t.out --dump-all \ # RUN: --translate=0x401180 | FileCheck %s --check-prefix=CHECK-BAT-DUMP # -# In this test we focus on function usqrt at address 0x401170. This is a -# non-reloc binary case, so we don't expect this address to change, that's -# why we hardcode its address here. This address also comes hardcoded in the -# blarge.yaml input file. -# -# This is the layout of the function before BOLT reorder blocks: -# -# BB Layout : .LBB02, .Ltmp39, .LFT1, .Ltmp38, .LFT2 -# -# This is the layout of the function after BOLT reorder blocks: -# -# BB Layout : .LBB02, .Ltmp38, .Ltmp39, .LFT2, .LFT3 -# -# .Ltmp38 is originally at offset 0x39 but gets moved to 0xc (see full dump -# below). -# -# We check that BAT is able to translate references happening in .Ltmp38 to -# its original offset. -# +## In this test we focus on function usqrt at address 0x401170. This is a +## non-reloc binary case, so we don't expect this address to change, that's +## why we hardcode its address here. This address also comes hardcoded in the +## blarge.yaml input file. +## +## This is the layout of the function before BOLT reorder blocks: +## +## BB Layout : .LBB02, .Ltmp39, .LFT1, .Ltmp38, .LFT2 +## +## This is the layout of the function after BOLT reorder blocks: +## +## BB Layout : .LBB02, .Ltmp38, .Ltmp39, .LFT2, .LFT3 +## +## .Ltmp38 is originally at offset 0x39 but gets moved to 0xc (see full dump +## below). +## +## We check that BAT is able to translate references happening in .Ltmp38 to +## its original offset. +## -# This binary has 3 functions with profile, all of them are split, so 6 maps. -# BAT creates one map per function fragment. +## This binary has 3 functions with profile, all of them are split, so 6 maps. +## BAT creates one map per function fragment. # # CHECK: BOLT: 3 out of 7 functions were overwritten. # CHECK: BOLT-INFO: Wrote 6 BAT maps diff --git a/bolt/test/X86/branch-data.test b/bolt/test/X86/branch-data.test index 0c64caaee8a5..231a77307ffe 100644 --- a/bolt/test/X86/branch-data.test +++ b/bolt/test/X86/branch-data.test @@ -1,6 +1,6 @@ -# Checks that llvm-bolt is able to read data generated by perf2bolt and update -# the CFG edges accordingly with absolute number of branches and mispredictions. -# Also checks that llvm-bolt disassembler and CFG builder is working properly. +## Checks that llvm-bolt is able to read data generated by perf2bolt and update +## the CFG edges accordingly with absolute number of branches and mispredictions. +## Also checks that llvm-bolt disassembler and CFG builder is working properly. RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --data %p/Inputs/blarge.fdata --print-cfg | FileCheck %s diff --git a/bolt/test/X86/broken_dynsym.test b/bolt/test/X86/broken_dynsym.test index 9e7ed405afba..f89fe4aaa474 100644 --- a/bolt/test/X86/broken_dynsym.test +++ b/bolt/test/X86/broken_dynsym.test @@ -1,8 +1,8 @@ -# This test checks if BOLT can process stripped binaries, where symbol's section -# header index is corrupted due to strip tool. +## This test checks if BOLT can process stripped binaries, where symbol's section +## header index is corrupted due to strip tool. # RUN: yaml2obj %p/Inputs/broken_dynsym.yaml -o %t # RUN: llvm-strip -s %t # RUN: llvm-bolt %t -o %t.bolt --allow-stripped | FileCheck %s -# CHECK-NOT: section index out of bounds +# CHECK-NOT: section index out of bounds diff --git a/bolt/test/X86/bug-function-layout-execount.s b/bolt/test/X86/bug-function-layout-execount.s index c88e4d0043b4..238347339f4e 100644 --- a/bolt/test/X86/bug-function-layout-execount.s +++ b/bolt/test/X86/bug-function-layout-execount.s @@ -1,4 +1,4 @@ -# Verifies that llvm-bolt correctly sorts functions by their execution counts. +## Verifies that llvm-bolt correctly sorts functions by their execution counts. # REQUIRES: x86_64-linux, asserts diff --git a/bolt/test/X86/bug-reorder-bb-jrcxz.s b/bolt/test/X86/bug-reorder-bb-jrcxz.s index 13611119beaf..d5ac3548909e 100644 --- a/bolt/test/X86/bug-reorder-bb-jrcxz.s +++ b/bolt/test/X86/bug-reorder-bb-jrcxz.s @@ -1,11 +1,11 @@ -# Test performs a BB reordering with unsupported -# instruction jrcxz. Reordering works correctly with the -# follow options: None, Normal or Reverse. Other strategies -# are completed with Assertion `isIntN(Size * 8 + 1, Value). -# The cause is the distance between BB where one contains -# jrcxz instruction. -# Example: OpenSSL -# https://github.com/openssl/openssl/blob/master/crypto/bn/asm/x86_64-mont5.pl#L3319 +## Test performs a BB reordering with unsupported +## instruction jrcxz. Reordering works correctly with the +## follow options: None, Normal or Reverse. Other strategies +## are completed with Assertion `isIntN(Size * 8 + 1, Value). +## The cause is the distance between BB where one contains +## jrcxz instruction. +## Example: OpenSSL +## https://github.com/openssl/openssl/blob/master/crypto/bn/asm/x86_64-mont5.pl#L3319 # REQUIRES: system-linux diff --git a/bolt/test/X86/calculate-emitted-block-size.s b/bolt/test/X86/calculate-emitted-block-size.s index b1d05b83cb87..820c00fa5508 100644 --- a/bolt/test/X86/calculate-emitted-block-size.s +++ b/bolt/test/X86/calculate-emitted-block-size.s @@ -1,6 +1,6 @@ -# Test BinaryContext::calculateEmittedSize's functionality to update -# BinaryBasicBlock::OutputAddressRange in place so that the emitted size -# of each basic block is given by BinaryBasicBlock::getOutputSize() +## Test BinaryContext::calculateEmittedSize's functionality to update +## BinaryBasicBlock::OutputAddressRange in place so that the emitted size +## of each basic block is given by BinaryBasicBlock::getOutputSize() # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata diff --git a/bolt/test/X86/call-zero.s b/bolt/test/X86/call-zero.s index 3d6308d9e6f8..05ae4b609b19 100644 --- a/bolt/test/X86/call-zero.s +++ b/bolt/test/X86/call-zero.s @@ -1,4 +1,4 @@ -# Verifies that llvm-bolt ignores function calls to 0. +## Verifies that llvm-bolt ignores function calls to 0. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe diff --git a/bolt/test/X86/cdsplit-call-scale.s b/bolt/test/X86/cdsplit-call-scale.s index 5701d9e6dfd6..66f30036de8c 100644 --- a/bolt/test/X86/cdsplit-call-scale.s +++ b/bolt/test/X86/cdsplit-call-scale.s @@ -1,10 +1,10 @@ -# Test the control of aggressiveness of 3-way splitting by -call-scale. -# When -call-scale=0.0, the tested function is 2-way splitted. -# When -call-scale=1.0, the tested function is 3-way splitted with 5 blocks -# in warm because of the increased benefit of shortening the call edges. -# When -call-scale=1000.0, the tested function is still 3-way splitted with -# 5 blocks in warm because cdsplit does not allow hot-warm splitting to break -# a fall through branch from a basic block to its most likely successor. +## Test the control of aggressiveness of 3-way splitting by -call-scale. +## When -call-scale=0.0, the tested function is 2-way splitted. +## When -call-scale=1.0, the tested function is 3-way splitted with 5 blocks +## in warm because of the increased benefit of shortening the call edges. +## When -call-scale=1000.0, the tested function is still 3-way splitted with +## 5 blocks in warm because cdsplit does not allow hot-warm splitting to break +## a fall through branch from a basic block to its most likely successor. # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata diff --git a/bolt/test/X86/cdsplit-symbol-names.s b/bolt/test/X86/cdsplit-symbol-names.s index e53863e22246..0960020d7478 100644 --- a/bolt/test/X86/cdsplit-symbol-names.s +++ b/bolt/test/X86/cdsplit-symbol-names.s @@ -1,6 +1,6 @@ -# Test the correctness of section names and function symbol names post cdsplit. -# Warm section should have name .text.warm and warm function fragments should -# have symbol names ending in warm. +## Test the correctness of section names and function symbol names post cdsplit. +## Warm section should have name .text.warm and warm function fragments should +## have symbol names ending in warm. # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata diff --git a/bolt/test/X86/cfi-expr-rewrite.s b/bolt/test/X86/cfi-expr-rewrite.s index 0d2065417854..6735b382025d 100644 --- a/bolt/test/X86/cfi-expr-rewrite.s +++ b/bolt/test/X86/cfi-expr-rewrite.s @@ -1,5 +1,5 @@ -# Check that llvm-bolt is able to parse DWARF expressions in CFI instructions, -# store them in memory and correctly write them back to the output binary. +## Check that llvm-bolt is able to parse DWARF expressions in CFI instructions, +## store them in memory and correctly write them back to the output binary. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe diff --git a/bolt/test/X86/cfi-instrs-count.s b/bolt/test/X86/cfi-instrs-count.s index 635d560ae753..d91c9bb47fb1 100644 --- a/bolt/test/X86/cfi-instrs-count.s +++ b/bolt/test/X86/cfi-instrs-count.s @@ -1,10 +1,10 @@ -# Check that llvm-bolt is able to read a file with DWARF Exception CFI -# information and annotate this into a disassembled function. +## Check that llvm-bolt is able to read a file with DWARF Exception CFI +## information and annotate this into a disassembled function. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe # RUN: llvm-bolt %t.exe -o %t.null --print-cfg 2>&1 | FileCheck %s -# +# # CHECK: Binary Function "_Z7catchitv" after building cfg { # CHECK: CFI Instrs : 6 # CHECK: } @@ -23,7 +23,7 @@ main: # FDATA: 0 [unknown] 0 1 main 0 0 0 .cfi_startproc -.LBB000: +.LBB000: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 @@ -49,7 +49,7 @@ main: _Z7catchitv: # FDATA: 0 [unknown] 0 1 _Z7catchitv 0 0 0 .cfi_startproc -.LBB00: +.LBB00: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 @@ -64,18 +64,18 @@ _Z7catchitv: .LBB00_br: jmp .Ltmp0 # FDATA: 1 _Z7catchitv #.LBB00_br# 1 _Z7catchitv #.Ltmp0# 0 0 -.LLP0: +.LLP0: cmpq $0x1, %rdx .LLP0_br: je .Ltmp1 # FDATA: 1 _Z7catchitv #.LLP0_br# 1 _Z7catchitv #.Ltmp1# 0 0 # FDATA: 1 _Z7catchitv #.LLP0_br# 1 _Z7catchitv #.LFT0# 0 0 -.LFT0: +.LFT0: movq %rax, %rdi .LFT0_br: callq _Unwind_Resume@PLT # FDATA: 1 _Z7catchitv #.LFT0_br# 1 _Z7catchitv #.Ltmp1# 0 0 -.Ltmp1: +.Ltmp1: movq %rax, %rdi callq __cxa_begin_catch@PLT movq %rax, -0x18(%rbp) @@ -85,7 +85,7 @@ _Z7catchitv: .Ltmp1_br: jmp .Ltmp2 # FDATA: 1 _Z7catchitv #.Ltmp1_br# 1 _Z7catchitv #.Ltmp2# 0 0 -.LLP1: +.LLP1: movl %edx, %ebx movq %rax, %r12 callq __cxa_end_catch@PLT @@ -95,11 +95,11 @@ _Z7catchitv: .LLP1_br: callq _Unwind_Resume@PLT # FDATA: 1 _Z7catchitv #.LLP1_br# 1 _Z7catchitv #.Ltmp2# 0 0 -.Ltmp2: +.Ltmp2: .Ltmp2_br: callq __cxa_end_catch@PLT # FDATA: 1 _Z7catchitv #.Ltmp2_br# 1 _Z7catchitv #.Ltmp0# 0 0 -.Ltmp0: +.Ltmp0: addq $0x10, %rsp popq %rbx popq %r12 diff --git a/bolt/test/X86/cfi-instrs-reordered.s b/bolt/test/X86/cfi-instrs-reordered.s index 8b2fe512f392..c325aaf1ad8b 100644 --- a/bolt/test/X86/cfi-instrs-reordered.s +++ b/bolt/test/X86/cfi-instrs-reordered.s @@ -1,5 +1,5 @@ -# Check that llvm-bolt is able to read a file with DWARF Exception CFI -# information and fix CFI information after reordering. +## Check that llvm-bolt is able to read a file with DWARF Exception CFI +## information and fix CFI information after reordering. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: llvm-strip --strip-unneeded %t.o diff --git a/bolt/test/X86/checkvma-large-section.test b/bolt/test/X86/checkvma-large-section.test index 89aa4f78d52d..427dcdbabf37 100644 --- a/bolt/test/X86/checkvma-large-section.test +++ b/bolt/test/X86/checkvma-large-section.test @@ -1,4 +1,4 @@ -# This test reproduces the issue with a section which ends at >4G address +## This test reproduces the issue with a section which ends at >4G address REQUIRES: asserts RUN: split-file %s %t RUN: yaml2obj %t/yaml -o %t.exe --max-size=0 diff --git a/bolt/test/X86/ctc-and-unreachable.test b/bolt/test/X86/ctc-and-unreachable.test index 0a0b7fcff4ce..55ba1fe316a9 100644 --- a/bolt/test/X86/ctc-and-unreachable.test +++ b/bolt/test/X86/ctc-and-unreachable.test @@ -1,5 +1,5 @@ -# Check that we don't fail processing a function with conditional tail call and -# a fall-through to a next function (result of builtin_unreachable()). +## Check that we don't fail processing a function with conditional tail call and +## a fall-through to a next function (result of builtin_unreachable()). RUN: %clang %cflags %p/Inputs/ctc_and_unreachable.s -o %t.exe -Wl,-q RUN: llvm-bolt %t.exe -o %t --print-after-lowering --print-only=foo 2>&1 | FileCheck %s diff --git a/bolt/test/X86/debug-fission-single-convert.s b/bolt/test/X86/debug-fission-single-convert.s index 82db6700079f..28fcb6686e0a 100644 --- a/bolt/test/X86/debug-fission-single-convert.s +++ b/bolt/test/X86/debug-fission-single-convert.s @@ -1,4 +1,4 @@ -# Checks debug fission support in BOLT +## Checks debug fission support in BOLT # REQUIRES: system-linux diff --git a/bolt/test/X86/debug-fission-single.s b/bolt/test/X86/debug-fission-single.s index 0d25aaef274a..4350bd9ec181 100644 --- a/bolt/test/X86/debug-fission-single.s +++ b/bolt/test/X86/debug-fission-single.s @@ -1,4 +1,4 @@ -# Checks debug fission support in BOLT +## Checks debug fission support in BOLT # REQUIRES: system-linux diff --git a/bolt/test/X86/double-jump.test b/bolt/test/X86/double-jump.test index cbd5ce9dae0e..791872a2b4f8 100644 --- a/bolt/test/X86/double-jump.test +++ b/bolt/test/X86/double-jump.test @@ -1,7 +1,7 @@ -# Test the double jump removal peephole. +## Test the double jump removal peephole. -# This test has commands that rely on shell capabilities that won't execute -# correctly on Windows e.g. subshell execution +## This test has commands that rely on shell capabilities that won't execute +## correctly on Windows e.g. subshell execution REQUIRES: shell RUN: %clang %cflags %p/Inputs/double_jump.cpp -o %t.exe diff --git a/bolt/test/X86/dwarf-handle-visit-loclist-error.s b/bolt/test/X86/dwarf-handle-visit-loclist-error.s index d5ba74fb6016..f14d77285c48 100644 --- a/bolt/test/X86/dwarf-handle-visit-loclist-error.s +++ b/bolt/test/X86/dwarf-handle-visit-loclist-error.s @@ -7,7 +7,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections &> file # RUN: cat file | FileCheck --check-prefix=CHECK %s -# Making sure we handle error returned by visitLocationList correctly. +## Making sure we handle error returned by visitLocationList correctly. # CHECK: BOLT-WARNING: empty location list detected at # CHECK-NEXT: BOLT-WARNING: empty location list detected at diff --git a/bolt/test/X86/dwarf-test-df-logging.test b/bolt/test/X86/dwarf-test-df-logging.test index 6126e9628a31..4219eb3f9205 100644 --- a/bolt/test/X86/dwarf-test-df-logging.test +++ b/bolt/test/X86/dwarf-test-df-logging.test @@ -1,4 +1,4 @@ -; Testing that we print out INFO message when binary has split dwarf. +;; Testing that we print out INFO message when binary has split dwarf. ; RUN: mkdir -p %t ; RUN: cd %t diff --git a/bolt/test/X86/dwarf3-lowpc-highpc-convert.s b/bolt/test/X86/dwarf3-lowpc-highpc-convert.s index faa4dc418f3b..96777a808c4e 100644 --- a/bolt/test/X86/dwarf3-lowpc-highpc-convert.s +++ b/bolt/test/X86/dwarf3-lowpc-highpc-convert.s @@ -8,7 +8,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that DW_AT_high_pc[DW_FORM_ADDR] can be converted to DW_AT_ranges correctly in Dwarf3 +## This tests checks that DW_AT_high_pc[DW_FORM_ADDR] can be converted to DW_AT_ranges correctly in Dwarf3 # PRECHECK: version = 0x0003 # PRECHECK: DW_AT_low_pc diff --git a/bolt/test/X86/dwarf4-cross-cu-backward-different-abbrev.test b/bolt/test/X86/dwarf4-cross-cu-backward-different-abbrev.test index e609440696db..555887a06758 100644 --- a/bolt/test/X86/dwarf4-cross-cu-backward-different-abbrev.test +++ b/bolt/test/X86/dwarf4-cross-cu-backward-different-abbrev.test @@ -7,8 +7,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles backward cross CU references for dwarf4 -# when CUs are have different abbrev tables. +## This test checks that BOLT handles backward cross CU references for dwarf4 +## when CUs are have different abbrev tables. # PRECHECK: DW_TAG_compile_unit # PRECHECK: DW_TAG_compile_unit diff --git a/bolt/test/X86/dwarf4-cross-cu-forward-different-abbrev.test b/bolt/test/X86/dwarf4-cross-cu-forward-different-abbrev.test index e73960e7251e..74c9491d95d3 100644 --- a/bolt/test/X86/dwarf4-cross-cu-forward-different-abbrev.test +++ b/bolt/test/X86/dwarf4-cross-cu-forward-different-abbrev.test @@ -7,8 +7,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles forward cross CU references for dwarf4 -# when CUs are have different abbrev tables. +## This test checks that BOLT handles forward cross CU references for dwarf4 +## when CUs are have different abbrev tables. # PRECHECK: DW_TAG_compile_unit # PRECHECK: DW_AT_abstract_origin [DW_FORM_ref_addr] diff --git a/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test b/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test index 581ce2cffcfd..6bcf8892ed0a 100644 --- a/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test +++ b/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test @@ -8,7 +8,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles location list with DWARF5/DWARF4 when order of CUs is not the same as in input. +## Tests that BOLT correctly handles location list with DWARF5/DWARF4 when order of CUs is not the same as in input. # PRECHECK: version = 0x0005 # PRECHECK: version = 0x0004 diff --git a/bolt/test/X86/dwarf4-df-basic.test b/bolt/test/X86/dwarf4-df-basic.test index d373b62ee618..601c0c58ec0a 100644 --- a/bolt/test/X86/dwarf4-df-basic.test +++ b/bolt/test/X86/dwarf4-df-basic.test @@ -7,6 +7,6 @@ ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections -v 1 &> log ; RUN: cat log | FileCheck %s -check-prefix=BOLT-LOG-CHECK -; Test check we don't print out a warning in -v 1 when Unit DIE doesn't have low_pc/high_pc +;; Test check we don't print out a warning in -v 1 when Unit DIE doesn't have low_pc/high_pc ; BOLT-LOG-CHECK-NOT: BOLT-ERROR: cannot update ranges for DIE in Unit offset diff --git a/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test b/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test index e00958d10614..fa72c798516b 100644 --- a/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test +++ b/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt ; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests that DW_AT_low_pc changes in DW_TAG_GNU_call_site. +;; Tests that DW_AT_low_pc changes in DW_TAG_GNU_call_site. ; PRE-BOLT-DWO-MAIN: version = 0x0004 ; PRE-BOLT-DWO-MAIN: DW_TAG_GNU_call_site diff --git a/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test b/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test index 5173c890f66a..b5aee42f337f 100644 --- a/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test +++ b/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test @@ -10,7 +10,7 @@ ; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt ; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests that new indices are assigned to DW_OP_GNU_addr_index. +;; Tests that new indices are assigned to DW_OP_GNU_addr_index. ; PRE-BOLT-DWO-MAIN: version = 0x0004 ; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x0) diff --git a/bolt/test/X86/dwarf4-df-do-no-convert-low-pc-high-pc-to-ranges.test b/bolt/test/X86/dwarf4-df-do-no-convert-low-pc-high-pc-to-ranges.test index 95c1c747a3d0..9ba8264eac07 100644 --- a/bolt/test/X86/dwarf4-df-do-no-convert-low-pc-high-pc-to-ranges.test +++ b/bolt/test/X86/dwarf4-df-do-no-convert-low-pc-high-pc-to-ranges.test @@ -10,8 +10,8 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo | FileCheck --check-prefix=PRECHECK %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo | FileCheck --check-prefix=POSTCHECK %s -; This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, -; when there is only one output range entry. +;; This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, +;; when there is only one output range entry. ; PRECHECK: DW_TAG_inlined_subroutine ; PRECHECK: DW_AT_abstract_origin diff --git a/bolt/test/X86/dwarf4-df-dualcu-loclist.test b/bolt/test/X86/dwarf4-df-dualcu-loclist.test index 6ef4fb97e8ca..57c75e282421 100644 --- a/bolt/test/X86/dwarf4-df-dualcu-loclist.test +++ b/bolt/test/X86/dwarf4-df-dualcu-loclist.test @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo | FileCheck -check-prefix=PRE-BOLT-DWO-HELPER %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-HELPER %s -; Testing dwarf4 split dwarf for two CUs. Making sure DW_AT_location [DW_FORM_sec_offset] is updated correctly. +;; Testing dwarf4 split dwarf for two CUs. Making sure DW_AT_location [DW_FORM_sec_offset] is updated correctly. ; PRE-BOLT-DWO-MAIN: version = 0x0004 ; PRE-BOLT-DWO-MAIN: DW_TAG_formal_parameter [10] diff --git a/bolt/test/X86/dwarf4-df-dualcu.test b/bolt/test/X86/dwarf4-df-dualcu.test index 91b3e9e4cf09..b690623b70d8 100644 --- a/bolt/test/X86/dwarf4-df-dualcu.test +++ b/bolt/test/X86/dwarf4-df-dualcu.test @@ -20,8 +20,8 @@ ; RUN: not llvm-dwarfdump --show-form --verbose --debug-info helper.dwo.dwo &> helperdwodwo.txt ; RUN: cat helperdwodwo.txt | FileCheck -check-prefix=BOLT-DWO-HELPER %s -; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. -; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx ##) are updated correctly. +;; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. +;; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx ##) are updated correctly. ; PRE-BOLT: version = 0x0004 ; PRE-BOLT: DW_TAG_compile_unit diff --git a/bolt/test/X86/dwarf4-df-inlined-subroutine-lowpc-0.test b/bolt/test/X86/dwarf4-df-inlined-subroutine-lowpc-0.test index 32bffcba4bec..0553a217a12c 100644 --- a/bolt/test/X86/dwarf4-df-inlined-subroutine-lowpc-0.test +++ b/bolt/test/X86/dwarf4-df-inlined-subroutine-lowpc-0.test @@ -9,8 +9,8 @@ ; RUN: llvm-dwarfdump --debug-info --verbose --show-form main.dwo.dwo >> log.txt ; RUN: cat log.txt | FileCheck -check-prefix=BOLT-MAIN %s -; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_low_pc is 0, -; and split dwarf is enabled. +;; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_low_pc is 0, +;; and split dwarf is enabled. ; BOLT-MAIN: 0x ; BOLT-MAIN: 0x diff --git a/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test b/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test new file mode 100644 index 000000000000..c9abd02bbb7d --- /dev/null +++ b/bolt/test/X86/dwarf4-df-input-lowpc-ranges-cus.test @@ -0,0 +1,97 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-main.s \ +; RUN: -split-dwarf-file=main.dwo -o main.o +; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-other.s \ +; RUN: -split-dwarf-file=mainOther.dwo -o other.o +; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o other.o -o main.exe +; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections +; RUN: llvm-dwarfdump --show-form --verbose --debug-ranges main.exe.bolt &> %t/foo.txt +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo.txt +; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s +; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo mainOther.dwo.dwo &> %t/mainddwodwo.txt +; RUN: cat %t/mainddwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s + +;; Tests that BOLT correctly handles Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input and handles multiple CUs with ranges. + +; BOLT: .debug_ranges +; BOLT-NEXT: 00000000 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000010 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000050 +; BOLT-NEXT: 00000090 [[#%.16x,ADDR1:]] [[#%.16x,ADDRB1:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR2:]] [[#%.16x,ADDRB2:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR3:]] [[#%.16x,ADDRB3:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR4:]] [[#%.16x,ADDRB4:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR5:]] [[#%.16x,ADDRB5:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR6:]] [[#%.16x,ADDRB6:]] +; BOLT-NEXT: 00000090 [[#%.16x,ADDR7:]] [[#%.16x,ADDRB7:]] +; BOLT-NEXT: 00000090 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000110 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000150 +; BOLT-NEXT: 00000190 [[#%.16x,ADDR8:]] [[#%.16x,ADDRB8:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR9:]] [[#%.16x,ADDRB9:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR10:]] [[#%.16x,ADDRB10:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR11:]] [[#%.16x,ADDRB11:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR12:]] [[#%.16x,ADDRB12:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR13:]] [[#%.16x,ADDRB13:]] +; BOLT-NEXT: 00000190 [[#%.16x,ADDR14:]] [[#%.16x,ADDRB14:]] +; BOLT-NEXT: 00000190 + +; BOLT: DW_TAG_compile_unit +; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-fA-F]+}}] = "main.dwo.dwo") +; BOLT-NEXT: DW_AT_GNU_dwo_id +; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000010) +; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000090 +; BOLT-NEXT: [0x[[#ADDR1]], 0x[[#ADDRB1]]) +; BOLT-NEXT: [0x[[#ADDR2]], 0x[[#ADDRB2]]) +; BOLT-NEXT: [0x[[#ADDR3]], 0x[[#ADDRB3]]) +; BOLT-NEXT: [0x[[#ADDR4]], 0x[[#ADDRB4]]) +; BOLT-NEXT: [0x[[#ADDR5]], 0x[[#ADDRB5]]) +; BOLT-NEXT: [0x[[#ADDR6]], 0x[[#ADDRB6]]) +; BOLT-NEXT: [0x[[#ADDR7]], 0x[[#ADDRB7]]) +; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) + +; BOLT: DW_TAG_compile_unit +; BOLT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-fA-F]+}}] = "mainOther.dwo.dwo") +; BOLT-NEXT: DW_AT_GNU_dwo_id +; BOLT-NEXT: DW_AT_GNU_ranges_base [DW_FORM_sec_offset] (0x00000110) +; BOLT-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) +; BOLT-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000190 +; BOLT-NEXT: [0x[[#ADDR8]], 0x[[#ADDRB8]]) +; BOLT-NEXT: [0x[[#ADDR9]], 0x[[#ADDRB9]]) +; BOLT-NEXT: [0x[[#ADDR10]], 0x[[#ADDRB10]]) +; BOLT-NEXT: [0x[[#ADDR11]], 0x[[#ADDRB11]]) +; BOLT-NEXT: [0x[[#ADDR12]], 0x[[#ADDRB12]]) +; BOLT-NEXT: [0x[[#ADDR13]], 0x[[#ADDRB13]]) +; BOLT-NEXT: [0x[[#ADDR14]], 0x[[#ADDRB14]]) +; BOLT-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000018) + +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000040 + +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN: DW_TAG_subprogram +; BOLT-DWO-MAIN-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000040 diff --git a/bolt/test/X86/dwarf4-df-input-lowpc-ranges.test b/bolt/test/X86/dwarf4-df-input-lowpc-ranges.test index fa116206950b..276bea4ba0c1 100644 --- a/bolt/test/X86/dwarf4-df-input-lowpc-ranges.test +++ b/bolt/test/X86/dwarf4-df-input-lowpc-ranges.test @@ -1,7 +1,7 @@ ; RUN: rm -rf %t ; RUN: mkdir %t ; RUN: cd %t -;; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-main.s \ +; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-input-lowpc-ranges-main.s \ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o -o main.exe ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections @@ -11,7 +11,7 @@ ; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/mainddwodwo.txt ; RUN: cat %t/mainddwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests BOLT handles correctly Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input. +;; Tests that BOLT correctly handles Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input. ; BOLT: .debug_ranges ; BOLT-NEXT: 00000000 diff --git a/bolt/test/X86/dwarf4-df-no-base.test b/bolt/test/X86/dwarf4-df-no-base.test index e5274cb829bc..338aa5444cb5 100644 --- a/bolt/test/X86/dwarf4-df-no-base.test +++ b/bolt/test/X86/dwarf4-df-no-base.test @@ -8,8 +8,8 @@ ; RUN: llvm-dwarfdump --debug-info main.exe | FileCheck -check-prefix=PRE-BOLT-MAIN %s ; RUN: llvm-dwarfdump --debug-info main.exe.bolt | FileCheck -check-prefix=BOLT-MAIN %s -; Tests whether we add DW_AT_GNU_ranges_base, if it's not present when Skeleton CU has -; DW_AT_ranges. +;; Tests whether we add DW_AT_GNU_ranges_base, if it's not present when Skeleton CU has +;; DW_AT_ranges. ; PRE-BOLT-MAIN-NOT: DW_AT_GNU_ranges_base ; BOLT-MAIN: DW_AT_GNU_ranges_base diff --git a/bolt/test/X86/dwarf4-do-no-convert-low-pc-high-pc-to-ranges.test b/bolt/test/X86/dwarf4-do-no-convert-low-pc-high-pc-to-ranges.test index 2e861c7ea504..2ff0b5dd3658 100644 --- a/bolt/test/X86/dwarf4-do-no-convert-low-pc-high-pc-to-ranges.test +++ b/bolt/test/X86/dwarf4-do-no-convert-low-pc-high-pc-to-ranges.test @@ -6,8 +6,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, -# when there is only one output range entry. +## This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, +## when there is only one output range entry. # PRECHECK: DW_TAG_inlined_subroutine # PRECHECK: DW_AT_abstract_origin diff --git a/bolt/test/X86/dwarf4-duplicate-types.test b/bolt/test/X86/dwarf4-duplicate-types.test index 8deed6ab0939..065ec7c7ac2c 100644 --- a/bolt/test/X86/dwarf4-duplicate-types.test +++ b/bolt/test/X86/dwarf4-duplicate-types.test @@ -6,10 +6,10 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# LLD does not de-duplicate COMDAT sections for LTO. -# Clang can generate type units with the same hash. -# https://discourse.llvm.org/t/dwarf-different-tu-with-the-same-hash/70095 -# Modified helper.s to have the same TU hash with a different COMDAT signature to test this. +## LLD does not de-duplicate COMDAT sections for LTO. +## Clang can generate type units with the same hash. +## https://discourse.llvm.org/t/dwarf-different-tu-with-the-same-hash/70095 +## Modified helper.s to have the same TU hash with a different COMDAT signature to test this. # POSTCHECK: Type Unit: length = 0x00000055, format = DWARF32, version = 0x0004, # POSTCHECK-SAME: abbr_offset = 0x0000, addr_size = 0x08, name = 'Foo', type_signature = 0x675d23e4f33235f2, type_offset = 0x001e (next unit at 0x00000059) diff --git a/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test index 8fd2f1950437..d08b596ec8dd 100644 --- a/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test +++ b/bolt/test/X86/dwarf4-ftypes-dwo-input-dwp-output.test @@ -10,8 +10,8 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s -; Test input into bolt a .dwo file with TU Index. -; Make sure the output .dwp file has a type information. +;; Test input into bolt a .dwo file with TU Index. +;; Make sure the output .dwp file has a type information. ; PRE-BOLT: DW_TAG_type_unit ; PRE-BOLT: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test index 40eae605b6a8..54382142afc8 100644 --- a/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test +++ b/bolt/test/X86/dwarf4-ftypes-dwo-mono-input-dwp-output.test @@ -12,9 +12,9 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s -; Test input into bolt a .dwo file with TU Index. -; Test split-dwarf and monolithic TUs. -; Make sure the output .dwp file has a type information. +;; Test input into bolt a .dwo file with TU Index. +;; Test split-dwarf and monolithic TUs. +;; Make sure the output .dwp file has a type information. ; PRE-BOLT: 0x675d23e4f33235f2 ; PRE-BOLT: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwo-output.test b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwo-output.test index c6b8671deb98..8077cc080823 100644 --- a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwo-output.test +++ b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwo-output.test @@ -11,8 +11,8 @@ ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections ; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.dwo.dwo | FileCheck -check-prefix=BOLT %s -; Test input into bolt a DWP file with TU Index. -; Make sure output in the .dwo files has type information. +;; Test input into bolt a DWP file with TU Index. +;; Make sure output in the .dwo files has type information. ; PRE-BOLT: DW_TAG_type_unit ; PRE-BOLT: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test index b326a6386ba9..673e86bb1533 100644 --- a/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test +++ b/bolt/test/X86/dwarf4-ftypes-dwp-input-dwp-output.test @@ -12,8 +12,8 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-types main.exe.bolt.dwp | FileCheck -check-prefix=BOLT %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s -; Test input into bolt a DWP file with TU Index. -; Make sure the output .dwp file has a type information. +;; Test input into bolt a DWP file with TU Index. +;; Make sure the output .dwp file has a type information. ; PRE-BOLT: DW_TAG_type_unit ; PRE-BOLT: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf4-gdb-index-types-gdb-generated.test b/bolt/test/X86/dwarf4-gdb-index-types-gdb-generated.test index 51293ce56008..eaf758091701 100644 --- a/bolt/test/X86/dwarf4-gdb-index-types-gdb-generated.test +++ b/bolt/test/X86/dwarf4-gdb-index-types-gdb-generated.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %tgdb.exe -o %tgdb.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %tgdb.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB. +## Tests that BOLT correctly handles gdb-index generated by GDB. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf4-gdb-index-types-lld-generated.test b/bolt/test/X86/dwarf4-gdb-index-types-lld-generated.test index 8943ce851a7e..640598978be7 100644 --- a/bolt/test/X86/dwarf4-gdb-index-types-lld-generated.test +++ b/bolt/test/X86/dwarf4-gdb-index-types-lld-generated.test @@ -6,7 +6,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by LLD. +## Tests that BOLT correctly handles gdb-index generated by LLD. # POSTCHECK: Version = 7 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s index 4cf0d3d0e255..494fe43cf105 100755 --- a/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s +++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s @@ -6,7 +6,7 @@ # RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s -# Tests BOLT does not assert when DIE reference is invalid. +## Tests BOLT does not assert when DIE reference is invalid. # CHECKBOLT: Referenced DIE offsets not in .debug_info # CHECKBOLT-NEXT: 91 diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s index 9d27c9cd9ff8..1bbb12ef3139 100755 --- a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s +++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s @@ -6,7 +6,7 @@ # RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s -# Tests BOLT does not assert when DIE reference is invalid. +## Tests BOLT does not assert when DIE reference is invalid. # CHECKBOLT: BOLT-WARNING: [internal-dwarf-error]: could not parse referenced DIE at offset: # CHECKBOLT-NOT: Referenced DIE offsets not in .debug_info diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s index b9cbf513bb26..3cec66132e9e 100755 --- a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s +++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s @@ -6,7 +6,7 @@ # RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s -# Tests BOLT does not assert when DIE reference is invalid. +## Tests BOLT does not assert when DIE reference is invalid. # CHECKBOLT: BOLT-WARNING: [internal-dwarf-error]: invalid referenced DIE at offset: # CHECKBOLT-NOT: Referenced DIE offsets not in .debug_info diff --git a/bolt/test/X86/dwarf4-sibling.s b/bolt/test/X86/dwarf4-sibling.s index 0ba97acb4f9e..94e112101f9b 100644 --- a/bolt/test/X86/dwarf4-sibling.s +++ b/bolt/test/X86/dwarf4-sibling.s @@ -5,9 +5,9 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles DW_AT_sibling. +## This test checks that BOLT handles DW_AT_sibling. -# The assembly was manually modified to do cross CU reference. +## The assembly was manually modified to do cross CU reference. # POSTCHECK: version = 0x0004 # POSTCHECK: DW_TAG_structure_type [5] diff --git a/bolt/test/X86/dwarf4-size-0-inlined_subroutine.s b/bolt/test/X86/dwarf4-size-0-inlined_subroutine.s index 584e67b1c79f..e7fc0dae3e44 100644 --- a/bolt/test/X86/dwarf4-size-0-inlined_subroutine.s +++ b/bolt/test/X86/dwarf4-size-0-inlined_subroutine.s @@ -16,8 +16,8 @@ # CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000000) -# Testing BOLT handles correctly when size of DW_AT_inlined_subroutine is 0. -# In other words DW_AT_high_pc is 0 or DW_AT_low_pc == DW_AT_high_pc. +## Testing BOLT handles correctly when size of DW_AT_inlined_subroutine is 0. +## In other words DW_AT_high_pc is 0 or DW_AT_low_pc == DW_AT_high_pc. # Modified assembly manually to set DW_AT_high_pc to 0. # clang++ -g2 -gdwarf-4 main.cpp -O1 -S -o main4.s diff --git a/bolt/test/X86/dwarf4-split-dwarf-no-address.test b/bolt/test/X86/dwarf4-split-dwarf-no-address.test index 753fad06eb06..fc6d8d324b95 100644 --- a/bolt/test/X86/dwarf4-split-dwarf-no-address.test +++ b/bolt/test/X86/dwarf4-split-dwarf-no-address.test @@ -9,7 +9,7 @@ ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt | FileCheck -check-prefix=BOLT %s -; Testing that there are no asserts/crashes when one of the DWARF4 CUs does not modify .debug_addr +;; Testing that there are no asserts/crashes when one of the DWARF4 CUs does not modify .debug_addr ; BOLT: DW_TAG_compile_unit ; BOLT: DW_TAG_compile_unit diff --git a/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test b/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test index e3734492d8f4..c9b12574caa3 100644 --- a/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test +++ b/bolt/test/X86/dwarf4-split-gdb-index-types-gdb-generated.test @@ -10,7 +10,7 @@ # RUN: llvm-bolt maingdb.exe -o maingdb.exe.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index maingdb.exe.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB with split-dwarf DWARF4. +## Tests that BOLT correctly handles gdb-index generated by GDB with split-dwarf DWARF4. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf4-subprogram-multiple-ranges-cus.test b/bolt/test/X86/dwarf4-subprogram-multiple-ranges-cus.test new file mode 100644 index 000000000000..c9ade995b708 --- /dev/null +++ b/bolt/test/X86/dwarf4-subprogram-multiple-ranges-cus.test @@ -0,0 +1,38 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-subprogram-multiple-ranges-main.s -o %t1.o +# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-subprogram-multiple-ranges-other.s -o %t2.o +# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-objdump %t.bolt --disassemble > %t1.txt +# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt +# RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s + +## This test checks that BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries and handles multiple CUs with ranges. + +# POSTCHECK: _Z7doStuffi>: +# POSTCHECK: [[#%.6x,ADDR:]] +# POSTCHECK: _Z7doStuffi.__part.1>: +# POSTCHECK-NEXT: [[#%.6x,ADDR1:]] +# POSTCHECK: _Z7doStuffi.__part.2>: +# POSTCHECK-NEXT: [[#%.6x,ADDR2:]] + +# POSTCHECK: _Z12doStuffOtheri>: +# POSTCHECK: [[#%.6x,ADDR3:]] +# POSTCHECK: _Z12doStuffOtheri.__part.1>: +# POSTCHECK-NEXT: [[#%.6x,ADDR4:]] +# POSTCHECK: _Z12doStuffOtheri.__part.2>: +# POSTCHECK-NEXT: [[#%.6x,ADDR5:]] + +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_AT_ranges +# POSTCHECK-NEXT: [0x0000000000[[#ADDR1]], 0x0000000000[[#ADDR1 + 0xb]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR2]], 0x0000000000[[#ADDR2 + 0x5]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR]], 0x0000000000[[#ADDR + 0xf]])) + +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_AT_ranges +# POSTCHECK-NEXT: [0x0000000000[[#ADDR4]], 0x0000000000[[#ADDR4 + 0xb]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR5]], 0x0000000000[[#ADDR5 + 0x5]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR3]], 0x0000000000[[#ADDR3 + 0xf]])) diff --git a/bolt/test/X86/dwarf4-subprogram-multiple-ranges.test b/bolt/test/X86/dwarf4-subprogram-multiple-ranges.test index 63db886c9137..5efe07a28057 100644 --- a/bolt/test/X86/dwarf4-subprogram-multiple-ranges.test +++ b/bolt/test/X86/dwarf4-subprogram-multiple-ranges.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries. # POSTCHECK: _Z7doStuffi>: # POSTCHECK: [[#%.6x,ADDR:]] diff --git a/bolt/test/X86/dwarf4-subprogram-single-gc-ranges.test b/bolt/test/X86/dwarf4-subprogram-single-gc-ranges.test index 3e7e765f98b1..9c121e5acc4a 100644 --- a/bolt/test/X86/dwarf4-subprogram-single-gc-ranges.test +++ b/bolt/test/X86/dwarf4-subprogram-single-gc-ranges.test @@ -6,7 +6,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt > %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry, when function was GCed. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry, when function was GCed. # POSTCHECK: DW_TAG_subprogram # POSTCHECK-NEXT: DW_AT_frame_base diff --git a/bolt/test/X86/dwarf4-subprogram-single-ranges.test b/bolt/test/X86/dwarf4-subprogram-single-ranges.test index 0dcbbcdfcce3..c02d2e4e6d44 100644 --- a/bolt/test/X86/dwarf4-subprogram-single-ranges.test +++ b/bolt/test/X86/dwarf4-subprogram-single-ranges.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry. # POSTCHECK: _Z7doStuffi>: # POSTCHECK: [[#%.6x,ADDR:]] diff --git a/bolt/test/X86/dwarf4-types-dwarf5-types.test b/bolt/test/X86/dwarf4-types-dwarf5-types.test index a5d2ec8df20a..a253f2283609 100644 --- a/bolt/test/X86/dwarf4-types-dwarf5-types.test +++ b/bolt/test/X86/dwarf4-types-dwarf5-types.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECKTU %s -# Check BOLT handles DWARF4/5 with fdebug-types. +## Check BOLT handles DWARF4/5 with fdebug-types. # POSTCHECK: version = 0x0005 # POSTCHECK: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf4-types-dwarf5.test b/bolt/test/X86/dwarf4-types-dwarf5.test index 9ece6db3f00a..1eb42683e40e 100644 --- a/bolt/test/X86/dwarf4-types-dwarf5.test +++ b/bolt/test/X86/dwarf4-types-dwarf5.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECKTU %s -# Check BOLT handles DWARF4 with fdebug-types, and DWARF5 without. +## Check BOLT handles DWARF4 with fdebug-types, and DWARF5 without. # POSTCHECK: version = 0x0004 # POSTCHECK: DW_TAG_compile_unit diff --git a/bolt/test/X86/dwarf4-types-forward-backward-cross-reference.s b/bolt/test/X86/dwarf4-types-forward-backward-cross-reference.s index c407ecadd111..3cfe8a3b74f6 100644 --- a/bolt/test/X86/dwarf4-types-forward-backward-cross-reference.s +++ b/bolt/test/X86/dwarf4-types-forward-backward-cross-reference.s @@ -5,8 +5,8 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles correctly backward and forward cross CU references -# for DWARF4 with -fdebug-types-section +## This test checks that BOLT handles correctly backward and forward cross CU references +## for DWARF4 with -fdebug-types-section # POSTCHECK: version = 0x0004 # POSTCHECK: DW_TAG_variable [10] diff --git a/bolt/test/X86/dwarf4-types.test b/bolt/test/X86/dwarf4-types.test index d717b4b3b47d..7ea804e95aa3 100644 --- a/bolt/test/X86/dwarf4-types.test +++ b/bolt/test/X86/dwarf4-types.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECKTU %s -# Check BOLT handles DWARF4/5 with fdebug-types. +## Check BOLT handles DWARF4/5 with fdebug-types. # POSTCHECK: version = 0x0004 # POSTCHECK: DW_TAG_compile_unit [6] diff --git a/bolt/test/X86/dwarf5-addr-section-reuse.s b/bolt/test/X86/dwarf5-addr-section-reuse.s index bc747e0657b5..6b00ce0fdf80 100644 --- a/bolt/test/X86/dwarf5-addr-section-reuse.s +++ b/bolt/test/X86/dwarf5-addr-section-reuse.s @@ -6,8 +6,8 @@ # RUN: llvm-bolt %t.exe -o %t.exe.bolt --update-debug-sections # RUN: llvm-dwarfdump --debug-info %t.exe.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that when a binary is bolted if CU is not modified and has DW_AT_addr_base that is shared -# after being bolted CUs still share same entry in .debug_addr. +## This test checks that when a binary is bolted if CU is not modified and has DW_AT_addr_base that is shared +## after being bolted CUs still share same entry in .debug_addr. # PRECHECK: DW_AT_addr_base (0x00000008) # PRECHECK: DW_AT_addr_base (0x00000008) diff --git a/bolt/test/X86/dwarf5-call-pc-function-null-check.test b/bolt/test/X86/dwarf5-call-pc-function-null-check.test index b04e30bcf532..761a4da69621 100644 --- a/bolt/test/X86/dwarf5-call-pc-function-null-check.test +++ b/bolt/test/X86/dwarf5-call-pc-function-null-check.test @@ -8,8 +8,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=CHECK %s -# Test checks we correctly handle nullptr returned by getBinaryFunctionContainingAddress for DW_AT_call_pc. -# This happens when address is not contained in any function. +## Test checks we correctly handle nullptr returned by getBinaryFunctionContainingAddress for DW_AT_call_pc. +## This happens when address is not contained in any function. # CHECK: DW_AT_call_pc [DW_FORM_addrx] # CHECK-SAME: address = 0x[[#%.16x,ADDR:]] diff --git a/bolt/test/X86/dwarf5-call-pc.test b/bolt/test/X86/dwarf5-call-pc.test index ec03a7bf8ad4..dc7773dc053d 100644 --- a/bolt/test/X86/dwarf5-call-pc.test +++ b/bolt/test/X86/dwarf5-call-pc.test @@ -11,7 +11,7 @@ # RUN: cat %tmain.txt | FileCheck --check-prefix=PRECHECK %s # RUN: cat %tmainbolt.txt | FileCheck --check-prefix=POSTCHECK %s -# Test checks that DW_AT_call_pc address points to a correct address for jmp instruction. +## Test checks that DW_AT_call_pc address points to a correct address for jmp instruction. # PRECHECK: DW_TAG_call_site [6] # PRECHECK-NEXT: DW_AT_call_origin [DW_FORM_ref4] diff --git a/bolt/test/X86/dwarf5-cu-no-debug-addr.test b/bolt/test/X86/dwarf5-cu-no-debug-addr.test index d19480805936..e78b68680d6c 100644 --- a/bolt/test/X86/dwarf5-cu-no-debug-addr.test +++ b/bolt/test/X86/dwarf5-cu-no-debug-addr.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that we handle correctly, don't crash, DWARF5 CUs that does not access .debug_addr. +## This tests checks that we handle correctly, don't crash, DWARF5 CUs that does not access .debug_addr. # PRECHECK: DW_TAG_compile_unit # PRECHECK: DW_AT_addr_base diff --git a/bolt/test/X86/dwarf5-debug-info-dwarf4-debug-line.s b/bolt/test/X86/dwarf5-debug-info-dwarf4-debug-line.s index 6042bbee8948..dbf6aef20a9c 100644 --- a/bolt/test/X86/dwarf5-debug-info-dwarf4-debug-line.s +++ b/bolt/test/X86/dwarf5-debug-info-dwarf4-debug-line.s @@ -6,7 +6,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that .debug_line gets generated correctly when .debug_info is DWARF5, and .debug_line is DWARF4. +## This test checks that .debug_line gets generated correctly when .debug_info is DWARF5, and .debug_line is DWARF4. # PRECHECK: version: 4 # PRECHECK: file_names[ 1]: diff --git a/bolt/test/X86/dwarf5-debug-line-not-modified.test b/bolt/test/X86/dwarf5-debug-line-not-modified.test index 20dd9083169a..15f7ead42dc1 100644 --- a/bolt/test/X86/dwarf5-debug-line-not-modified.test +++ b/bolt/test/X86/dwarf5-debug-line-not-modified.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT generates correct debug_line_str when one of CU contributions is not modified. +## This test checks that BOLT generates correct debug_line_str when one of CU contributions is not modified. # POSTCHECK: version: 5 # POSTCHECK: include_directories[ 0] = .debug_line_str[{{.*}}] = "/test" diff --git a/bolt/test/X86/dwarf5-debug-line.s b/bolt/test/X86/dwarf5-debug-line.s index 5b1cdba712a9..732e0d61d672 100644 --- a/bolt/test/X86/dwarf5-debug-line.s +++ b/bolt/test/X86/dwarf5-debug-line.s @@ -6,7 +6,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-line %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that DWARF5 .debug_line is handled correctly. +## This test checks that DWARF5 .debug_line is handled correctly. # PRECHECK: version: 5 # PRECHECK: include_directories[ 0] = .debug_line_str diff --git a/bolt/test/X86/dwarf5-debug-loclists.s b/bolt/test/X86/dwarf5-debug-loclists.s index 753858d0b32e..6ce0467a840b 100644 --- a/bolt/test/X86/dwarf5-debug-loclists.s +++ b/bolt/test/X86/dwarf5-debug-loclists.s @@ -8,7 +8,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that re-writing of .debug_loclists is handled correctly. +## This tests checks that re-writing of .debug_loclists is handled correctly. # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) diff --git a/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test b/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test index ea717a5e0888..27614fe08634 100644 --- a/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test +++ b/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt ; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests that DW_AT_low_pc changes in DW_TAG_call_site. +;; Tests that DW_AT_low_pc changes in DW_TAG_call_site. ; PRE-BOLT-DWO-MAIN: version = 0x0005 ; PRE-BOLT-DWO-MAIN: DW_TAG_call_site diff --git a/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test b/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test index f266caec7af3..e31d1e0a6351 100644 --- a/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test +++ b/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test @@ -10,7 +10,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt ; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests that new indices are assigned to DW_OP_GNU_addr_index. +;; Tests that new indices are assigned to DW_OP_GNU_addr_index. ; PRE-BOLT-DWO-MAIN: version = 0x0005 ; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0) diff --git a/bolt/test/X86/dwarf5-df-cu-function-gc.test b/bolt/test/X86/dwarf5-df-cu-function-gc.test index 62f75c2c7553..01a9ed9d85e5 100644 --- a/bolt/test/X86/dwarf5-df-cu-function-gc.test +++ b/bolt/test/X86/dwarf5-df-cu-function-gc.test @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> addr.txt ; RUN: cat addr.txt | FileCheck -check-prefix=BOLT %s -; Tests we generate range when linker GCs only function used in CU +;; Tests we generate range when linker GCs only function used in CU ; BOLT: Addrs: ; BOLT-NEXT: 0x[[#%.16x,ADDR:]] diff --git a/bolt/test/X86/dwarf5-df-dualcu-loclist.test b/bolt/test/X86/dwarf5-df-dualcu-loclist.test index ea5b28a2e88f..4461f5b35ff0 100644 --- a/bolt/test/X86/dwarf5-df-dualcu-loclist.test +++ b/bolt/test/X86/dwarf5-df-dualcu-loclist.test @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo | FileCheck -check-prefix=PRE-BOLT-DWO-HELPER %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-HELPER %s -; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_location [DW_FORM_loclistx] is updated correctly. +;; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_location [DW_FORM_loclistx] is updated correctly. ; PRE-BOLT-DWO-MAIN: version = 0x0005 ; PRE-BOLT-DWO-MAIN: DW_TAG_formal_parameter [10] diff --git a/bolt/test/X86/dwarf5-df-dualcu.test b/bolt/test/X86/dwarf5-df-dualcu.test index deaeea036690..c6ad5afa305c 100644 --- a/bolt/test/X86/dwarf5-df-dualcu.test +++ b/bolt/test/X86/dwarf5-df-dualcu.test @@ -16,8 +16,8 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo | FileCheck -check-prefix=PRE-BOLT-DWO-HELPER %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info helper.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-HELPER %s -; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. -; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx ##) are updated correctly. +;; Testing dwarf5 split dwarf for two CUs. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. +;; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx ##) are updated correctly. ; PRE-BOLT: version = 0x0005 ; PRE-BOLT: DW_TAG_skeleton_unit diff --git a/bolt/test/X86/dwarf5-df-inlined-subroutine-gc-sections-range.test b/bolt/test/X86/dwarf5-df-inlined-subroutine-gc-sections-range.test index 6e9bd0502d8b..3132208475bd 100644 --- a/bolt/test/X86/dwarf5-df-inlined-subroutine-gc-sections-range.test +++ b/bolt/test/X86/dwarf5-df-inlined-subroutine-gc-sections-range.test @@ -19,8 +19,8 @@ ; RUN: cat log.txt | FileCheck -check-prefix=BOLT-PRE %s ; RUN: cat logBolt.txt | FileCheck -check-prefix=BOLT-MAIN %s -; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_ranges is 0, -; and split dwarf is enabled. +;; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_ranges is 0, +;; and split dwarf is enabled. ; BOLT-PRE: Addrs: ; BOLT-PRE: 0x0000000000000000 diff --git a/bolt/test/X86/dwarf5-df-inlined-subroutine-range-0.test b/bolt/test/X86/dwarf5-df-inlined-subroutine-range-0.test index 4ecc66f52ff8..b9f38d42aa92 100644 --- a/bolt/test/X86/dwarf5-df-inlined-subroutine-range-0.test +++ b/bolt/test/X86/dwarf5-df-inlined-subroutine-range-0.test @@ -9,8 +9,8 @@ ; RUN: llvm-dwarfdump --debug-info --verbose --show-form main.dwo.dwo >> log.txt ; RUN: cat log.txt | FileCheck -check-prefix=BOLT-MAIN %s -; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_ranges is 0, -; and split dwarf is enabled. +;; Tests whether BOLT handles correctly DW_TAG_inlined_subroutine when DW_AT_ranges is 0, +;; and split dwarf is enabled. ; BOLT-MAIN: 0x ; BOLT-MAIN: 0x diff --git a/bolt/test/X86/dwarf5-df-input-lowpc-ranges.test b/bolt/test/X86/dwarf5-df-input-lowpc-ranges.test index 1867f49a5204..2123353044c3 100644 --- a/bolt/test/X86/dwarf5-df-input-lowpc-ranges.test +++ b/bolt/test/X86/dwarf5-df-input-lowpc-ranges.test @@ -1,7 +1,7 @@ ; RUN: rm -rf %t ; RUN: mkdir %t ; RUN: cd %t -;; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-main.s \ +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-main.s \ ; RUN: -split-dwarf-file=main.dwo -o main.o ; RUN: %clang %cflags -gdwarf-4 -gsplit-dwarf=split main.o -o main.exe ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections @@ -12,7 +12,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/mainddwodwo.txt ; RUN: cat %t/mainddwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Tests BOLT handles correctly Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input. +;; Tests that BOLT correctly handles Skeleton CU which has DW_AT_low_pc/DW_AT_ranges as input. ; BOLT: Addrs: [ ; BOLT-NEXT: 0x[[#%.16x,ADDR1:]] diff --git a/bolt/test/X86/dwarf5-df-mono-dualcu.test b/bolt/test/X86/dwarf5-df-mono-dualcu.test index 12269287ef13..13272cc1c3c4 100644 --- a/bolt/test/X86/dwarf5-df-mono-dualcu.test +++ b/bolt/test/X86/dwarf5-df-mono-dualcu.test @@ -13,7 +13,7 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo | FileCheck -check-prefix=PRE-BOLT-DWO-MAIN %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-MAIN %s -; Testing dwarf5 mix of split dwarf and monolithic CUs. +;; Testing dwarf5 mix of split dwarf and monolithic CUs. ; PRE-BOLT: version = 0x0005 ; PRE-BOLT: DW_TAG_skeleton_unit diff --git a/bolt/test/X86/dwarf5-df-output-dir-same-name.test b/bolt/test/X86/dwarf5-df-output-dir-same-name.test index 1f78da2022b8..b466f87d95e5 100644 --- a/bolt/test/X86/dwarf5-df-output-dir-same-name.test +++ b/bolt/test/X86/dwarf5-df-output-dir-same-name.test @@ -14,15 +14,15 @@ ; RUN: llvm-dwarfdump --debug-info main.exe.bolt >> log ; RUN: cat log | FileCheck -check-prefix=BOLT %s -; Tests that BOLT handles correctly writing out .dwo files to the same directory when input has input where part of path -; is in DW_AT_dwo_name and the .dwo file names are the same. +;; Tests that BOLT handles correctly writing out .dwo files to the same directory when input has input where part of path +;; is in DW_AT_dwo_name and the .dwo file names are the same. ; BOLT: split.dwo0.dwo ; BOLT: split.dwo1.dwo ; BOLT: DW_AT_dwo_name ("split.dwo0.dwo") ; BOLT: DW_AT_dwo_name ("split.dwo1.dwo") -; Tests that when --dwarf-output-path is specified, but path do not exist BOLT creates it. +;; Tests that when --dwarf-output-path is specified, but path do not exist BOLT creates it. ; RUN: rm -rf dwo ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --dwarf-output-path=%t/dwo @@ -30,8 +30,8 @@ ; RUN: llvm-dwarfdump --debug-info main.exe.bolt >> log ; RUN: cat log | FileCheck -check-prefix=BOLT1 %s -; Tests that BOLT handles correctly writing out .dwo files to the same directory when input has input where part of path -; is in DW_AT_dwo_name and the .dwo file names are the same. +;; Tests that BOLT handles correctly writing out .dwo files to the same directory when input has input where part of path +;; is in DW_AT_dwo_name and the .dwo file names are the same. ; BOLT1: split.dwo0.dwo ; BOLT1: split.dwo1.dwo diff --git a/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test b/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test index 036d4c9168ee..754f05dc9632 100644 --- a/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test +++ b/bolt/test/X86/dwarf5-df-types-dup-dwp-input.test @@ -11,7 +11,7 @@ ; RUN: llvm-dwarfdump --debug-info -r 0 main.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-DWO-MAIN %s ; RUN: llvm-dwarfdump --debug-info -r 0 helper.dwo.dwo | FileCheck -check-prefix=BOLT-DWO-DWO-HELPER %s -; Tests that BOLT correctly handles DWARF5 DWP file as input. Output has correct CU, and all the type units are written out. +;; Tests that BOLT correctly handles DWARF5 DWP file as input. Output has correct CU, and all the type units are written out. ; BOLT-DWO-DWO-MAIN: debug_info.dwo ; BOLT-DWO-DWO-MAIN-NEXT: type_signature = 0x49dc260088be7e56 diff --git a/bolt/test/X86/dwarf5-do-no-convert-low-pc-high-pc-to-ranges.test b/bolt/test/X86/dwarf5-do-no-convert-low-pc-high-pc-to-ranges.test index 1a59844814cd..1c7843e1f210 100644 --- a/bolt/test/X86/dwarf5-do-no-convert-low-pc-high-pc-to-ranges.test +++ b/bolt/test/X86/dwarf5-do-no-convert-low-pc-high-pc-to-ranges.test @@ -6,8 +6,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, -# when there is only one output range entry. +## This test checks that we do not convert low_pc/high_pc to ranges for DW_TAG_inlined_subroutine, +## when there is only one output range entry. # PRECHECK: DW_TAG_inlined_subroutine # PRECHECK: DW_AT_abstract_origin diff --git a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb11.test b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb11.test index 17663a7f72df..10ad6ed404f1 100644 --- a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb11.test +++ b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb11.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %tgdb.exe -o %tgdb.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %tgdb.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB. +## Tests that BOLT correctly handles gdb-index generated by GDB. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb9.test b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb9.test index c283ec02387f..2da0bcca89b2 100644 --- a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb9.test +++ b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-gdb-generated-gdb9.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %tgdb.exe -o %tgdb.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %tgdb.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB. +## Tests that BOLT correctly handles gdb-index generated by GDB. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 3 entries diff --git a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-lld-generated.test b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-lld-generated.test index 6eaad4cd06d3..9be540352005 100644 --- a/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-lld-generated.test +++ b/bolt/test/X86/dwarf5-dwarf4-gdb-index-types-lld-generated.test @@ -6,7 +6,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by LLD. +## Tests that BOLT correctly handles gdb-index generated by LLD. # POSTCHECK: Version = 7 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf5-dwarf4-monolithic.test b/bolt/test/X86/dwarf5-dwarf4-monolithic.test index 274451c4546a..ff0f6990aaac 100644 --- a/bolt/test/X86/dwarf5-dwarf4-monolithic.test +++ b/bolt/test/X86/dwarf5-dwarf4-monolithic.test @@ -15,7 +15,7 @@ # RUN: FileCheck --check-prefix=CHECK-LINE %s --input-file %t_line.txt -# Check BOLT handles monolithic mix of DWARF4 and DWARF5. +## Check BOLT handles monolithic mix of DWARF4 and DWARF5. # main.cpp # PRECHECK: version = 0x0005 diff --git a/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test b/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test index 8afbe9e747d2..070648c042c1 100644 --- a/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test +++ b/bolt/test/X86/dwarf5-dwarf4-types-backward-forward-cross-reference.test @@ -7,8 +7,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-types %t.bolt | FileCheck --check-prefix=POSTCHECKTU %s -# This test checks that BOLT handles correctly backward and forward cross CU references -# for DWARF5 and DWARF4 with -fdebug-types-section +## This test checks that BOLT handles correctly backward and forward cross CU references +## for DWARF5 and DWARF4 with -fdebug-types-section # POSTCHECK: version = 0x0005 # POSTCHECK: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test b/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test index 69758505c2a6..b6e9f60bbfc7 100644 --- a/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test +++ b/bolt/test/X86/dwarf5-ftypes-dwo-mono-input-dwp-output.test @@ -13,9 +13,9 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-tu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-TU-INDEX %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-cu-index main.exe.bolt.dwp | FileCheck -check-prefix=BOLT-DWP-CU-INDEX %s -; Test input into bolt a .dwo file with TU Index. -; Test split-dwarf and monolithic TUs. -; Make sure the output .dwp file has a type and cu information. +;; Test input into bolt a .dwo file with TU Index. +;; Test split-dwarf and monolithic TUs. +;; Make sure the output .dwp file has a type and cu information. ; PRE-BOLT: Type Unit ; PRE-BOLT-SAME: 0x675d23e4f33235f2 diff --git a/bolt/test/X86/dwarf5-ftypes-dwp-input-dwo-output.test b/bolt/test/X86/dwarf5-ftypes-dwp-input-dwo-output.test index b59a3f056b22..5381039ffa37 100644 --- a/bolt/test/X86/dwarf5-ftypes-dwp-input-dwo-output.test +++ b/bolt/test/X86/dwarf5-ftypes-dwp-input-dwo-output.test @@ -13,8 +13,8 @@ ; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections ; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo | FileCheck -check-prefix=BOLT %s -; Test input into bolt a DWP file with TU Index. -; Make sure output in the .dwo files has type information. +;; Test input into bolt a DWP file with TU Index. +;; Make sure output in the .dwo files has type information. ; PRE-BOLT: DW_TAG_type_unit ; PRE-BOLT: DW_TAG_type_unit diff --git a/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb11.test b/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb11.test index f8f33b321a7d..338a476e46f3 100644 --- a/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb11.test +++ b/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb11.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %tgdb.exe -o %tgdb.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %tgdb.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB. +## Tests that BOLT correctly handles gdb-index generated by GDB. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb9.test b/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb9.test index bccc92d3de84..c9d3913a1933 100644 --- a/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb9.test +++ b/bolt/test/X86/dwarf5-gdb-index-types-gdb-generated-gdb9.test @@ -7,7 +7,7 @@ # RUN: llvm-bolt %tgdb.exe -o %tgdb.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %tgdb.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB. +## Tests that BOLT correctly handles gdb-index generated by GDB. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 4 entries diff --git a/bolt/test/X86/dwarf5-gdb-index-types-lld-generated.test b/bolt/test/X86/dwarf5-gdb-index-types-lld-generated.test index 18fe7daa4ad4..a770e40260dd 100644 --- a/bolt/test/X86/dwarf5-gdb-index-types-lld-generated.test +++ b/bolt/test/X86/dwarf5-gdb-index-types-lld-generated.test @@ -6,7 +6,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by LLD. +## Tests that BOLT correctly handles gdb-index generated by LLD. # POSTCHECK: Version = 7 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf5-locaddrx.test b/bolt/test/X86/dwarf5-locaddrx.test index 00e15101f853..6cb198515e0f 100644 --- a/bolt/test/X86/dwarf5-locaddrx.test +++ b/bolt/test/X86/dwarf5-locaddrx.test @@ -12,8 +12,8 @@ ; RUN: llvm-dwarfdump --show-form --verbose --debug-info mainlocadddrx.dwo | FileCheck -check-prefix=PRE-BOLT-DWO %s ; RUN: llvm-dwarfdump --show-form --verbose --debug-info mainlocadddrx.dwo.dwo | FileCheck -check-prefix=BOLT-DWO %s -; Testing dwarf5 split dwarf. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. -; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0) is updated correctly. +;; Testing dwarf5 split dwarf. Making sure DW_AT_low_pc/DW_AT_high_pc are converted correctly in the binary and in dwo. +;; Checking that DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0) is updated correctly. ; PRE-BOLT: version = 0x0005 ; PRE-BOLT: DW_TAG_skeleton_unit diff --git a/bolt/test/X86/dwarf5-locexpr-addrx.s b/bolt/test/X86/dwarf5-locexpr-addrx.s index 1e8183b7527d..6a8d81d2d08e 100644 --- a/bolt/test/X86/dwarf5-locexpr-addrx.s +++ b/bolt/test/X86/dwarf5-locexpr-addrx.s @@ -6,8 +6,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that we correctly encode new index into .debug_addr section -# from DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x#) +## This test checks that we correctly encode new index into .debug_addr section +## from DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x#) # PRECHECK: version = 0x0005 # PRECHECK: DW_TAG_variable diff --git a/bolt/test/X86/dwarf5-locexpr-referrence.test b/bolt/test/X86/dwarf5-locexpr-referrence.test index 27b7a2b38d97..ea73d7601b25 100644 --- a/bolt/test/X86/dwarf5-locexpr-referrence.test +++ b/bolt/test/X86/dwarf5-locexpr-referrence.test @@ -6,7 +6,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=CHECK %s -# This test checks that we update relative DIE references with DW_OP_convert that are in locexpr. +## This test checks that we update relative DIE references with DW_OP_convert that are in locexpr. # CHECK: version = 0x0005 # CHECK: DW_TAG_variable diff --git a/bolt/test/X86/dwarf5-loclist-offset-form.test b/bolt/test/X86/dwarf5-loclist-offset-form.test index d4b8ab15fd0f..3178c11a6706 100644 --- a/bolt/test/X86/dwarf5-loclist-offset-form.test +++ b/bolt/test/X86/dwarf5-loclist-offset-form.test @@ -9,7 +9,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# Checks we can handle DWARF5 CU with DWARF4 DW_AT_location access pattern. +## Checks we can handle DWARF5 CU with DWARF4 DW_AT_location access pattern. # PRECHECK: DW_TAG_compile_unit # PRECHECK: DW_TAG_variable [5] diff --git a/bolt/test/X86/dwarf5-lowpc-highpc-convert.s b/bolt/test/X86/dwarf5-lowpc-highpc-convert.s index aba62ea98454..6cdc345b435e 100644 --- a/bolt/test/X86/dwarf5-lowpc-highpc-convert.s +++ b/bolt/test/X86/dwarf5-lowpc-highpc-convert.s @@ -8,8 +8,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that DW_AT_low_pc/DW_AT_high_pc is converted to DW_AT_low_pc/DW_AT_ranges. -# Checks that DW_AT_rnglists_base is inserted, and that correct address is used. +## This tests checks that DW_AT_low_pc/DW_AT_high_pc is converted to DW_AT_low_pc/DW_AT_ranges. +## Checks that DW_AT_rnglists_base is inserted, and that correct address is used. # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_low_pc diff --git a/bolt/test/X86/dwarf5-multiple-dw-op-addrx-locexpr.s b/bolt/test/X86/dwarf5-multiple-dw-op-addrx-locexpr.s index 6429ccd86b32..b88e69e86eb7 100644 --- a/bolt/test/X86/dwarf5-multiple-dw-op-addrx-locexpr.s +++ b/bolt/test/X86/dwarf5-multiple-dw-op-addrx-locexpr.s @@ -21,7 +21,7 @@ # CHECK: DW_AT_decl_line [DW_FORM_data1] # CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x2, DW_OP_piece 0x4, DW_OP_addrx 0x3, DW_OP_piece 0x4) -# This test checks that we update DW_AT_location [DW_FORM_exprloc] with multiple DW_OP_addrx. +## This test checks that we update DW_AT_location [DW_FORM_exprloc] with multiple DW_OP_addrx. # struct pair {int i; int j; }; # static pair p; diff --git a/bolt/test/X86/dwarf5-one-loclists-two-bases.test b/bolt/test/X86/dwarf5-one-loclists-two-bases.test index 7ef53f681381..873512aad5e8 100644 --- a/bolt/test/X86/dwarf5-one-loclists-two-bases.test +++ b/bolt/test/X86/dwarf5-one-loclists-two-bases.test @@ -9,8 +9,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that re-writing of .debug_loclists is handled correctly when one of the CUs -# doesn't have any DW_AT_location accesses. +## This tests checks that re-writing of .debug_loclists is handled correctly when one of the CUs +## doesn't have any DW_AT_location accesses. # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) diff --git a/bolt/test/X86/dwarf5-rangeoffset-to-rangeindex.s b/bolt/test/X86/dwarf5-rangeoffset-to-rangeindex.s index 481ff41c301f..647d49895619 100644 --- a/bolt/test/X86/dwarf5-rangeoffset-to-rangeindex.s +++ b/bolt/test/X86/dwarf5-rangeoffset-to-rangeindex.s @@ -8,7 +8,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests conversion for DWARF5 ranges DW_AT_ranges [DW_FORM_sec_offset] to DW_AT_ranges [DW_FORM_rnglistx] +## This tests conversion for DWARF5 ranges DW_AT_ranges [DW_FORM_sec_offset] to DW_AT_ranges [DW_FORM_rnglistx] # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_ranges [DW_FORM_sec_offset] diff --git a/bolt/test/X86/dwarf5-return-pc-form-addr.test b/bolt/test/X86/dwarf5-return-pc-form-addr.test index 737aae91608b..5a83615cac03 100644 --- a/bolt/test/X86/dwarf5-return-pc-form-addr.test +++ b/bolt/test/X86/dwarf5-return-pc-form-addr.test @@ -11,7 +11,7 @@ # RUN: cat %tmain.txt | FileCheck --check-prefix=PRECHECK %s # RUN: cat %tmainbolt.txt | FileCheck --check-prefix=POSTCHECK %s -# Test checks that DW_AT_call_return_pc points to an address after the callq instruction. +## Test checks that DW_AT_call_return_pc points to an address after the callq instruction. # PRECHECK: DW_TAG_call_site [11] # PRECHECK-NEXT: DW_AT_call_origin [DW_FORM_ref4] diff --git a/bolt/test/X86/dwarf5-return-pc.test b/bolt/test/X86/dwarf5-return-pc.test index 987a9fa8cefa..e9ef99ef5b94 100644 --- a/bolt/test/X86/dwarf5-return-pc.test +++ b/bolt/test/X86/dwarf5-return-pc.test @@ -11,7 +11,7 @@ # RUN: cat %tmain.txt | FileCheck --check-prefix=PRECHECK %s # RUN: cat %tmainbolt.txt | FileCheck --check-prefix=POSTCHECK %s -# Test checks that DW_AT_call_return_pc points to an address after the callq instruction. +## Test checks that DW_AT_call_return_pc points to an address after the callq instruction. # PRECHECK: DW_TAG_call_site [11] # PRECHECK-NEXT: DW_AT_call_origin [DW_FORM_ref4] diff --git a/bolt/test/X86/dwarf5-shared-str-offset-base.s b/bolt/test/X86/dwarf5-shared-str-offset-base.s index 0756d537b25a..d8492298a160 100644 --- a/bolt/test/X86/dwarf5-shared-str-offset-base.s +++ b/bolt/test/X86/dwarf5-shared-str-offset-base.s @@ -9,8 +9,8 @@ # RUN: llvm-dwarfdump --show-section-sizes %tmain.exe.bolt >> %tout.text # RUN: cat %tout.text | FileCheck %s -# This test checks that with DWARF5 when two CUs share the same .debug_str_offsets -# entry BOLT does not create a duplicate. +## This test checks that with DWARF5 when two CUs share the same .debug_str_offsets +## entry BOLT does not create a duplicate. # CHECK: DW_AT_str_offsets_base (0x[[#%.8x,ADDR:]] # CHECK: DW_AT_str_offsets_base (0x[[#ADDR]] diff --git a/bolt/test/X86/dwarf5-split-dwarf4-monolithic.test b/bolt/test/X86/dwarf5-split-dwarf4-monolithic.test index 6fc0825cd2fa..2cfe5e26bd4c 100644 --- a/bolt/test/X86/dwarf5-split-dwarf4-monolithic.test +++ b/bolt/test/X86/dwarf5-split-dwarf4-monolithic.test @@ -20,7 +20,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-line main.bolt | FileCheck --check-prefix=POSTCHECK-LINE %s -# Check BOLT handles monolithic mix of DWARF4 and DWARF5. +## Check BOLT handles monolithic mix of DWARF4 and DWARF5. # main.cpp # PRECHECK: version = 0x0005 @@ -89,7 +89,7 @@ # PRECHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] # PRECHECK-NEXT: DW_AT_high_pc -# Checking debug line. +## Checking debug line. # PRECHECK-LINE: debug_line[ # PRECHECK-LINE: version: 5 @@ -262,7 +262,7 @@ # POSTCHECK-DWO-HELPER1-NEXT: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000018 # POSTCHECK-DWO-HELPER1-NEXT: [0x0000000000000000, 0x0000000000000003)) -# Checking debug line. +## Checking debug line. # POSTCHECK-LINE: debug_line[ # POSTCHECK-LINE: version: 5 diff --git a/bolt/test/X86/dwarf5-split-gdb-index-types-gdb-generated.test b/bolt/test/X86/dwarf5-split-gdb-index-types-gdb-generated.test index 414f3d695494..ec2b8f7084c7 100644 --- a/bolt/test/X86/dwarf5-split-gdb-index-types-gdb-generated.test +++ b/bolt/test/X86/dwarf5-split-gdb-index-types-gdb-generated.test @@ -10,7 +10,7 @@ # RUN: llvm-bolt maingdb.exe -o maingdb.exe.bolt --update-debug-sections # RUN: llvm-dwarfdump --gdb-index maingdb.exe.bolt | FileCheck --check-prefix=POSTCHECK %s -# Tests that BOLT correctly handles gdb-index generated by GDB with split-dwarf DWARF4. +## Tests that BOLT correctly handles gdb-index generated by GDB with split-dwarf DWARF4. # POSTCHECK: Version = 8 # POSTCHECK: CU list offset = 0x18, has 2 entries diff --git a/bolt/test/X86/dwarf5-subprogram-multiple-ranges-cus.test b/bolt/test/X86/dwarf5-subprogram-multiple-ranges-cus.test new file mode 100644 index 000000000000..bcf63fe6a0d8 --- /dev/null +++ b/bolt/test/X86/dwarf5-subprogram-multiple-ranges-cus.test @@ -0,0 +1,38 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-subprogram-multiple-ranges-main.s -o %t1.o +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-subprogram-multiple-ranges-other.s -o %t2.o +# RUN: %clang %cflags %t1.o %t2.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-objdump %t.bolt --disassemble > %t1.txt +# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt +# RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s + +## This test checks that BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries and handles multiple CUs with ranges. + +# POSTCHECK: _Z7doStuffi>: +# POSTCHECK: [[#%.6x,ADDR:]] +# POSTCHECK: _Z7doStuffi.__part.1>: +# POSTCHECK-NEXT: [[#%.6x,ADDR1:]] +# POSTCHECK: _Z7doStuffi.__part.2>: +# POSTCHECK-NEXT: [[#%.6x,ADDR2:]] + +# POSTCHECK: _Z12doStuffOtheri>: +# POSTCHECK: [[#%.6x,ADDR3:]] +# POSTCHECK: _Z12doStuffOtheri.__part.1>: +# POSTCHECK-NEXT: [[#%.6x,ADDR4:]] +# POSTCHECK: _Z12doStuffOtheri.__part.2>: +# POSTCHECK-NEXT: [[#%.6x,ADDR5:]] + +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_AT_ranges +# POSTCHECK-NEXT: [0x0000000000[[#ADDR]], 0x0000000000[[#ADDR + 0xf]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR1]], 0x0000000000[[#ADDR1 + 0xb]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR2]], 0x0000000000[[#ADDR2 + 0x5]])) + +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK: DW_TAG_subprogram +# POSTCHECK-NEXT: DW_AT_ranges +# POSTCHECK-NEXT: [0x0000000000[[#ADDR3]], 0x0000000000[[#ADDR3 + 0xf]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR4]], 0x0000000000[[#ADDR4 + 0xb]]) +# POSTCHECK-NEXT: [0x0000000000[[#ADDR5]], 0x0000000000[[#ADDR5 + 0x5]])) diff --git a/bolt/test/X86/dwarf5-subprogram-multiple-ranges.test b/bolt/test/X86/dwarf5-subprogram-multiple-ranges.test index 9fedd57b0c6f..80bf8f899040 100644 --- a/bolt/test/X86/dwarf5-subprogram-multiple-ranges.test +++ b/bolt/test/X86/dwarf5-subprogram-multiple-ranges.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with multiple entries. # POSTCHECK: _Z7doStuffi>: # POSTCHECK: [[#%.6x,ADDR:]] diff --git a/bolt/test/X86/dwarf5-subprogram-single-gc-ranges.test b/bolt/test/X86/dwarf5-subprogram-single-gc-ranges.test index 9f8f895ed5f1..21944eba4c92 100644 --- a/bolt/test/X86/dwarf5-subprogram-single-gc-ranges.test +++ b/bolt/test/X86/dwarf5-subprogram-single-gc-ranges.test @@ -6,7 +6,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt > %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry, when function was GCed. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry, when function was GCed. # POSTCHECK: DW_TAG_subprogram # POSTCHECK-NEXT: DW_AT_frame_base diff --git a/bolt/test/X86/dwarf5-subprogram-single-ranges.test b/bolt/test/X86/dwarf5-subprogram-single-ranges.test index f53780eeb5b0..8ffa73c8c9df 100644 --- a/bolt/test/X86/dwarf5-subprogram-single-ranges.test +++ b/bolt/test/X86/dwarf5-subprogram-single-ranges.test @@ -7,7 +7,7 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t1.txt # RUN: cat %t1.txt | FileCheck --check-prefix=POSTCHECK %s -# This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry. +## This test checks BOLT correctly handles DW_TAG_subprogram with Ranges with single entry. # POSTCHECK: _Z7doStuffi>: # POSTCHECK: [[#%.6x,ADDR:]] diff --git a/bolt/test/X86/dwarf5-two-loclists.test b/bolt/test/X86/dwarf5-two-loclists.test index f5c399a944a9..2ede02f3b76f 100644 --- a/bolt/test/X86/dwarf5-two-loclists.test +++ b/bolt/test/X86/dwarf5-two-loclists.test @@ -9,8 +9,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that re-writing of .debug_loclists is handled correctly for two CUs, -# and two loclist entries. +## This tests checks that re-writing of .debug_loclists is handled correctly for two CUs, +## and two loclist entries. # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c) diff --git a/bolt/test/X86/dwarf5-two-rnglists.test b/bolt/test/X86/dwarf5-two-rnglists.test index 98330558a573..17cdc7643bae 100644 --- a/bolt/test/X86/dwarf5-two-rnglists.test +++ b/bolt/test/X86/dwarf5-two-rnglists.test @@ -9,8 +9,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt >> %t.txt # RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s -# This tests checks that re-writing of .debug_rnglists is handled correctly for two CUs, -# and DW_AT_low_pc/DW_AT_high_pc conversion is handled correctly. +## This tests checks that re-writing of .debug_rnglists is handled correctly for two CUs, +## and DW_AT_low_pc/DW_AT_high_pc conversion is handled correctly. # PRECHECK: version = 0x0005 # PRECHECK: DW_AT_low_pc [DW_FORM_addrx] diff --git a/bolt/test/X86/dwarf5-types-backward-cross-reference.s b/bolt/test/X86/dwarf5-types-backward-cross-reference.s index 9278c23ef510..2345cac2fde9 100644 --- a/bolt/test/X86/dwarf5-types-backward-cross-reference.s +++ b/bolt/test/X86/dwarf5-types-backward-cross-reference.s @@ -5,8 +5,8 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles backward cross CU references for dwarf5 -# when -fdebug-types-sections is specified. +## This test checks that BOLT handles backward cross CU references for dwarf5 +## when -fdebug-types-sections is specified. # The assembly was manually modified to do cross CU reference. diff --git a/bolt/test/X86/dwarf5-types-forward-cross-reference.s b/bolt/test/X86/dwarf5-types-forward-cross-reference.s index feeb75da93a8..5ff4ba4286db 100644 --- a/bolt/test/X86/dwarf5-types-forward-cross-reference.s +++ b/bolt/test/X86/dwarf5-types-forward-cross-reference.s @@ -5,10 +5,10 @@ # RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks that BOLT handles forward cross CU references for dwarf5 -# when -fdebug-types-sections is specified. +## This test checks that BOLT handles forward cross CU references for dwarf5 +## when -fdebug-types-sections is specified. -# The assembly was manually modified to do cross CU reference. +## The assembly was manually modified to do cross CU reference. # POSTCHECK: Type Unit # POSTCHECK-SAME: version = 0x0005 diff --git a/bolt/test/X86/dynrelocs.s b/bolt/test/X86/dynrelocs.s index 6d771df4b4ff..b12942e93575 100644 --- a/bolt/test/X86/dynrelocs.s +++ b/bolt/test/X86/dynrelocs.s @@ -1,26 +1,26 @@ -# This reproduces a bug when rewriting dynamic relocations in X86 as -# BOLT incorrectly attributes R_X86_64_64 dynamic relocations -# to the wrong section when the -jump-tables=move flag is used. We -# expect the relocations to belong to the .bolt.org.rodata section but -# it is attributed to a new .rodata section that only contains jump -# table entries, created by BOLT. BOLT will only create this new .rodata -# section if both -jump-tables=move is used and a hot function with -# jt is present in the input binary, triggering a scenario where the -# dynamic relocs rewriting gets confused on where to put .rodata relocs. +## This reproduces a bug when rewriting dynamic relocations in X86 as +## BOLT incorrectly attributes R_X86_64_64 dynamic relocations +## to the wrong section when the -jump-tables=move flag is used. We +## expect the relocations to belong to the .bolt.org.rodata section but +## it is attributed to a new .rodata section that only contains jump +## table entries, created by BOLT. BOLT will only create this new .rodata +## section if both -jump-tables=move is used and a hot function with +## jt is present in the input binary, triggering a scenario where the +## dynamic relocs rewriting gets confused on where to put .rodata relocs. -# It is uncommon to end up with dynamic relocations against .rodata, -# but it can happen. In these cases we cannot corrupt the -# output binary by writing out dynamic relocs incorrectly. The linker -# avoids emitting relocs against read-only sections but we override -# this behavior with the -z notext flag. During runtime, these pages -# are mapped with write permission and then changed to read-only after -# the dynamic linker finishes processing the dynamic relocs. +## It is uncommon to end up with dynamic relocations against .rodata, +## but it can happen. In these cases we cannot corrupt the +## output binary by writing out dynamic relocs incorrectly. The linker +## avoids emitting relocs against read-only sections but we override +## this behavior with the -z notext flag. During runtime, these pages +## are mapped with write permission and then changed to read-only after +## the dynamic linker finishes processing the dynamic relocs. -# In this test, we create a reference to a dynamic object that will -# imply in R_X86_64_64 being used for .rodata. Now BOLT, when creating -# a new .rodata to hold jump table entries, needs to remember to emit -# these dynamic relocs against the original .rodata, and not the new -# one it just created. +## In this test, we create a reference to a dynamic object that will +## imply in R_X86_64_64 being used for .rodata. Now BOLT, when creating +## a new .rodata to hold jump table entries, needs to remember to emit +## these dynamic relocs against the original .rodata, and not the new +## one it just created. # REQUIRES: system-linux @@ -36,8 +36,8 @@ # RUN: -jump-tables=move # RUN: llvm-readobj -rs %t.out | FileCheck --check-prefix=READOBJ %s -# Verify that BOLT outputs the dynamic reloc at the correct address, -# which is the start of the .bolt.org.rodata section. +## Verify that BOLT outputs the dynamic reloc at the correct address, +## which is the start of the .bolt.org.rodata section. # READOBJ: Relocations [ # READOBJ: Section ([[#]]) .rela.dyn { # READOBJ-NEXT: 0x[[#%X,ADDR:]] R_X86_64_64 bar 0x10 diff --git a/bolt/test/X86/exceptions-args.test b/bolt/test/X86/exceptions-args.test index 3a4fa2f0eac1..a617ab653c63 100644 --- a/bolt/test/X86/exceptions-args.test +++ b/bolt/test/X86/exceptions-args.test @@ -1,5 +1,5 @@ -# Check that we handle GNU_args_size correctly. -# It is generated for throwing functions with LP that have parameters on stack. +## Check that we handle GNU_args_size correctly. +## It is generated for throwing functions with LP that have parameters on stack. RUN: %clang %cflags %p/../Inputs/stub.c -fPIC -pie -shared -o %t.so RUN: %clangxx %cxxflags -no-pie %p/Inputs/exc_args.s -o %t %t.so -Wl,-z,notext diff --git a/bolt/test/X86/fallthrough-to-noop.test b/bolt/test/X86/fallthrough-to-noop.test index 2055ca603043..61782f713607 100644 --- a/bolt/test/X86/fallthrough-to-noop.test +++ b/bolt/test/X86/fallthrough-to-noop.test @@ -1,5 +1,5 @@ -# Check that profile data for the fall-through jump is not ignored when there is -# a conditional jump followed by a no-op. +## Check that profile data for the fall-through jump is not ignored when there is +## a conditional jump followed by a no-op. RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ RUN: %S/Inputs/ft_to_noop.s -o %t.o @@ -13,11 +13,11 @@ CHECK: Binary Function "foo" after building cfg CHECK: Exec Count : 20 CHECK: Profile Acc : 100.0% -# This block is terminated with a conditional jump to .Ltmp0 followed by a -# no-op. The profile data contains a count for the fall-through (3) which -# is different from what would be inferred (2). However the destination -# offset of this fall-through jump in the profile data points to the no-op -# following the jump and not the start of the fall-through block .LFT0. +## This block is terminated with a conditional jump to .Ltmp0 followed by a +## no-op. The profile data contains a count for the fall-through (3) which +## is different from what would be inferred (2). However the destination +## offset of this fall-through jump in the profile data points to the no-op +## following the jump and not the start of the fall-through block .LFT0. CHECK: Entry Point CHECK-NEXT: Exec Count : 20 CHECK: Successors: .Ltmp[[#BB1:]] (mispreds: 0, count: 18), .LFT[[#BB2:]] (mispreds: 0, count: 3) diff --git a/bolt/test/X86/false-jump-table.s b/bolt/test/X86/false-jump-table.s index 8cb87ed821e0..fafaa62ccb08 100644 --- a/bolt/test/X86/false-jump-table.s +++ b/bolt/test/X86/false-jump-table.s @@ -1,5 +1,5 @@ -# Check that jump table detection does not fail on a false -# reference to a jump table. +## Check that jump table detection does not fail on a false +## reference to a jump table. # REQUIRES: system-linux diff --git a/bolt/test/X86/fatal-error.s b/bolt/test/X86/fatal-error.s index 312d1d47429f..b883ed1a076b 100644 --- a/bolt/test/X86/fatal-error.s +++ b/bolt/test/X86/fatal-error.s @@ -1,6 +1,6 @@ -# Tests whether llvm-bolt will correctly exit with error code and printing -# fatal error message in case one occurs. Here we test opening a function -# reordering file that does not exist. +## Tests whether llvm-bolt will correctly exit with error code and printing +## fatal error message in case one occurs. Here we test opening a function +## reordering file that does not exist. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q diff --git a/bolt/test/X86/fragment-lite-reverse.s b/bolt/test/X86/fragment-lite-reverse.s index 3d681208d3e9..94bd2961c951 100644 --- a/bolt/test/X86/fragment-lite-reverse.s +++ b/bolt/test/X86/fragment-lite-reverse.s @@ -1,4 +1,4 @@ -# Check that BOLT in lite mode processes fragments as expected. +## Check that BOLT in lite mode processes fragments as expected. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata diff --git a/bolt/test/X86/fragment-lite.s b/bolt/test/X86/fragment-lite.s index 32d1f5a98b64..9a5e5f83bc3f 100644 --- a/bolt/test/X86/fragment-lite.s +++ b/bolt/test/X86/fragment-lite.s @@ -1,4 +1,4 @@ -# Check that BOLT in lite mode processes fragments as expected. +## Check that BOLT in lite mode processes fragments as expected. # RUN: split-file %s %t # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o diff --git a/bolt/test/X86/fragmented-symbols.s b/bolt/test/X86/fragmented-symbols.s index ac2f705c64e9..c03e2f5d46c8 100644 --- a/bolt/test/X86/fragmented-symbols.s +++ b/bolt/test/X86/fragmented-symbols.s @@ -1,5 +1,5 @@ -# Checks that symbols are allocated in correct sections, and that empty -# fragments are not allocated at all. +## Checks that symbols are allocated in correct sections, and that empty +## fragments are not allocated at all. # REQUIRES: x86_64-linux diff --git a/bolt/test/X86/frame-opt-lea.s b/bolt/test/X86/frame-opt-lea.s index fe84e8c03744..4b0c9e44080f 100644 --- a/bolt/test/X86/frame-opt-lea.s +++ b/bolt/test/X86/frame-opt-lea.s @@ -1,6 +1,6 @@ -# This checks that frame optimizer does not try to optimize away caller-saved -# regs when we do not have complete aliasing info (when there is an LEA -# instruction and the function does arithmetic with stack addresses). +## This checks that frame optimizer does not try to optimize away caller-saved +## regs when we do not have complete aliasing info (when there is an LEA +## instruction and the function does arithmetic with stack addresses). # REQUIRES: system-linux diff --git a/bolt/test/X86/function-order-lite.s b/bolt/test/X86/function-order-lite.s index 5cedc833b089..b8a6497c755d 100644 --- a/bolt/test/X86/function-order-lite.s +++ b/bolt/test/X86/function-order-lite.s @@ -1,5 +1,5 @@ -# Check that functions listed in -function-order list take precedence over -# lite mode function filtering. +## Check that functions listed in -function-order list take precedence over +## lite mode function filtering. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: link_fdata %s %t.o %t.fdata diff --git a/bolt/test/X86/gdbindex.test b/bolt/test/X86/gdbindex.test index 87a5ec142af2..f9ae7aebe786 100644 --- a/bolt/test/X86/gdbindex.test +++ b/bolt/test/X86/gdbindex.test @@ -4,15 +4,15 @@ RUN: ld.lld --gdb-index %t.o %t2.o -o %tfile.exe RUN: llvm-bolt %tfile.exe -o %tfile.exe.bolt --update-debug-sections RUN: llvm-dwarfdump -gdb-index %tfile.exe.bolt | FileCheck %s -; test.cpp: -; int main() { return 0; } -; test2.cpp: -; int main2() { return 0; } -; Compiled with: -; gcc -gsplit-dwarf -c test.cpp test2.cpp -; gold --gdb-index test.o test2.o -o dwarfdump-gdbindex-v7.elf-x86-64 -; gcc version 5.3.1 20160413, GNU gold (GNU Binutils for Ubuntu 2.26) 1.11 -; Info about gdb-index: https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html +;; test.cpp: +;; int main() { return 0; } +;; test2.cpp: +;; int main2() { return 0; } +;; Compiled with: +;; gcc -gsplit-dwarf -c test.cpp test2.cpp +;; gold --gdb-index test.o test2.o -o dwarfdump-gdbindex-v7.elf-x86-64 +;; gcc version 5.3.1 20160413, GNU gold (GNU Binutils for Ubuntu 2.26) 1.11 +;; Info about gdb-index: https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html ; CHECK-LABEL: .gdb_index contents: ; CHECK: Version = 7 diff --git a/bolt/test/X86/high_pc_udata.s b/bolt/test/X86/high_pc_udata.s index c3a62842b875..ad15d41bc5b7 100644 --- a/bolt/test/X86/high_pc_udata.s +++ b/bolt/test/X86/high_pc_udata.s @@ -15,8 +15,8 @@ # POSTCHECK-NEXT: DW_AT_name [DW_FORM_strp] # POSTCHECK-SAME: "main.cpp" -# Testing that BOLT transforms DW_AT_high_pc of form DW_FORM_udata correctly into DW_AT_ranges. -# Manually changed so that DW_AT_high_pc is DW_FORM_udata, and that DW_AT_name is after it. +## Testing that BOLT transforms DW_AT_high_pc of form DW_FORM_udata correctly into DW_AT_ranges. +## Manually changed so that DW_AT_high_pc is DW_FORM_udata, and that DW_AT_name is after it. # int main() { # return 0; # } diff --git a/bolt/test/X86/icp-inline.s b/bolt/test/X86/icp-inline.s index 3c863833449f..c5106db5a538 100644 --- a/bolt/test/X86/icp-inline.s +++ b/bolt/test/X86/icp-inline.s @@ -1,7 +1,7 @@ -# This test verifies the effect of -icp-inline option: that ICP is only -# performed for call targets eligible for inlining. +## This test verifies the effect of -icp-inline option: that ICP is only +## performed for call targets eligible for inlining. -# The assembly was produced from C code compiled with clang-15 -O1 -S: +## The assembly was produced from C code compiled with clang-15 -O1 -S: # int foo(int x) { return x + 1; } # int bar(int x) { return x*100 + 42; } diff --git a/bolt/test/X86/ignored-interprocedural-reference.s b/bolt/test/X86/ignored-interprocedural-reference.s index 12e4fb92adcc..94d7a91f2c7f 100644 --- a/bolt/test/X86/ignored-interprocedural-reference.s +++ b/bolt/test/X86/ignored-interprocedural-reference.s @@ -1,5 +1,5 @@ -# This reproduces a bug with not processing interprocedural references from -# ignored functions. +## This reproduces a bug with not processing interprocedural references from +## ignored functions. # REQUIRES: system-linux @@ -16,7 +16,7 @@ # CHECK-YAML: calls: {{.*}} disc: 1 # PREAGG: B #main# #foo_secondary# 1 1 -# main calls foo at valid instruction offset past nops that are to be stripped. +## main calls foo at valid instruction offset past nops that are to be stripped. .globl main main: .cfi_startproc @@ -25,7 +25,7 @@ main: .cfi_endproc .size main,.-main -# Placeholder cold fragment to force main to be ignored in non-relocation mode. +## Placeholder cold fragment to force main to be ignored in non-relocation mode. .globl main.cold main.cold: .cfi_startproc @@ -33,8 +33,8 @@ main.cold: .cfi_endproc .size main.cold,.-main.cold -# foo is set up to contain a valid instruction at called offset, and trapping -# instructions past that. +## foo is set up to contain a valid instruction at called offset, and trapping +## instructions past that. .globl foo foo: .cfi_startproc diff --git a/bolt/test/X86/indirect-goto-pie.test b/bolt/test/X86/indirect-goto-pie.test index 039ff5c41d3d..81cff9a32fbb 100644 --- a/bolt/test/X86/indirect-goto-pie.test +++ b/bolt/test/X86/indirect-goto-pie.test @@ -1,6 +1,6 @@ -# Check that llvm-bolt fails to process PIC binaries with computed goto, as the -# support is not there yet for correctly updating dynamic relocations -# referencing code inside functions. +## Check that llvm-bolt fails to process PIC binaries with computed goto, as the +## support is not there yet for correctly updating dynamic relocations +## referencing code inside functions. REQUIRES: x86_64-linux @@ -8,7 +8,7 @@ RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q RUN: not llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \ RUN: |& FileCheck %s -# Check that processing works if main() is skipped. +## Check that processing works if main() is skipped. RUN: llvm-bolt %t -o %t.bolt --relocs=1 --skip-funcs=main CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW diff --git a/bolt/test/X86/indirect-goto.test b/bolt/test/X86/indirect-goto.test index bbc11e7d3317..8d2cb5e62a97 100644 --- a/bolt/test/X86/indirect-goto.test +++ b/bolt/test/X86/indirect-goto.test @@ -1,9 +1,9 @@ -# Check llvm-bolt processes binaries compiled from sources that use indirect goto. +## Check llvm-bolt processes binaries compiled from sources that use indirect goto. RUN: %clang %cflags -no-pie %S/Inputs/indirect_goto.c -Wl,-q -o %t RUN: llvm-bolt %t -o %t.null --relocs=1 --print-cfg --print-only=main \ RUN: --strict \ RUN: 2>&1 | FileCheck %s -# Check that all possible destinations are included as successors. +## Check that all possible destinations are included as successors. CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW CHECK: Successors: .Ltmp0, .Ltmp1, .Ltmp2 diff --git a/bolt/test/X86/inlined-function-mixed.test b/bolt/test/X86/inlined-function-mixed.test index 5a87bdde9535..9f6ef396bb15 100644 --- a/bolt/test/X86/inlined-function-mixed.test +++ b/bolt/test/X86/inlined-function-mixed.test @@ -1,5 +1,5 @@ -# Make sure inlining from a unit with debug info into unit without -# debug info does not cause a crash. +## Make sure inlining from a unit with debug info into unit without +## debug info does not cause a crash. RUN: %clangxx %cxxflags %S/Inputs/inlined.cpp -c -o %T/inlined.o RUN: %clangxx %cxxflags %S/Inputs/inlinee.cpp -c -o %T/inlinee.o -g diff --git a/bolt/test/X86/insert-addr-rnglists_base.s b/bolt/test/X86/insert-addr-rnglists_base.s index 800bed27243d..c08376c91634 100644 --- a/bolt/test/X86/insert-addr-rnglists_base.s +++ b/bolt/test/X86/insert-addr-rnglists_base.s @@ -6,8 +6,8 @@ # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s # RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s -# This test checks we correctly insert DW_AT_addr_base, when converting DW_AT_low_pc into DW_AT_ranges. -# PRECHECK-NOT: DW_AT_addr_base +## This test checks we correctly insert DW_AT_addr_base, when converting DW_AT_low_pc into DW_AT_ranges. +## PRECHECK-NOT: DW_AT_addr_base # POSTCHECK: DW_AT_ranges [DW_FORM_rnglistx] # POSTCHECK: DW_AT_rnglists_base [DW_FORM_sec_offset] (0x0000000c) diff --git a/bolt/test/X86/insert-debug-info-entry.test b/bolt/test/X86/insert-debug-info-entry.test index f36e3ed6f722..31af3db7d4a8 100644 --- a/bolt/test/X86/insert-debug-info-entry.test +++ b/bolt/test/X86/insert-debug-info-entry.test @@ -7,7 +7,7 @@ ; RUN: llvm-dwarfdump --debug-info foo.exe | FileCheck -check-prefix=PRE-BOLT %s ; RUN: llvm-dwarfdump --debug-info foo.exe.bolt | FileCheck %s -; This tests checks that DW_AT_GNU_ranges_base is added at the end of the CU. +;; This tests checks that DW_AT_GNU_ranges_base is added at the end of the CU. ; PRE-BOLT: DW_AT_GNU_addr_base ; PRE-BOLT-NOT: DW_AT_GNU_ranges_base diff --git a/bolt/test/X86/internal-call-instrument-so.s b/bolt/test/X86/internal-call-instrument-so.s index d13c828f605c..99e5b2922140 100644 --- a/bolt/test/X86/internal-call-instrument-so.s +++ b/bolt/test/X86/internal-call-instrument-so.s @@ -1,4 +1,4 @@ -# This reproduces a bug with instrumentation crashes on internal call +## This reproduces a bug with instrumentation crashes on internal call # REQUIRES: system-linux,bolt-runtime,target=x86_64{{.*}} diff --git a/bolt/test/X86/internal-call-instrument.s b/bolt/test/X86/internal-call-instrument.s index c393f1dac864..4dc0408c6d12 100644 --- a/bolt/test/X86/internal-call-instrument.s +++ b/bolt/test/X86/internal-call-instrument.s @@ -1,4 +1,4 @@ -# This reproduces a bug with instrumentation crashes on internal call +## This reproduces a bug with instrumentation crashes on internal call # REQUIRES: x86_64-linux,bolt-runtime,target=x86_64{{.*}} diff --git a/bolt/test/X86/interprocedural-ref-entry-point.s b/bolt/test/X86/interprocedural-ref-entry-point.s index 0e1cca5c9bfe..67f0a452bf34 100644 --- a/bolt/test/X86/interprocedural-ref-entry-point.s +++ b/bolt/test/X86/interprocedural-ref-entry-point.s @@ -1,7 +1,7 @@ -# This reproduces a bug where not registering cold fragment entry points -# leads to removing blocks and an inconsistent CFG after UCE. -# Test assembly was obtained using C-Reduce from this C++ code: -# (compiled with `g++ -O2 -Wl,-q`) +## This reproduces a bug where not registering cold fragment entry points +## leads to removing blocks and an inconsistent CFG after UCE. +## Test assembly was obtained using C-Reduce from this C++ code: +## (compiled with `g++ -O2 -Wl,-q`) # # #include # int a; diff --git a/bolt/test/X86/is-strip.s b/bolt/test/X86/is-strip.s index df12986efc42..1ce81872326c 100644 --- a/bolt/test/X86/is-strip.s +++ b/bolt/test/X86/is-strip.s @@ -1,4 +1,4 @@ -# This test checks whether a binary is stripped or not. +## This test checks whether a binary is stripped or not. # RUN: %clang++ %cflags %p/Inputs/linenumber.cpp -o %t -Wl,-q # RUN: llvm-bolt %t -o %t.out 2>&1 | FileCheck %s -check-prefix=CHECK-NOSTRIP diff --git a/bolt/test/X86/issue20.s b/bolt/test/X86/issue20.s index 785064df89c9..99a4f2ea2ac9 100644 --- a/bolt/test/X86/issue20.s +++ b/bolt/test/X86/issue20.s @@ -1,6 +1,6 @@ -# This reproduces issue 20 from our github repo -# "BOLT crashes when removing unreachable BBs that are a target -# in a JT" +## This reproduces issue 20 from our github repo +## "BOLT crashes when removing unreachable BBs that are a target +## in a JT" # REQUIRES: system-linux diff --git a/bolt/test/X86/issue20.test b/bolt/test/X86/issue20.test index eeb76d15aec4..dcb1ce5ab156 100644 --- a/bolt/test/X86/issue20.test +++ b/bolt/test/X86/issue20.test @@ -1,6 +1,6 @@ -# This reproduces issue 20 from our github repo -# "BOLT crashes when removing unreachable BBs that are a target -# in a JT" +## This reproduces issue 20 from our github repo +## "BOLT crashes when removing unreachable BBs that are a target +## in a JT" # RUN: yaml2obj %p/Inputs/issue20.yaml &> %t.exe # RUN: llvm-bolt %t.exe --relocs=0 --jump-tables=move --print-finalized \ diff --git a/bolt/test/X86/issue26.s b/bolt/test/X86/issue26.s index 6f9bc72d6e10..2a97febfd23c 100644 --- a/bolt/test/X86/issue26.s +++ b/bolt/test/X86/issue26.s @@ -1,6 +1,6 @@ -# This reproduces issue 26 from our github repo -# BOLT fails with the following assertion: -# llvm/tools/llvm-bolt/src/BinaryFunction.cpp:2950: void llvm::bolt::BinaryFunction::postProcessBranches(): Assertion `validateCFG() && "invalid CFG"' failed. +## This reproduces issue 26 from our github repo +## BOLT fails with the following assertion: +## llvm/tools/llvm-bolt/src/BinaryFunction.cpp:2950: void llvm::bolt::BinaryFunction::postProcessBranches(): Assertion `validateCFG() && "invalid CFG"' failed. # REQUIRES: system-linux diff --git a/bolt/test/X86/issue26.test b/bolt/test/X86/issue26.test index bafd0912cf4a..55704a884d20 100644 --- a/bolt/test/X86/issue26.test +++ b/bolt/test/X86/issue26.test @@ -1,4 +1,4 @@ -# This reproduces issue 26 from our github repo +## This reproduces issue 26 from our github repo # RUN: yaml2obj %p/Inputs/issue26.yaml &> %t.exe # RUN: llvm-bolt %t.exe --relocs --print-cfg -o %t.out 2>&1 \ diff --git a/bolt/test/X86/jmp-optimization.test b/bolt/test/X86/jmp-optimization.test index 92f4b9a14f0f..a98be1157341 100644 --- a/bolt/test/X86/jmp-optimization.test +++ b/bolt/test/X86/jmp-optimization.test @@ -1,7 +1,7 @@ -# Tests the optimization of functions that just do a tail call in the beginning. +## Tests the optimization of functions that just do a tail call in the beginning. -# This test has commands that rely on shell capabilities that won't execute -# correctly on Windows e.g. unsupported parameter expansion +## This test has commands that rely on shell capabilities that won't execute +## correctly on Windows e.g. unsupported parameter expansion REQUIRES: shell RUN: %clang %cflags -O2 %S/Inputs/jmp_opt{,2,3}.cpp -o %t diff --git a/bolt/test/X86/jmpjmp.test b/bolt/test/X86/jmpjmp.test index cc6107f47812..0d058fec8af4 100644 --- a/bolt/test/X86/jmpjmp.test +++ b/bolt/test/X86/jmpjmp.test @@ -1,5 +1,5 @@ -# Verifies that llvm-bolt allocates two consecutive jumps in two separate basic -# blocks. +## Verifies that llvm-bolt allocates two consecutive jumps in two separate basic +## blocks. RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %S/Inputs/jmpjmp.s -o %t.o RUN: %clang %cflags %t.o -o %t.exe diff --git a/bolt/test/X86/jt-symbol-disambiguation-3.s b/bolt/test/X86/jt-symbol-disambiguation-3.s index c472b6bbf9c6..22b34cef1bc4 100644 --- a/bolt/test/X86/jt-symbol-disambiguation-3.s +++ b/bolt/test/X86/jt-symbol-disambiguation-3.s @@ -1,11 +1,11 @@ -# In this test case, we reproduce the behavior seen in gcc where the -# base address of a jump table is decremented by some number and ends up -# at the exact addess of a jump table from another function. After -# linking, the instruction references another jump table and that -# confuses BOLT. -# We repro here the following issue: -# Before assembler: Instruction operand is: jumptable - 32 -# After linking: Instruction operand is: another_jumptable +## In this test case, we reproduce the behavior seen in gcc where the +## base address of a jump table is decremented by some number and ends up +## at the exact addess of a jump table from another function. After +## linking, the instruction references another jump table and that +## confuses BOLT. +## We repro here the following issue: +## Before assembler: Instruction operand is: jumptable - 32 +## After linking: Instruction operand is: another_jumptable # REQUIRES: system-linux, asserts @@ -18,8 +18,8 @@ # RUN: llvm-bolt %t.exe -o %t.exe.bolt --relocs=1 --lite=0 \ # RUN: --reorder-blocks=reverse -# Useful when manually testing this. Currently we just check that -# the test does not cause BOLT to assert. +## Useful when manually testing this. Currently we just check that +## the test does not cause BOLT to assert. # COM: %t.exe.bolt 1 2 .file "jt-symbol-disambiguation-3.s" diff --git a/bolt/test/X86/jump-table-fixed-ref-pic.test b/bolt/test/X86/jump-table-fixed-ref-pic.test index 4195b97aac50..c8b6eda2278b 100644 --- a/bolt/test/X86/jump-table-fixed-ref-pic.test +++ b/bolt/test/X86/jump-table-fixed-ref-pic.test @@ -1,5 +1,5 @@ -# Verify that BOLT detects fixed destination of indirect jump for PIC -# case. +## Verify that BOLT detects fixed destination of indirect jump for PIC +## case. XFAIL: * diff --git a/bolt/test/X86/jump-table-footprint-reduction.test b/bolt/test/X86/jump-table-footprint-reduction.test index 4e0f9b16818d..290e585fc1b7 100644 --- a/bolt/test/X86/jump-table-footprint-reduction.test +++ b/bolt/test/X86/jump-table-footprint-reduction.test @@ -1,5 +1,5 @@ -# Checks that jump table footprint reduction optimization is reducing entry -# sizes. +## Checks that jump table footprint reduction optimization is reducing entry +## sizes. RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ RUN: %S/Inputs/jump_table_footprint_reduction.s -o %t.o diff --git a/bolt/test/X86/jump-table-icp.test b/bolt/test/X86/jump-table-icp.test index 5b989d18018b..f1474326db3b 100644 --- a/bolt/test/X86/jump-table-icp.test +++ b/bolt/test/X86/jump-table-icp.test @@ -4,8 +4,8 @@ RUN: link_fdata %p/Inputs/jump_table_icp.s %t.o %t.fdata --nmtool llvm-nm RUN: llvm-strip --strip-unneeded %t.o RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q -# This test has commands that rely on shell capabilities that won't execute -# correctly on Windows e.g. subshell execution +## This test has commands that rely on shell capabilities that won't execute +## correctly on Windows e.g. subshell execution REQUIRES: shell RUN: (llvm-bolt %t.exe --data %t.fdata -o %t --relocs \ diff --git a/bolt/test/X86/jump-table-pic-conflict.s b/bolt/test/X86/jump-table-pic-conflict.s index ed3c77d49b6c..c84551a0e213 100644 --- a/bolt/test/X86/jump-table-pic-conflict.s +++ b/bolt/test/X86/jump-table-pic-conflict.s @@ -1,16 +1,16 @@ -# Check cases when the first PIC jump table entries of one function can be -# interpreted as valid last entries of the previous function. +## Check cases when the first PIC jump table entries of one function can be +## interpreted as valid last entries of the previous function. -# Conditions to trigger the bug: Function A and B have jump tables that -# are adjacent in memory. We run in lite relocation mode. Function B -# is not disassembled because it does not have profile. Function A -# triggers a special conditional that forced BOLT to rewrite its jump -# table in-place (instead of moving it) because it is marked as -# non-simple (in this case, containing unknown control flow). The -# first entry of B's jump table (a PIC offset) happens to be a valid -# address inside A when added to A's jump table base address. In this -# case, BOLT could overwrite B's jump table, corrupting it, thinking -# the first entry of it is actually part of A's jump table. +## Conditions to trigger the bug: Function A and B have jump tables that +## are adjacent in memory. We run in lite relocation mode. Function B +## is not disassembled because it does not have profile. Function A +## triggers a special conditional that forced BOLT to rewrite its jump +## table in-place (instead of moving it) because it is marked as +## non-simple (in this case, containing unknown control flow). The +## first entry of B's jump table (a PIC offset) happens to be a valid +## address inside A when added to A's jump table base address. In this +## case, BOLT could overwrite B's jump table, corrupting it, thinking +## the first entry of it is actually part of A's jump table. # REQUIRES: system-linux @@ -26,8 +26,8 @@ # readelf. This is another way to check this bug: # COM: %t.out -# BOLT needs to create a new rodata section, indicating that it -# successfully moved the jump table in _start. +## BOLT needs to create a new rodata section, indicating that it +## successfully moved the jump table in _start. # CHECK: [{{.*}}] .bolt.org.rodata .globl _start @@ -41,8 +41,8 @@ _start: cmpq $3, %rdi ja .L5 jmp .L6 -# Unreachable code, here to mark this function as non-simple -# (containing unknown control flow) with a stray indirect jmp +## Unreachable code, here to mark this function as non-simple +## (containing unknown control flow) with a stray indirect jmp jmp *%rax .L6: decq %rdi @@ -115,8 +115,8 @@ str1: .asciz "Message 1\n" str2: .asciz "Message 2\n" str3: .asciz "Message 3\n" str4: .asciz "Highrange\n" -# Special case where the first .LJT2 entry is a valid offset of -# _start when interpreted with .LJT1 as a base address. +## Special case where the first .LJT2 entry is a valid offset of +## _start when interpreted with .LJT1 as a base address. .LJT1: .long .L1-.LJT1 .long .L2-.LJT1 diff --git a/bolt/test/X86/jump-table-pic-order.test b/bolt/test/X86/jump-table-pic-order.test index 59c0af252b07..09bda932121b 100644 --- a/bolt/test/X86/jump-table-pic-order.test +++ b/bolt/test/X86/jump-table-pic-order.test @@ -1,5 +1,5 @@ -# Check that successors of a basic block with jump table are generated -# in the same order as they appear in the input code. +## Check that successors of a basic block with jump table are generated +## in the same order as they appear in the input code. RUN: %clang %cflags %S/Inputs/jump-table-pic.s -o %t.exe -Wl,-q RUN: llvm-bolt %t.exe --strict --print-cfg --print-only=main -o %t.null \ @@ -7,6 +7,6 @@ RUN: | FileCheck %s CHECK: BB Layout : {{.*, .*, .*,}} [[BB4to6:.*, .*, .*]] -# Check that successors appear in the order matching the input layout. +## Check that successors appear in the order matching the input layout. CHECK: jmpq *%rax # JUMPTABLE CHECK-NEXT: Successors: [[BB4to6]] diff --git a/bolt/test/X86/jump-table-reference.test b/bolt/test/X86/jump-table-reference.test index 9d33c0d5e727..32696683fb5e 100644 --- a/bolt/test/X86/jump-table-reference.test +++ b/bolt/test/X86/jump-table-reference.test @@ -1,4 +1,4 @@ -# Verifies that BOLT detects fixed destination of indirect jump +## Verifies that BOLT detects fixed destination of indirect jump RUN: %clang %cflags -no-pie %S/Inputs/jump_table_reference.s -Wl,-q -o %t RUN: llvm-bolt %t --relocs -o %t.null 2>&1 | FileCheck %s diff --git a/bolt/test/X86/layout-heuristic.test b/bolt/test/X86/layout-heuristic.test index 3d24e1aad139..c614e7b0f33e 100644 --- a/bolt/test/X86/layout-heuristic.test +++ b/bolt/test/X86/layout-heuristic.test @@ -1,8 +1,8 @@ -# Checks that llvm-bolt is able to read data generated by perf2bolt, update the -# CFG edges accordingly with absolute number of branches and mispredictions, -# infer fallthrough branch info and reorder basic blocks using a greedy -# heuristic, or find the optimal solution if the function is small enough. -# Also checks that llvm-bolt disassembler and CFG builder is working properly. +## Checks that llvm-bolt is able to read data generated by perf2bolt, update the +## CFG edges accordingly with absolute number of branches and mispredictions, +## infer fallthrough branch info and reorder basic blocks using a greedy +## heuristic, or find the optimal solution if the function is small enough. +## Also checks that llvm-bolt disassembler and CFG builder is working properly. RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --data %p/Inputs/blarge.fdata \ diff --git a/bolt/test/X86/line-number.test b/bolt/test/X86/line-number.test index b039962643d4..d4dca825502e 100644 --- a/bolt/test/X86/line-number.test +++ b/bolt/test/X86/line-number.test @@ -1,17 +1,17 @@ -# Verifies that the extraction of DWARF line number information is correct. +## Verifies that the extraction of DWARF line number information is correct. RUN: %clangxx %cxxflags %S/Inputs/linenumber.cpp -g -o %t RUN: llvm-bolt %t -o %t.null --print-reordered --update-debug-sections \ RUN: --print-debug-info --reorder-blocks=reverse --sequential-disassembly \ RUN: 2>&1 | FileCheck %s -# Local variable in f() +## Local variable in f() CHECK: movl $0xbeef, -0x4(%rbp) # debug line {{.*}}linenumber.cpp:9 -# Checks that a branch instruction that is inserted by BOLT does not have -# debug line info associated with it. +## Checks that a branch instruction that is inserted by BOLT does not have +## debug line info associated with it. CHECK-NOT: jmp .LFT0 # debug line {{.*}}linenumber.cpp:1 -# Call to f() in g() +## Call to f() in g() CHECK: callq _Z1fv{{.*}} # debug line {{.*}}linenumber.cpp:19 -# Calls to g() and f() in main +## Calls to g() and f() in main CHECK: callq _Z1gv{{.*}} # debug line {{.*}}linenumber.cpp:23 CHECK: callq _Z1fv{{.*}} # debug line {{.*}}linenumber.cpp:23 diff --git a/bolt/test/X86/lit.local.cfg b/bolt/test/X86/lit.local.cfg index 947d25cb6e8c..ea9928d19188 100644 --- a/bolt/test/X86/lit.local.cfg +++ b/bolt/test/X86/lit.local.cfg @@ -1,7 +1,7 @@ if not "X86" in config.root.targets: config.unsupported = True -flags = "--target=x86_64-pc-linux -nostdlib" +flags = "--target=x86_64-unknown-linux-gnu -nostdlib" config.substitutions.insert(0, ("%cflags", f"%cflags {flags}")) config.substitutions.insert(0, ("%cxxflags", f"%cxxflags {flags}")) diff --git a/bolt/test/X86/log.test b/bolt/test/X86/log.test index 0cbb5b625d00..42109db87d9e 100644 --- a/bolt/test/X86/log.test +++ b/bolt/test/X86/log.test @@ -1,6 +1,6 @@ -# Tests whether llvm-bolt is able to redirect logs when processing a simple -# input. If this test fails on your changes, please use BinaryContext::outs() -# to print BOLT logging instead of llvm::outs(). +## Tests whether llvm-bolt is able to redirect logs when processing a simple +## input. If this test fails on your changes, please use BinaryContext::outs() +## to print BOLT logging instead of llvm::outs(). RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --data %p/Inputs/blarge.fdata -v=2 \ @@ -12,7 +12,7 @@ CHECK-NOT: BOLT-INFO CHECK-NOT: BOLT-WARNING CHECK-NOT: BOLT-ERROR -# Check some usual BOLT output lines are being redirected to the log file +## Check some usual BOLT output lines are being redirected to the log file CHECK-LOG: BOLT-INFO: Target architecture CHECK-LOG: BOLT-INFO: BOLT version CHECK-LOG: BOLT-INFO: basic block reordering modified layout diff --git a/bolt/test/X86/loop-inversion-pass.s b/bolt/test/X86/loop-inversion-pass.s index cb241110cf70..495737580984 100644 --- a/bolt/test/X86/loop-inversion-pass.s +++ b/bolt/test/X86/loop-inversion-pass.s @@ -16,19 +16,19 @@ # RUN: --print-finalized --loop-inversion-opt -o %t.out3 \ # RUN: | FileCheck --check-prefix="CHECK3" %s -# The case where the loop is used: +## The case where the loop is used: # FDATA: 1 main 2 1 main #.J1# 0 420 # FDATA: 1 main b 1 main #.Jloop# 0 420 # FDATA: 1 main b 1 main d 0 1 # CHECK: BB Layout : .LBB00, .Ltmp0, .Ltmp1, .LFT0 -# The case where the loop is unused: +## The case where the loop is unused: # FDATA2: 1 main 2 1 main #.J1# 0 420 # FDATA2: 1 main b 1 main #.Jloop# 0 1 # FDATA2: 1 main b 1 main d 0 420 # CHECK2: BB Layout : .LBB00, .Ltmp1, .LFT0, .Ltmp0 -# The case where the loop does not require rotation: +## The case where the loop does not require rotation: # FDATA3: 1 main 2 1 main #.J1# 0 420 # FDATA3: 1 main b 1 main #.Jloop# 0 420 # FDATA3: 1 main b 1 main d 0 1 diff --git a/bolt/test/X86/loop-nest.test b/bolt/test/X86/loop-nest.test index 24fde1004b00..51c8fcdb32ea 100644 --- a/bolt/test/X86/loop-nest.test +++ b/bolt/test/X86/loop-nest.test @@ -1,4 +1,4 @@ -# Verifies that llvm-bolt prints correct loop information. +## Verifies that llvm-bolt prints correct loop information. RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ RUN: %p/Inputs/loop_nest.s -o %t.o diff --git a/bolt/test/X86/merge-fdata-bat-mode.test b/bolt/test/X86/merge-fdata-bat-mode.test index 41738e196b5d..2d2a423fb85b 100644 --- a/bolt/test/X86/merge-fdata-bat-mode.test +++ b/bolt/test/X86/merge-fdata-bat-mode.test @@ -1,5 +1,5 @@ -# Check merge-fdata tool correctly processes fdata files with header strings -# such as the ones produced by BAT mode (boltedcollection) +## Check merge-fdata tool correctly processes fdata files with header strings +## such as the ones produced by BAT mode (boltedcollection) RUN: merge-fdata %S/Inputs/bat_profile_1.fdata \ RUN: %S/Inputs/bat_profile_2.fdata \ RUN: | FileCheck %s --check-prefix=CHECK-FDATA diff --git a/bolt/test/X86/merge-fdata-nobat-mode.test b/bolt/test/X86/merge-fdata-nobat-mode.test index 870d9f880e28..978052e35007 100644 --- a/bolt/test/X86/merge-fdata-nobat-mode.test +++ b/bolt/test/X86/merge-fdata-nobat-mode.test @@ -1,4 +1,4 @@ -# Check that merge-fdata tool doesn't spuriously print boltedcollection +## Check that merge-fdata tool doesn't spuriously print boltedcollection RUN: merge-fdata %S/Inputs/blarge.fdata %S/Inputs/blarge.fdata \ RUN: | FileCheck %s --check-prefix=CHECK-FDATA diff --git a/bolt/test/X86/merge-fdata-output.test b/bolt/test/X86/merge-fdata-output.test index 17050e48a95f..b12b460d9d7b 100644 --- a/bolt/test/X86/merge-fdata-output.test +++ b/bolt/test/X86/merge-fdata-output.test @@ -1,4 +1,4 @@ -# Check merge-fdata tool correctly handles `-o` option. +## Check merge-fdata tool correctly handles `-o` option. RUN: merge-fdata %S/Inputs/bat_profile_1.fdata \ RUN: %S/Inputs/bat_profile_2.fdata \ RUN: | FileCheck %s @@ -13,4 +13,4 @@ RUN: %S/Inputs/bat_profile_2.fdata \ RUN: -o %t RUN: FileCheck %s < %t -CHECK: 1 main 451 1 SolveCubic 0 0 302 \ No newline at end of file +CHECK: 1 main 451 1 SolveCubic 0 0 302 diff --git a/bolt/test/X86/no-entry-reordering.test b/bolt/test/X86/no-entry-reordering.test index a2638e1388c9..309e5c1d04f9 100644 --- a/bolt/test/X86/no-entry-reordering.test +++ b/bolt/test/X86/no-entry-reordering.test @@ -1,5 +1,5 @@ -# Verifies that llvm-bolt reordering heuristic does not allocate a BB before the -# entry point even if there is a hot edge from a block to entry point +## Verifies that llvm-bolt reordering heuristic does not allocate a BB before the +## entry point even if there is a hot edge from a block to entry point RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %S/Inputs/entry.s -o %t.o RUN: link_fdata %S/Inputs/entry.s %t.o %t.fdata --nmtool llvm-nm diff --git a/bolt/test/X86/no-output.test b/bolt/test/X86/no-output.test index 523bdf25f521..fa0c8dd68ae4 100644 --- a/bolt/test/X86/no-output.test +++ b/bolt/test/X86/no-output.test @@ -1,4 +1,4 @@ -# This script checks that BOLT is able to work in dry run mode (no output) +## This script checks that BOLT is able to work in dry run mode (no output) # REQUIRES: system-linux diff --git a/bolt/test/X86/nolbr.s b/bolt/test/X86/nolbr.s index bebb697122f4..999c68566c94 100644 --- a/bolt/test/X86/nolbr.s +++ b/bolt/test/X86/nolbr.s @@ -1,6 +1,6 @@ -# This reproduces a bug where profile collected from perf without LBRs and -# converted into fdata-no-lbr format is reported to not contain profile for any -# functions. +## This reproduces a bug where profile collected from perf without LBRs and +## converted into fdata-no-lbr format is reported to not contain profile for any +## functions. # REQUIRES: system-linux diff --git a/bolt/test/X86/patch-entries.test b/bolt/test/X86/patch-entries.test index 4a725412dd61..bf31af342dc6 100644 --- a/bolt/test/X86/patch-entries.test +++ b/bolt/test/X86/patch-entries.test @@ -1,7 +1,7 @@ -# Checking crashes against injected binary functions created by patch -# entries pass and debug info turned on. In these cases, we were -# trying to fetch input to output maps on injected functions and -# crashing. +## Checking crashes against injected binary functions created by patch +## entries pass and debug info turned on. In these cases, we were +## trying to fetch input to output maps on injected functions and +## crashing. REQUIRES: system-linux @@ -10,8 +10,8 @@ RUN: -Wl,-q -I%p/../Inputs RUN: llvm-bolt -relocs %t.exe -o %t.out --update-debug-sections --force-patch \ RUN: --enable-bat -# Check that patched functions can be disassembled (override FDE from the -# original function) +## Check that patched functions can be disassembled (override FDE from the +## original function) # PREAGG: B X:0 #foo.org.0# 1 0 RUN: link_fdata %s %t.out %t.preagg PREAGG RUN: perf2bolt %t.out -p %t.preagg --pa -o %t.yaml --profile-format=yaml \ @@ -19,13 +19,13 @@ RUN: -print-disasm -print-only=foo.org.0/1 2>&1 | FileCheck %s CHECK-NOT: BOLT-WARNING: sizes differ for function foo.org.0/1 CHECK: Binary Function "foo.org.0/1(*2)" after disassembly { -# Check the expected eh_frame contents +## Check the expected eh_frame contents RUN: llvm-nm --print-size %t.out > %t.foo RUN: llvm-objdump %t.out --dwarf=frames >> %t.foo RUN: FileCheck %s --input-file %t.foo --check-prefix=CHECK-FOO CHECK-FOO: 0000000000[[#%x,FOO:]] [[#%x,OPTSIZE:]] t foo CHECK-FOO: 0000000000[[#%x,ORG:]] [[#%x,ORGSIZE:]] t foo.org.0 -# patched FDE comes first +## patched FDE comes first CHECK-FOO: FDE {{.*}} pc=00[[#%x,ORG]]...00[[#%x,ORG+ORGSIZE]] -# original FDE comes second +## original FDE comes second CHECK-FOO: FDE {{.*}} pc=00[[#%x,ORG]]...00[[#%x,ORG+OPTSIZE]] diff --git a/bolt/test/X86/pre-aggregated-perf.test b/bolt/test/X86/pre-aggregated-perf.test index 0bd44720f1b7..90252f9ff68d 100644 --- a/bolt/test/X86/pre-aggregated-perf.test +++ b/bolt/test/X86/pre-aggregated-perf.test @@ -1,12 +1,12 @@ -# This script checks that perf2bolt is reading pre-aggregated perf information -# correctly for a simple example. The perf.data of this example was generated -# with the following command: -# -# $ perf record -j any,u -e branch -o perf.data -- ./blarge -# -# blarge is the binary for "basicmath large inputs" taken from Mibench. +## This script checks that perf2bolt is reading pre-aggregated perf information +## correctly for a simple example. The perf.data of this example was generated +## with the following command: +## +## $ perf record -j any,u -e branch -o perf.data -- ./blarge +## +## blarge is the binary for "basicmath large inputs" taken from Mibench. -# Currently failing in MacOS / generating different hash for usqrt +## Currently failing in MacOS / generating different hash for usqrt REQUIRES: system-linux RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe @@ -22,7 +22,7 @@ CHECK: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty exec RUN: cat %t | sort | FileCheck %s -check-prefix=PERF2BOLT RUN: cat %t.new | FileCheck %s -check-prefix=NEWFORMAT -# Test --profile-format option with perf2bolt +## Test --profile-format option with perf2bolt RUN: perf2bolt %t.exe -o %t.fdata --pa -p %p/Inputs/pre-aggregated.txt \ RUN: --profile-format=fdata RUN: cat %t.fdata | sort | FileCheck %s -check-prefix=PERF2BOLT @@ -31,7 +31,7 @@ RUN: perf2bolt %t.exe -o %t.yaml --pa -p %p/Inputs/pre-aggregated.txt \ RUN: --profile-format=yaml --profile-use-dfs RUN: cat %t.yaml | FileCheck %s -check-prefix=NEWFORMAT -# Test --profile-format option with llvm-bolt --aggregate-only +## Test --profile-format option with llvm-bolt --aggregate-only RUN: llvm-bolt %t.exe -o %t.bolt.fdata --pa -p %p/Inputs/pre-aggregated.txt \ RUN: --aggregate-only --profile-format=fdata RUN: cat %t.bolt.fdata | sort | FileCheck %s -check-prefix=PERF2BOLT diff --git a/bolt/test/X86/pt_gnu_relro.s b/bolt/test/X86/pt_gnu_relro.s index fa4af8287494..d7cfad5f954b 100644 --- a/bolt/test/X86/pt_gnu_relro.s +++ b/bolt/test/X86/pt_gnu_relro.s @@ -1,7 +1,7 @@ # REQUIRES: system-linux -# Check that BOLT recognizes PT_GNU_RELRO segment and marks respective sections -# accordingly. +## Check that BOLT recognizes PT_GNU_RELRO segment and marks respective sections +## accordingly. # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o # RUN: ld.lld %t.o -o %t.exe -q --no-relax diff --git a/bolt/test/X86/reader-stale-yaml-std.test b/bolt/test/X86/reader-stale-yaml-std.test index e0b6ca0645e1..b43442ca9ea9 100644 --- a/bolt/test/X86/reader-stale-yaml-std.test +++ b/bolt/test/X86/reader-stale-yaml-std.test @@ -1,19 +1,19 @@ -# This script checks that YamlProfileReader in llvm-bolt is reading data -# correctly and stale data is corrected by profile inference. +## This script checks that YamlProfileReader in llvm-bolt is reading data +## correctly and stale data is corrected by profile inference. RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null -b %p/Inputs/blarge_profile_stale.std-hash.yaml \ RUN: --print-cfg --print-only=usqrt,SolveCubic --infer-stale-profile=1 -v=1 \ RUN: 2>&1 | FileCheck %s -# Verify that yaml reader works as expected. +## Verify that yaml reader works as expected. CHECK: pre-processing profile using YAML profile reader CHECK: BOLT-INFO: YAML profile with hash: std::hash -# Function "SolveCubic" has stale profile, since there is one jump in the -# profile (from bid=13 to bid=2) which is not in the CFG in the binary. The test -# verifies that the inference is able to match two blocks (bid=1 and bid=13) -# using "loose" hashes and then correctly propagate the counts. +## Function "SolveCubic" has stale profile, since there is one jump in the +## profile (from bid=13 to bid=2) which is not in the CFG in the binary. The test +## verifies that the inference is able to match two blocks (bid=1 and bid=13) +## using "loose" hashes and then correctly propagate the counts. CHECK: Binary Function "SolveCubic" after building cfg { CHECK: State : CFG constructed @@ -25,7 +25,7 @@ CHECK: BB Count : 18 CHECK: Exec Count : 151 CHECK: Branch Count: 552 CHECK: } -# Verify block counts. +## Verify block counts. CHECK: .LBB00 (43 instructions, align : 1) CHECK: Successors: .Ltmp[[#BB07:]] (mispreds: 0, count: 0), .LFT[[#BB01:]] (mispreds: 0, count: 151) CHECK: .LFT[[#BB01:]] (5 instructions, align : 1) @@ -37,10 +37,10 @@ CHECK: .Ltmp[[#BB013:]] (12 instructions, align : 1) CHECK: Successors: .Ltmp[[#BB03:]] (mispreds: 0, count: 151) CHECK: End of Function "SolveCubic" -# Function "usqrt" has stale profile, since the number of blocks in the profile -# (nblocks=6) does not match the size of the CFG in the binary. The entry -# block (bid=0) has an incorrect (missing) count, which should be inferred by -# the algorithm. +## Function "usqrt" has stale profile, since the number of blocks in the profile +## (nblocks=6) does not match the size of the CFG in the binary. The entry +## block (bid=0) has an incorrect (missing) count, which should be inferred by +# #the algorithm. CHECK: Binary Function "usqrt" after building cfg { CHECK: State : CFG constructed @@ -52,7 +52,7 @@ CHECK: BB Count : 5 CHECK: Exec Count : 20 CHECK: Branch Count: 640 CHECK: } -# Verify block counts. +## Verify block counts. CHECK: .LBB01 (4 instructions, align : 1) CHECK: Successors: .Ltmp[[#BB113:]] (mispreds: 0, count: 20) CHECK: .Ltmp[[#BB113:]] (9 instructions, align : 1) @@ -63,6 +63,6 @@ CHECK: .Ltmp[[#BB112:]] (2 instructions, align : 1) CHECK: Successors: .Ltmp[[#BB113:]] (mispreds: 0, count: 300), .LFT[[#BB11:]] (mispreds: 0, count: 20) CHECK: .LFT[[#BB11:]] (2 instructions, align : 1) CHECK: End of Function "usqrt" -# Check the overall inference stats. +## Check the overall inference stats. CHECK: 2 out of 7 functions in the binary (28.6%) have non-empty execution profile CHECK: inferred profile for 2 (100.00% of profiled, 100.00% of stale) functions responsible for {{.*}} samples ({{.*}} out of {{.*}}) diff --git a/bolt/test/X86/reader-stale-yaml.test b/bolt/test/X86/reader-stale-yaml.test index f4a8865b1f9a..378abc382524 100644 --- a/bolt/test/X86/reader-stale-yaml.test +++ b/bolt/test/X86/reader-stale-yaml.test @@ -1,20 +1,20 @@ -# This script checks that YamlProfileReader in llvm-bolt is reading data -# correctly and stale data is corrected by profile inference. +## This script checks that YamlProfileReader in llvm-bolt is reading data +## correctly and stale data is corrected by profile inference. REQUIRES: asserts RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ RUN: --infer-stale-profile=0 --profile-ignore-hash=1 --profile-use-dfs=0 \ RUN: 2>&1 | FileCheck %s -check-prefix=CHECK0 -# Testing "usqrt" +## Testing "usqrt" RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 \ RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK1 -# Testing "SolveCubic" +## Testing "SolveCubic" RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ RUN: --print-cfg --print-only=SolveCubic --infer-stale-profile=1 \ RUN: --profile-ignore-hash=1 --profile-use-dfs=0 --debug-only=bolt-prof 2>&1 | FileCheck %s -check-prefix=CHECK2 -# Testing skipped function +## Testing skipped function RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale.yaml \ RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 --skip-funcs=usqrt \ RUN: --profile-ignore-hash=1 --profile-use-dfs=0 @@ -23,12 +23,12 @@ CHECK0: BOLT-INFO: 2 out of 7 functions in the binary (28.6%) have non-empty exe CHECK0: BOLT-WARNING: 2 (100.0% of all profiled) functions have invalid (possibly stale) profile CHECK0: BOLT-WARNING: 1192 out of 1192 samples in the binary (100.0%) belong to functions with invalid (possibly stale) profile -# Function "usqrt" has stale profile, since the number of blocks in the profile -# (nblocks=6) does not match the size of the CFG in the binary. The entry -# block (bid=0) has an incorrect (missing) count, which should be inferred by -# the algorithm. +## Function "usqrt" has stale profile, since the number of blocks in the profile +## (nblocks=6) does not match the size of the CFG in the binary. The entry +## block (bid=0) has an incorrect (missing) count, which should be inferred by +## the algorithm. -# Verify inference details. +## Verify inference details. CHECK1: pre-processing profile using YAML profile reader CHECK1: applying profile inference for "usqrt" CHECK1: Matched yaml block (bid = 0) with hash 1111111111111111 to BB (index = 0) with hash 36007ba1d80c0000 @@ -38,7 +38,7 @@ CHECK1-NEXT: exact match CHECK1: Matched yaml block (bid = 3) with hash 5c06705524800039 to BB (index = 3) with hash 5c06705524800039 CHECK1-NEXT: exact match -# Verify that yaml reader works as expected. +## Verify that yaml reader works as expected. CHECK1: Binary Function "usqrt" after building cfg { CHECK1: State : CFG constructed CHECK1: Address : 0x401170 @@ -50,7 +50,7 @@ CHECK1: Exec Count : 20 CHECK1: Branch Count: 640 CHECK1: } -# Verify block counts. +## Verify block counts. CHECK1: .LBB01 (4 instructions, align : 1) CHECK1: Successors: .Ltmp[[#BB13:]] (mispreds: 0, count: 20) CHECK1: .Ltmp[[#BB13:]] (9 instructions, align : 1) @@ -60,19 +60,19 @@ CHECK1: Successors: .Ltmp[[#BB12:]] (mispreds: 0, count: 0) CHECK1: .Ltmp[[#BB12:]] (2 instructions, align : 1) CHECK1: Successors: .Ltmp[[#BB13:]] (mispreds: 0, count: 300), .LFT[[#BB1:]] (mispreds: 0, count: 20) CHECK1: .LFT[[#BB1:]] (2 instructions, align : 1) -# Check the overall inference stats. +## Check the overall inference stats. CHECK1: 2 out of 7 functions in the binary (28.6%) have non-empty execution profile CHECK1: BOLT-WARNING: 2 (100.0% of all profiled) functions have invalid (possibly stale) profile CHECK1: BOLT-WARNING: 1192 out of 1192 samples in the binary (100.0%) belong to functions with invalid (possibly stale) profile CHECK1: inferred profile for 2 (100.00% of profiled, 100.00% of stale) functions responsible for {{.*}} samples ({{.*}} out of {{.*}}) -# Function "SolveCubic" has stale profile, since there is one jump in the -# profile (from bid=13 to bid=2) which is not in the CFG in the binary. The test -# verifies that the inference is able to match two blocks (bid=1 and bid=13) -# using "loose" hashes and then correctly propagate the counts. +## Function "SolveCubic" has stale profile, since there is one jump in the +## profile (from bid=13 to bid=2) which is not in the CFG in the binary. The test +## verifies that the inference is able to match two blocks (bid=1 and bid=13) +## using "loose" hashes and then correctly propagate the counts. -# Verify inference details. +## Verify inference details. CHECK2: pre-processing profile using YAML profile reader CHECK2: applying profile inference for "SolveCubic" CHECK2: Matched yaml block (bid = 0) with hash 4600940a609c0000 to BB (index = 0) with hash 4600940a609c0000 @@ -86,7 +86,7 @@ CHECK2-NEXT: loose match CHECK2: Matched yaml block (bid = 5) with hash 6446e1ea500111 to BB (index = 5) with hash 6446e1ea500111 CHECK2-NEXT: exact match -# Verify that yaml reader works as expected. +## Verify that yaml reader works as expected. CHECK2: Binary Function "SolveCubic" after building cfg { CHECK2: State : CFG constructed CHECK2: Address : 0x400e00 @@ -97,7 +97,7 @@ CHECK2: BB Count : 18 CHECK2: Exec Count : 151 CHECK2: Branch Count: 552 -# Verify block counts. +## Verify block counts. CHECK2: .LBB00 (43 instructions, align : 1) CHECK2: Successors: .Ltmp[[#BB7:]] (mispreds: 0, count: 0), .LFT[[#BB1:]] (mispreds: 0, count: 151) CHECK2: .LFT[[#BB1:]] (5 instructions, align : 1) diff --git a/bolt/test/X86/reader.test b/bolt/test/X86/reader.test index 308b97e30bb5..4d5d7bc818dd 100644 --- a/bolt/test/X86/reader.test +++ b/bolt/test/X86/reader.test @@ -1,4 +1,4 @@ -# This script checks that DataReader in llvm-bolt is reading data correctly +## This script checks that DataReader in llvm-bolt is reading data correctly RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: llvm-bolt %t.exe -o %t.null --data %p/Inputs/blarge.fdata --dump-data \ diff --git a/bolt/test/X86/register-fragments-bolt-symbols.s b/bolt/test/X86/register-fragments-bolt-symbols.s index 90c402b2234d..5c9fb5ed1a75 100644 --- a/bolt/test/X86/register-fragments-bolt-symbols.s +++ b/bolt/test/X86/register-fragments-bolt-symbols.s @@ -1,10 +1,22 @@ -# Test the heuristics for matching BOLT-added split functions. +## Test the heuristics for matching BOLT-added split functions. # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %S/cdsplit-symbol-names.s -o %t.main.o # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.chain.o # RUN: link_fdata %S/cdsplit-symbol-names.s %t.main.o %t.fdata -# RUN: sed -i 's|chain|chain/2|g' %t.fdata # RUN: llvm-strip --strip-unneeded %t.main.o + +## Check warm fragment name matching (produced by cdsplit) +# RUN: %clang %cflags %t.main.o -o %t.warm.exe -Wl,-q +# RUN: llvm-bolt %t.warm.exe -o %t.warm.bolt --split-functions --split-strategy=cdsplit \ +# RUN: --call-scale=2 --data=%t.fdata --reorder-blocks=ext-tsp --enable-bat +# RUN: link_fdata %s %t.warm.bolt %t.preagg.warm PREAGGWARM +# PREAGGWARM: B X:0 #chain.warm# 1 0 +# RUN: perf2bolt %t.warm.bolt -p %t.preagg.warm --pa -o %t.warm.fdata -w %t.warm.yaml \ +# RUN: -v=1 | FileCheck %s --check-prefix=CHECK-BOLT-WARM + +# CHECK-BOLT-WARM: marking chain.warm/1(*2) as a fragment of chain + +# RUN: sed -i 's|chain|chain/2|g' %t.fdata # RUN: llvm-objcopy --localize-symbol=chain %t.main.o # RUN: %clang %cflags %t.chain.o %t.main.o -o %t.exe -Wl,-q # RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=randomN \ diff --git a/bolt/test/X86/relaxed-tailcall.test b/bolt/test/X86/relaxed-tailcall.test index d303c4255ae7..c2f7a71b9e3e 100644 --- a/bolt/test/X86/relaxed-tailcall.test +++ b/bolt/test/X86/relaxed-tailcall.test @@ -1,4 +1,4 @@ -# Check that tail calls can be 2 bytes in the output binary. +## Check that tail calls can be 2 bytes in the output binary. RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-unknown -o %t.o \ RUN: %S/Inputs/relaxed_tc.s diff --git a/bolt/test/X86/remove-unused.test b/bolt/test/X86/remove-unused.test index 45e9f428e91d..83223ace26b7 100644 --- a/bolt/test/X86/remove-unused.test +++ b/bolt/test/X86/remove-unused.test @@ -1,5 +1,5 @@ -# Verifies that llvm-bolt is able to remove dead basic blocks. Also check that -# the BB reordering ignores dead BBs. +## Verifies that llvm-bolt is able to remove dead basic blocks. Also check that +## the BB reordering ignores dead BBs. RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %S/Inputs/entry.s -o %t.o RUN: link_fdata %S/Inputs/entry.s %t.o %t.fdata --nmtool llvm-nm @@ -9,5 +9,5 @@ RUN: llvm-bolt %t.exe --data %t.fdata -o %t --funcs=_start \ RUN: --eliminate-unreachable --reorder-blocks=none \ RUN: --print-finalized --sequential-disassembly 2>&1 | FileCheck %s -# Optimized +## Optimized CHECK: BB Layout : .LBB00, .Ltmp0, .Ltmp2, .Ltmp3, .Ltmp4, .Ltmp5, .Ltmp6, .Ltmp7, .Ltmp8, .Ltmp9, .Ltmp10, .Ltmp11 diff --git a/bolt/test/X86/rodata-simpl-loads.test b/bolt/test/X86/rodata-simpl-loads.test index 8018ad75e5d6..4617331fb761 100644 --- a/bolt/test/X86/rodata-simpl-loads.test +++ b/bolt/test/X86/rodata-simpl-loads.test @@ -1,4 +1,4 @@ -# Check for the simplification of .rodata loads. +## Check for the simplification of .rodata loads. RUN: %clang %cflags %p/Inputs/rodata_simpl_loads.s -o %t.exe RUN: llvm-bolt %t.exe -o %t --simplify-rodata-loads @@ -7,8 +7,8 @@ RUN: llvm-objdump -d %t --print-imm-hex --disassemble-symbols=main | FileCheck % CHECK: Disassembly of section .text: CHECK:
: -# check that the following rip-relative operands have been -# replaced with immediates +## check that the following rip-relative operands have been +## replaced with immediates ORIGINAL: movzbl s1(%rip), %eax CHECK: movl $0x41, %eax diff --git a/bolt/test/X86/sctc-bug.test b/bolt/test/X86/sctc-bug.test index 1b581df23749..fb3aff8529f8 100644 --- a/bolt/test/X86/sctc-bug.test +++ b/bolt/test/X86/sctc-bug.test @@ -1,4 +1,4 @@ -# Check that we don't accidentally optimize out a tail call. +## Check that we don't accidentally optimize out a tail call. RUN: %clang %cflags %S/Inputs/sctc_bug.s -o %t RUN: llvm-bolt %t -o %t.null --funcs=main --print-after-lowering \ diff --git a/bolt/test/X86/sctc-bug2.test b/bolt/test/X86/sctc-bug2.test index 0e235564dc3b..8b2f58f62507 100644 --- a/bolt/test/X86/sctc-bug2.test +++ b/bolt/test/X86/sctc-bug2.test @@ -1,4 +1,4 @@ -# Check that conditional tail call is not treated as a regular tail call by SCTC. +## Check that conditional tail call is not treated as a regular tail call by SCTC. RUN: %clang %cflags %S/Inputs/sctc_bug2.s -o %t RUN: llvm-bolt %t -o %t.null --funcs=main --print-after-lowering \ diff --git a/bolt/test/X86/sctc-bug3.test b/bolt/test/X86/sctc-bug3.test index 69c8c4542844..d821389a459f 100644 --- a/bolt/test/X86/sctc-bug3.test +++ b/bolt/test/X86/sctc-bug3.test @@ -1,4 +1,4 @@ -# Check that we don't accidentally optimize out a tail call. +## Check that we don't accidentally optimize out a tail call. RUN: %clang %cflags %S/Inputs/sctc_bug3.s -o %t RUN: llvm-bolt %t -o %t.null --funcs=main --print-after-lowering \ @@ -7,9 +7,9 @@ RUN: --sequential-disassembly 2>&1 | FileCheck %s CHECK: .LBB00 (1 instructions, align : 1) CHECK: cmpq %rdi, 0x0 -# Check that .Ltmp0 does not have a deleted predecessor. +## Check that .Ltmp0 does not have a deleted predecessor. CHECK: .Ltmp0 (1 instructions, align : 1) CHECK: Predecessors: .LBB00 -# Tail call. +## Tail call. CHECK: jmp foo diff --git a/bolt/test/X86/sctc-bug4.test b/bolt/test/X86/sctc-bug4.test index 92aca5110059..21a602b6729a 100644 --- a/bolt/test/X86/sctc-bug4.test +++ b/bolt/test/X86/sctc-bug4.test @@ -1,5 +1,5 @@ -# Check that fallthrough blocks are handled properly and Offset annotation is -# set for conditional tail calls. +## Check that fallthrough blocks are handled properly and Offset annotation is +## set for conditional tail calls. RUN: %clang %cflags %S/Inputs/sctc_bug4.s -o %t RUN: llvm-bolt %t -o %t.null --enable-bat \ diff --git a/bolt/test/X86/shared_object_entry.s b/bolt/test/X86/shared_object_entry.s index eeefbd8ee4e6..87a3c0655533 100644 --- a/bolt/test/X86/shared_object_entry.s +++ b/bolt/test/X86/shared_object_entry.s @@ -4,7 +4,7 @@ # RUN: -split-functions -reorder-blocks=ext-tsp -split-all-cold \ # RUN: -dyno-stats -icf=1 -use-gnu-stack -# Check that an entry point is a cold symbol +## Check that an entry point is a cold symbol # RUN: llvm-readelf -h %t.so > %t.log # RUN: llvm-nm %t.so >> %t.log # RUN: FileCheck %s --input-file %t.log diff --git a/bolt/test/X86/shorten-mov.test b/bolt/test/X86/shorten-mov.test index db911ad0c0eb..dfe21ef967ef 100644 --- a/bolt/test/X86/shorten-mov.test +++ b/bolt/test/X86/shorten-mov.test @@ -1,5 +1,5 @@ -# Test that 64 bit movq instructions with immediate operands -# that fit in 32 bits are shortened. +## Test that 64 bit movq instructions with immediate operands +## that fit in 32 bits are shortened. RUN: %clang %cflags %p/Inputs/asm_main.c %p/Inputs/shorten_mov.s -o %t.exe RUN: llvm-bolt %t.exe -o %t diff --git a/bolt/test/X86/shrinkwrapping-and-rsp.s b/bolt/test/X86/shrinkwrapping-and-rsp.s index 2e5918e857e6..cbc2953d5db0 100644 --- a/bolt/test/X86/shrinkwrapping-and-rsp.s +++ b/bolt/test/X86/shrinkwrapping-and-rsp.s @@ -1,5 +1,5 @@ -# This checks that shrink wrapping does attempt at accessing stack elements -# using RSP when the function is aligning RSP and changing offsets. +## This checks that shrink wrapping does attempt at accessing stack elements +## using RSP when the function is aligning RSP and changing offsets. # REQUIRES: system-linux @@ -12,10 +12,10 @@ # RUN: --frame-opt=all --simplify-conditional-tail-calls=false \ # RUN: --eliminate-unreachable=false | FileCheck %s -# Here we have a function that aligns the stack at prologue. Stack pointer -# analysis can't try to infer offset positions after AND because that depends -# on the runtime value of the stack pointer of callee (whether it is misaligned -# or not). +## Here we have a function that aligns the stack at prologue. Stack pointer +## analysis can't try to infer offset positions after AND because that depends +## on the runtime value of the stack pointer of callee (whether it is misaligned +## or not). .globl _start .type _start, %function _start: diff --git a/bolt/test/X86/shrinkwrapping-critedge.s b/bolt/test/X86/shrinkwrapping-critedge.s index ed9a206dec41..6b5213ba1985 100644 --- a/bolt/test/X86/shrinkwrapping-critedge.s +++ b/bolt/test/X86/shrinkwrapping-critedge.s @@ -1,5 +1,5 @@ -# This reproduces a bug with shrink wrapping when trying to split critical -# edges originating at the same basic block. +## This reproduces a bug with shrink wrapping when trying to split critical +## edges originating at the same basic block. # REQUIRES: system-linux diff --git a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s index 3fdd5f5e38fe..343dd89f75fc 100644 --- a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s +++ b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s @@ -1,10 +1,10 @@ -# This checks that shrink wrapping does not pessimize a CFG pattern where two -# blocks can be proved to have the same execution count but, because of profile -# inaccuricies, we could move saves into the second block. We can prove two -# blocks have the same frequency when B post-dominate A and A dominates B and -# are at the same loop nesting level. This would be a pessimization because -# shrink wrapping is unlikely to be able to cleanly move PUSH instructions, -# inserting additional store instructions. +## This checks that shrink wrapping does not pessimize a CFG pattern where two +## blocks can be proved to have the same execution count but, because of profile +## inaccuricies, we could move saves into the second block. We can prove two +## blocks have the same frequency when B post-dominate A and A dominates B and +## are at the same loop nesting level. This would be a pessimization because +## shrink wrapping is unlikely to be able to cleanly move PUSH instructions, +## inserting additional store instructions. # REQUIRES: system-linux @@ -16,15 +16,15 @@ # RUN: llvm-bolt -relocs %t.exe -o %t.out -data %t.fdata \ # RUN: -frame-opt=all -equalize-bb-counts | FileCheck %s -# Here we create a CFG pattern with two blocks A and B belonging to the same -# equivalency class as defined by dominance relations and having in theory -# the same frequency. But we tweak edge counts from profile to make block A -# hotter than block B. +## Here we create a CFG pattern with two blocks A and B belonging to the same +## equivalency class as defined by dominance relations and having in theory +## the same frequency. But we tweak edge counts from profile to make block A +## hotter than block B. .globl _start .type _start, %function _start: .cfi_startproc -# Hot prologue +## Hot prologue # FDATA: 0 [unknown] 0 1 _start 0 0 10 push %rbp mov %rsp, %rbp @@ -36,7 +36,7 @@ b: je end_if_1 if_false: movq rel(%rip), %rdi # Add this to create a relocation and run bolt w/ relocs c: jmp end_if_1 -# Reduce frequency from 9 to 1 to simulate an inaccurate profile +## Reduce frequency from 9 to 1 to simulate an inaccurate profile # FDATA: 1 _start #c# 1 _start #end_if_1# 0 1 end_if_1: # first uses of R14 and RBX appear at this point, possible move point for SW diff --git a/bolt/test/X86/shrinkwrapping-insertcfi.s b/bolt/test/X86/shrinkwrapping-insertcfi.s index 57b43cf4b662..b3813ad86b46 100644 --- a/bolt/test/X86/shrinkwrapping-insertcfi.s +++ b/bolt/test/X86/shrinkwrapping-insertcfi.s @@ -1,5 +1,5 @@ -# This test reproduces the issue with inserting updated CFI in shrink wrapping -# into the first basic block. +## This test reproduces the issue with inserting updated CFI in shrink wrapping +## into the first basic block. # REQUIRES: system-linux @@ -10,10 +10,10 @@ # RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --frame-opt=all --lite=0 \ # RUN: --print-fop 2>&1 | FileCheck %s -# Check shrink wrapping results: +## Check shrink wrapping results: # CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 1 spills inserting push/pops -# Check that CFI is successfully inserted into the first basic block: +## Check that CFI is successfully inserted into the first basic block: # CHECK: Binary Function "_start" after frame-optimizer # CHECK: .LBB00 (2 instructions, align : 1) # CHECK-NEXT: Entry Point @@ -34,8 +34,8 @@ c: .cfi_offset 3, 4 pop %rbx -# This basic block is treated as having 0 execution count. -# push and pop will be sinked into this block. +## This basic block is treated as having 0 execution count. +## push and pop will be sinked into this block. a: ud2 .cfi_endproc diff --git a/bolt/test/X86/shrinkwrapping-lea.s b/bolt/test/X86/shrinkwrapping-lea.s index db31696ebd6d..c4860826bea5 100644 --- a/bolt/test/X86/shrinkwrapping-lea.s +++ b/bolt/test/X86/shrinkwrapping-lea.s @@ -1,5 +1,5 @@ -# This checks that shrink wrapping correctly drops moving push/pops when -# there is an LEA instruction. +## This checks that shrink wrapping correctly drops moving push/pops when +## there is an LEA instruction. # REQUIRES: system-linux @@ -58,7 +58,7 @@ JT: # CHECK: BOLT-INFO: Shrink wrapping moved 2 spills inserting load/stores and 0 spills inserting push/pops -# Checks that offsets of instructions accessing the stack were not changed +## Checks that offsets of instructions accessing the stack were not changed # CHECK-OBJDUMP: <_start>: # CHECK-OBJDUMP: movq %rbx, %rdi # CHECK-OBJDUMP-NEXT: leaq -0x20(%rbp), %r14 diff --git a/bolt/test/X86/shrinkwrapping-mov.s b/bolt/test/X86/shrinkwrapping-mov.s index 4a81b369c976..c6e5aed34419 100644 --- a/bolt/test/X86/shrinkwrapping-mov.s +++ b/bolt/test/X86/shrinkwrapping-mov.s @@ -1,6 +1,6 @@ -# This checks that shrink wrapping correctly drops moving push/pops when -# there is a MOV instruction loading the value of the stack pointer in -# order to do pointer arithmetic with a stack address. +## This checks that shrink wrapping correctly drops moving push/pops when +## there is a MOV instruction loading the value of the stack pointer in +## order to do pointer arithmetic with a stack address. # REQUIRES: system-linux diff --git a/bolt/test/X86/shrinkwrapping-pop-order.s b/bolt/test/X86/shrinkwrapping-pop-order.s index 2a5db3685e52..abad44e61800 100644 --- a/bolt/test/X86/shrinkwrapping-pop-order.s +++ b/bolt/test/X86/shrinkwrapping-pop-order.s @@ -1,6 +1,6 @@ -# This test reproduces a POP reordering issue in shrink wrapping where we would -# incorrectly put a store after a load (instead of before) when having multiple -# insertions at the same point. Check that the order is correct in this test. +## This test reproduces a POP reordering issue in shrink wrapping where we would +## incorrectly put a store after a load (instead of before) when having multiple +## insertions at the same point. Check that the order is correct in this test. # REQUIRES: system-linux @@ -25,23 +25,23 @@ c: pop %rbp pop %rbx -# This basic block is treated as having 0 execution count. -# push and pop will be sinked into this block. +## This basic block is treated as having 0 execution count. +## push and pop will be sinked into this block. a: ud2 .cfi_endproc -# Check shrink wrapping results: +## Check shrink wrapping results: # CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 2 spills inserting push/pops # CHECK: BOLT-INFO: Shrink wrapping reduced 6 store executions (28.6% total instructions executed, 100.0% store instructions) # CHECK: BOLT-INFO: Shrink wrapping failed at reducing 0 store executions (0.0% total instructions executed, 0.0% store instructions) -# Check that order is correct +## Check that order is correct # CHECK: Binary Function "_start" after frame-optimizer # Pushes are ordered according to their reg number and come first # CHECK: pushq %rbp # CHECK: pushq %rbx -# Pops are ordered according to their dominance relation and come last +## Pops are ordered according to their dominance relation and come last # CHECK: popq %rbx # CHECK: popq %rbp diff --git a/bolt/test/X86/shrinkwrapping-popf.s b/bolt/test/X86/shrinkwrapping-popf.s index 9e1dcd54a617..a21ea99c37ef 100644 --- a/bolt/test/X86/shrinkwrapping-popf.s +++ b/bolt/test/X86/shrinkwrapping-popf.s @@ -1,4 +1,4 @@ -# This test checks that POPF will not crash our frame analysis pass +## This test checks that POPF will not crash our frame analysis pass # REQUIRES: system-linux @@ -26,7 +26,7 @@ c: pop %rbx popf -# This basic block is treated as having 0 execution count. +## This basic block is treated as having 0 execution count. a: ud2 .cfi_endproc diff --git a/bolt/test/X86/shrinkwrapping-restore-position.s b/bolt/test/X86/shrinkwrapping-restore-position.s index 576fa8fcc394..1d26b6e48e6f 100644 --- a/bolt/test/X86/shrinkwrapping-restore-position.s +++ b/bolt/test/X86/shrinkwrapping-restore-position.s @@ -1,5 +1,5 @@ -# This checks that shrink wrapping uses the red zone defined in the X86 ABI by -# placing restores that access elements already deallocated by the stack. +## This checks that shrink wrapping uses the red zone defined in the X86 ABI by +## placing restores that access elements already deallocated by the stack. # REQUIRES: system-linux @@ -16,10 +16,10 @@ # RUN: FileCheck --check-prefix CHECK-OBJDUMP %s -# Here we create a CFG where the restore position matches the previous (deleted) -# restore position. Shrink wrapping then will put a stack access to an element -# that was deallocated at the previously deleted POP, which falls in the red -# zone and should be safe for X86 Linux ABI. +## Here we create a CFG where the restore position matches the previous (deleted) +## restore position. Shrink wrapping then will put a stack access to an element +## that was deallocated at the previously deleted POP, which falls in the red +## zone and should be safe for X86 Linux ABI. .globl _start .type _start, %function _start: diff --git a/bolt/test/X86/shrinkwrapping.test b/bolt/test/X86/shrinkwrapping.test index 1767db2978d1..8581d7e0c0f7 100644 --- a/bolt/test/X86/shrinkwrapping.test +++ b/bolt/test/X86/shrinkwrapping.test @@ -1,9 +1,9 @@ -# Verifies that llvm-bolt updates CFI correctly after -# shrink-wrapping when optimizing a function without -# frame pointers. +## Verifies that llvm-bolt updates CFI correctly after +## shrink-wrapping when optimizing a function without +## frame pointers. -# This test has commands that rely on shell capabilities that won't execute -# correctly on Windows e.g. subshell execution to capture command output. +## This test has commands that rely on shell capabilities that won't execute +## correctly on Windows e.g. subshell execution to capture command output. REQUIRES: shell RUN: %clangxx %cxxflags -no-pie %S/Inputs/exc4sw.S -o %t.exe -Wl,-q diff --git a/bolt/test/X86/split-all-lptrampoline.s b/bolt/test/X86/split-all-lptrampoline.s index 4629a2cf9b95..df50a7fbe030 100644 --- a/bolt/test/X86/split-all-lptrampoline.s +++ b/bolt/test/X86/split-all-lptrampoline.s @@ -1,6 +1,6 @@ -# This test checks that trampolines are inserted in split fragments if -# necessary. There are 4 LSDA ranges with a landing pad to three landing pads. -# After splitting all blocks, there have to be 4 trampolines in the output. +## This test checks that trampolines are inserted in split fragments if +## necessary. There are 4 LSDA ranges with a landing pad to three landing pads. +## After splitting all blocks, there have to be 4 trampolines in the output. # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: %clangxx %cxxflags %t.o -o %t.exe -Wl,-q -pie diff --git a/bolt/test/X86/split-all.s b/bolt/test/X86/split-all.s index 1f51ba2e375e..0b21e1b2b535 100644 --- a/bolt/test/X86/split-all.s +++ b/bolt/test/X86/split-all.s @@ -1,4 +1,4 @@ -# Test split all block strategy +## Test split all block strategy # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q diff --git a/bolt/test/X86/split-func-icf.s b/bolt/test/X86/split-func-icf.s index 259c30186400..a87c52cccb0f 100644 --- a/bolt/test/X86/split-func-icf.s +++ b/bolt/test/X86/split-func-icf.s @@ -1,7 +1,7 @@ -# This reproduces an issue where two cold fragments are folded into one, so the -# fragment has two parents. -# The fragment is only reachable through a jump table, so all functions must be -# ignored. +## This reproduces an issue where two cold fragments are folded into one, so the +## fragment has two parents. +## The fragment is only reachable through a jump table, so all functions must be +## ignored. # REQUIRES: system-linux @@ -27,10 +27,10 @@ main: LBB0: andl $0xf, %ecx cmpb $0x4, %cl - # exit through ret + ## exit through ret ja LBB3 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: leaq JUMP_TABLE1(%rip), %r8 movzbl %cl, %ecx @@ -55,7 +55,7 @@ LBB20: # exit through ret ja LBB23 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB21: leaq JUMP_TABLE2(%rip), %r8 movzbl %cl, %ecx @@ -70,7 +70,7 @@ LBB23: ret .size main2, .-main2 -# cold fragment is only reachable through jump table +## cold fragment is only reachable through jump table .globl main2.cold.1 .type main2.cold.1, %function main2.cold.1: @@ -78,15 +78,15 @@ main2.cold.1: .type main.cold.1, %function .p2align 2 main.cold.1: - # load bearing nop: pad LBB4 so that it can't be treated - # as __builtin_unreachable by analyzeJumpTable + ## load bearing nop: pad LBB4 so that it can't be treated + ## as __builtin_unreachable by analyzeJumpTable nop LBB4: callq abort .size main.cold.1, .-main.cold.1 .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE1 JUMP_TABLE1: .long LBB2-JUMP_TABLE1 diff --git a/bolt/test/X86/split-func-jump-table-fragment-bidirection.s b/bolt/test/X86/split-func-jump-table-fragment-bidirection.s index caebe59ed086..52c816ccd900 100644 --- a/bolt/test/X86/split-func-jump-table-fragment-bidirection.s +++ b/bolt/test/X86/split-func-jump-table-fragment-bidirection.s @@ -1,7 +1,7 @@ -# This reproduces an issue where two fragments of same function access same -# jump table, which means at least one fragment visits the other, i.e., one -# of them has split jump table. As a result, all of them will be marked as -# non-simple function. +## This reproduces an issue where two fragments of same function access same +## jump table, which means at least one fragment visits the other, i.e., one +## of them has split jump table. As a result, all of them will be marked as +## non-simple function. # REQUIRES: system-linux @@ -21,10 +21,10 @@ main: LBB0: andl $0xf, %ecx cmpb $0x4, %cl - # exit through ret + ## exit through ret ja LBB3 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: leaq JUMP_TABLE1(%rip), %r8 movzbl %cl, %ecx @@ -39,13 +39,13 @@ LBB3: ret .size main, .-main -# cold fragment is only reachable +## cold fragment is only reachable .globl main.cold.1 .type main.cold.1, %function .p2align 2 main.cold.1: - # load bearing nop: pad LBB8 so that it can't be treated - # as __builtin_unreachable by analyzeJumpTable + ## load bearing nop: pad LBB8 so that it can't be treated + ## as __builtin_unreachable by analyzeJumpTable nop LBB4: andl $0xb, %ebx @@ -53,7 +53,7 @@ LBB4: # exit through ret ja LBB7 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB5: leaq JUMP_TABLE1(%rip), %r8 movzbl %cl, %ecx @@ -71,7 +71,7 @@ LBB8: .size main.cold.1, .-main.cold.1 .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE1 JUMP_TABLE1: .long LBB2-JUMP_TABLE1 diff --git a/bolt/test/X86/split-func-jump-table-fragment-noparent.s b/bolt/test/X86/split-func-jump-table-fragment-noparent.s index a3ac643ee137..499dcaf4ced4 100644 --- a/bolt/test/X86/split-func-jump-table-fragment-noparent.s +++ b/bolt/test/X86/split-func-jump-table-fragment-noparent.s @@ -1,6 +1,6 @@ -# This reproduces a bug with jump table identification where jump table has -# entries pointing to code in function and its cold fragment. -# The fragment is only reachable through jump table. +## This reproduces a bug with jump table identification where jump table has +## entries pointing to code in function and its cold fragment. +## The fragment is only reachable through jump table. # REQUIRES: system-linux @@ -19,10 +19,10 @@ main: LBB0: andl $0xf, %ecx cmpb $0x4, %cl - # exit through ret + ## exit through ret ja LBB3 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: leaq JUMP_TABLE(%rip), %r8 movzbl %cl, %ecx @@ -37,20 +37,20 @@ LBB3: ret .size main, .-main -# cold fragment is only reachable through jump table +## cold fragment is only reachable through jump table .globl main.cold.1 .type main.cold.1, %function .p2align 2 main.cold.1: - # load bearing nop: pad LBB4 so that it can't be treated - # as __builtin_unreachable by analyzeJumpTable + ## load bearing nop: pad LBB4 so that it can't be treated + ## as __builtin_unreachable by analyzeJumpTable nop LBB4: callq abort .size main.cold.1, .-main.cold.1 .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE JUMP_TABLE: .long LBB2-JUMP_TABLE diff --git a/bolt/test/X86/split-func-jump-table-fragment-reverse.s b/bolt/test/X86/split-func-jump-table-fragment-reverse.s index 639c800a795b..634a45b3f2f1 100644 --- a/bolt/test/X86/split-func-jump-table-fragment-reverse.s +++ b/bolt/test/X86/split-func-jump-table-fragment-reverse.s @@ -1,6 +1,6 @@ -# This reproduces a bug with jump table identification where jump table has -# entries pointing to code in function and its cold fragment. -# The fragment is only reachable through jump table. +## This reproduces a bug with jump table identification where jump table has +## entries pointing to code in function and its cold fragment. +## The fragment is only reachable through jump table. # REQUIRES: system-linux @@ -26,10 +26,10 @@ main.cold: LBB0: andl $0xf, %ecx cmpb $0x4, %cl - # exit through ret + ## exit through ret ja LBB3 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: leaq JUMP_TABLE(%rip), %r8 movzbl %cl, %ecx @@ -44,20 +44,20 @@ LBB3: ret .size main.cold, .-main.cold -# main function, referenced from jump table in cold fragment +## main function, referenced from jump table in cold fragment .globl main .type main, %function .p2align 2 main: - # load bearing nop: pad LBB4 so that it can't be treated - # as __builtin_unreachable by analyzeJumpTable + ## load bearing nop: pad LBB4 so that it can't be treated + ## as __builtin_unreachable by analyzeJumpTable nop LBB4: callq abort .size main, .-main .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE JUMP_TABLE: .long LBB2-JUMP_TABLE diff --git a/bolt/test/X86/split-func-jump-table-fragment.s b/bolt/test/X86/split-func-jump-table-fragment.s index a92e6731dffe..12fe69110b26 100644 --- a/bolt/test/X86/split-func-jump-table-fragment.s +++ b/bolt/test/X86/split-func-jump-table-fragment.s @@ -19,10 +19,10 @@ main: LBB0: andl $0xf, %ecx cmpb $0x4, %cl - # exit through abort in main.cold.1, registers cold fragment the regular way + ## exit through abort in main.cold.1, registers cold fragment the regular way ja main.cold.1 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: leaq JUMP_TABLE(%rip), %r8 movzbl %cl, %ecx @@ -37,8 +37,8 @@ LBB3: ret .size main, .-main -# Insert padding between functions, so that the next instruction cannot be -# treated as __builtin_unreachable destination for the jump table. +## Insert padding between functions, so that the next instruction cannot be +## treated as __builtin_unreachable destination for the jump table. .quad 0 .globl main.cold.1 @@ -50,7 +50,7 @@ LBB4: .size main.cold.1, .-main.cold.1 .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE JUMP_TABLE: .long LBB2-JUMP_TABLE diff --git a/bolt/test/X86/split-func-jump-table-unknown.s b/bolt/test/X86/split-func-jump-table-unknown.s index 71a172bb5f4a..aae140418401 100644 --- a/bolt/test/X86/split-func-jump-table-unknown.s +++ b/bolt/test/X86/split-func-jump-table-unknown.s @@ -1,5 +1,5 @@ -# This reproduces a bug with converting an unknown control flow jump table with -# entries pointing to code in function and its cold fragment. +## This reproduces a bug with converting an unknown control flow jump table with +## entries pointing to code in function and its cold fragment. # REQUIRES: system-linux @@ -27,10 +27,10 @@ LBB0: leaq JUMP_TABLE(%rip), %r8 andl $0xf, %ecx cmpb $0x4, %cl - # exit through abort in main.cold.1, registers cold fragment the regular way + ## exit through abort in main.cold.1, registers cold fragment the regular way ja main.cold.1 -# jump table dispatch, jumping to label indexed by val in %ecx +## jump table dispatch, jumping to label indexed by val in %ecx LBB1: movzbl %cl, %ecx movslq (%r8,%rcx,4), %rax @@ -48,15 +48,15 @@ LBB3: .type main.cold.1, %function .p2align 2 main.cold.1: - # load bearing nop: pad LBB4 so that it can't be treated - # as __builtin_unreachable by analyzeJumpTable + ## load bearing nop: pad LBB4 so that it can't be treated + ## as __builtin_unreachable by analyzeJumpTable nop LBB4: callq abort .size main.cold.1, .-main.cold.1 .rodata -# jmp table, entries must be R_X86_64_PC32 relocs +## jmp table, entries must be R_X86_64_PC32 relocs .globl JUMP_TABLE JUMP_TABLE: .long LBB2-JUMP_TABLE diff --git a/bolt/test/X86/split-landing-pad.s b/bolt/test/X86/split-landing-pad.s index dda27891443f..681f14f1e533 100644 --- a/bolt/test/X86/split-landing-pad.s +++ b/bolt/test/X86/split-landing-pad.s @@ -1,25 +1,25 @@ -# This test reproduces the case where C++ exception handling is used and split -# function optimization is enabled. In particular, function foo is splitted -# to two fragments: -# foo: contains 2 try blocks, which invokes bar to throw exception -# foo.cold.1: contains 2 corresponding catch blocks (landing pad) -# -# Similar to split jump table, split landing pad target to different fragment. -# This test is written to ensure BOLT safely handle these targets, e.g., by -# marking them as non-simple. -# -# Steps to write this test: -# - Create a copy of Inputs/src/unreachable.cpp -# - Simplify bar(), focus on throw an exception -# - Create the second switch case in foo() to have multiple landing pads -# - Compile with clang++ to .s -# - Move landing pad code from foo to foo.cold.1 -# - Ensure that all landing pads can be reached normally -# -# Additional details: -# .gcc_except_table specify the landing pads for try blocks -# LPStart = 255 (omit), which means LPStart = foo start -# Landing pads .Ltmp2 and .Ltmp5 in call site record are offset to foo start. +## This test reproduces the case where C++ exception handling is used and split +## function optimization is enabled. In particular, function foo is splitted +## to two fragments: +## foo: contains 2 try blocks, which invokes bar to throw exception +## foo.cold.1: contains 2 corresponding catch blocks (landing pad) +## +## Similar to split jump table, split landing pad target to different fragment. +## This test is written to ensure BOLT safely handle these targets, e.g., by +## marking them as non-simple. +## +## Steps to write this test: +## - Create a copy of Inputs/src/unreachable.cpp +## - Simplify bar(), focus on throw an exception +## - Create the second switch case in foo() to have multiple landing pads +## - Compile with clang++ to .s +## - Move landing pad code from foo to foo.cold.1 +## - Ensure that all landing pads can be reached normally +## +## Additional details: +## .gcc_except_table specify the landing pads for try blocks +## LPStart = 255 (omit), which means LPStart = foo start +## Landing pads .Ltmp2 and .Ltmp5 in call site record are offset to foo start. # REQUIRES: system-linux diff --git a/bolt/test/X86/split-random.s b/bolt/test/X86/split-random.s index de9a4f108065..5bed619e82a9 100644 --- a/bolt/test/X86/split-random.s +++ b/bolt/test/X86/split-random.s @@ -1,4 +1,4 @@ -# Test random function splitting option +## Test random function splitting option # RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q diff --git a/bolt/test/X86/static-exe.test b/bolt/test/X86/static-exe.test index d12ac0a0f6f6..e288160da152 100644 --- a/bolt/test/X86/static-exe.test +++ b/bolt/test/X86/static-exe.test @@ -1,4 +1,4 @@ -# Check that llvm-bolt can rewrite static executable +## Check that llvm-bolt can rewrite static executable RUN: %clang %cflags %S/Inputs/static_exe.s -static -o %t.exe -nostdlib RUN: llvm-bolt %t.exe -o %t 2>&1 | FileCheck %s diff --git a/bolt/test/X86/symtab-secondary-entries.test b/bolt/test/X86/symtab-secondary-entries.test index 6e05129340a0..5291f64b1c46 100644 --- a/bolt/test/X86/symtab-secondary-entries.test +++ b/bolt/test/X86/symtab-secondary-entries.test @@ -1,4 +1,4 @@ -# Check that secondary entry points are updated correctly in the ELF symtab +## Check that secondary entry points are updated correctly in the ELF symtab RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ RUN: %p/Inputs/user-order.S -o %t.o @@ -13,7 +13,7 @@ CHECK: [[#]] FUNC GLOBAL DEFAULT [[#NDX]] main CHECK: [[#]] FUNC LOCAL DEFAULT [[#NDX]] _a CHECK: [[#]] FUNC GLOBAL DEFAULT [[#NDX]] _b CHECK: [[#]] FUNC GLOBAL DEFAULT [[#NDX]] _f -# The following are all secondary entries of _f +## The following are all secondary entries of _f CHECK: 0 FUNC GLOBAL DEFAULT [[#NDX]] _c CHECK: 0 FUNC GLOBAL DEFAULT [[#NDX]] _d CHECK: 0 FUNC GLOBAL DEFAULT [[#NDX]] _e diff --git a/bolt/test/X86/tail-duplication-cache.s b/bolt/test/X86/tail-duplication-cache.s index c3890c0337dd..8021cfacd543 100644 --- a/bolt/test/X86/tail-duplication-cache.s +++ b/bolt/test/X86/tail-duplication-cache.s @@ -11,7 +11,7 @@ # RUN: --print-finalized --tail-duplication=cache -o %t.out2 \ # RUN: | FileCheck --check-prefix="CHECK2" %s -# A test where the tail is duplicated to eliminate an unconditional jump +## A test where the tail is duplicated to eliminate an unconditional jump # FDATA: 1 main #.BB0_br# 1 main #.BB4# 0 100 # FDATA: 1 main #.BB0_br# 1 main #.BB1# 0 100 # FDATA: 1 main #.BB1_br# 1 main #.BB3# 0 50 @@ -20,7 +20,7 @@ # CHECK: BOLT-INFO: tail duplication modified 1 ({{.*}}%) functions; duplicated 1 blocks (13 bytes) responsible for 50 dynamic executions ({{.*}}% of all block executions) # CHECK: BB Layout : .LBB00, .Ltmp0, .Ltmp1, .Ltmp2, .Ltmp3, .Ltmp4, .Ltmp5, .Ltail-dup0, .Ltmp6 -# A test where the tail is not duplicated due to the cache score +## A test where the tail is not duplicated due to the cache score # FDATA2: 1 main #.BB0_br# 1 main #.BB4# 0 100 # FDATA2: 1 main #.BB0_br# 1 main #.BB1# 0 2 # FDATA2: 1 main #.BB1_br# 1 main #.BB3# 0 1 diff --git a/bolt/test/X86/tail-duplication-cacheline.s b/bolt/test/X86/tail-duplication-cacheline.s index acc49dc34834..de77dbcdae07 100644 --- a/bolt/test/X86/tail-duplication-cacheline.s +++ b/bolt/test/X86/tail-duplication-cacheline.s @@ -1,5 +1,5 @@ -# This reproduces a bug in TailDuplication::isInCacheLine -# with accessing BlockLayout past bounds (unreachable blocks). +## This reproduces a bug in TailDuplication::isInCacheLine +## with accessing BlockLayout past bounds (unreachable blocks). # REQUIRES: system-linux diff --git a/bolt/test/X86/tail-duplication-complex.s b/bolt/test/X86/tail-duplication-complex.s index ced59aea7a4c..71407da548b7 100644 --- a/bolt/test/X86/tail-duplication-complex.s +++ b/bolt/test/X86/tail-duplication-complex.s @@ -17,12 +17,12 @@ # CHECK: tail duplication modified 1 ({{.*}}%) functions; duplicated 1 blocks ({{.*}} bytes) responsible for {{.*}} dynamic executions ({{.*}} of all block executions) # CHECK: BB Layout : .LBB00, .Ltmp0, .Ltail-dup0, .Ltmp1, .Ltmp2 -# This is the C++ code fed to Clang -# int fib(int term) { -# if (term <= 1) -# return term; -# return fib(term-1) + fib(term-2); -# } +## This is the C++ code fed to Clang +## int fib(int term) { +## if (term <= 1) +## return term; +## return fib(term-1) + fib(term-2); +## } .text .globl main diff --git a/bolt/test/X86/tail-duplication-jt.s b/bolt/test/X86/tail-duplication-jt.s index 03211b399ba6..c050aa8ddb85 100644 --- a/bolt/test/X86/tail-duplication-jt.s +++ b/bolt/test/X86/tail-duplication-jt.s @@ -1,5 +1,5 @@ -# This reproduces a bug in tail duplication when aggressiveCodeToDuplicate -# fails to handle a block with a jump table. +## This reproduces a bug in tail duplication when aggressiveCodeToDuplicate +## fails to handle a block with a jump table. # REQUIRES: system-linux diff --git a/bolt/test/X86/tail-duplication-pass.s b/bolt/test/X86/tail-duplication-pass.s index ed50cc5227d8..9867f74fa344 100644 --- a/bolt/test/X86/tail-duplication-pass.s +++ b/bolt/test/X86/tail-duplication-pass.s @@ -16,7 +16,7 @@ # CHECK: BOLT-INFO: tail duplication modified 1 ({{.*}}%) functions; duplicated 1 blocks (1 bytes) responsible for {{.*}} dynamic executions ({{.*}}% of all block executions) # CHECK: BB Layout : .LBB00, .Ltail-dup0, .Ltmp0, .Ltmp1 -# Check that the successor of Ltail-dup0 is .LBB00, not itself. +## Check that the successor of Ltail-dup0 is .LBB00, not itself. # CHECK-NOLOOP: .Ltail-dup0 (1 instructions, align : 1) # CHECK-NOLOOP: Predecessors: .LBB00 # CHECK-NOLOOP: retq diff --git a/bolt/test/X86/tail-duplication-prop-bug.s b/bolt/test/X86/tail-duplication-prop-bug.s index 5e9efc87fa2f..431851d12190 100644 --- a/bolt/test/X86/tail-duplication-prop-bug.s +++ b/bolt/test/X86/tail-duplication-prop-bug.s @@ -1,4 +1,4 @@ -# This reproduces a bug in aggressive tail duplication/copy propagation. +## This reproduces a bug in aggressive tail duplication/copy propagation. # REQUIRES: system-linux # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o diff --git a/bolt/test/X86/tailcall-traps.test b/bolt/test/X86/tailcall-traps.test index 7ce6d61a738b..ab4fcf10f7a3 100644 --- a/bolt/test/X86/tailcall-traps.test +++ b/bolt/test/X86/tailcall-traps.test @@ -1,4 +1,4 @@ -# Tests the peephole that adds trap instructions following indirect tail calls. +## Tests the peephole that adds trap instructions following indirect tail calls. RUN: %clang %cflags %p/Inputs/tailcall_traps.s -o %t.exe RUN: llvm-bolt %t.exe -o %t --peepholes=tailcall-traps \ diff --git a/bolt/test/X86/tailcall.test b/bolt/test/X86/tailcall.test index 83b69bd25ab9..f00b04d255c0 100644 --- a/bolt/test/X86/tailcall.test +++ b/bolt/test/X86/tailcall.test @@ -1,5 +1,5 @@ -# Verifies that llvm-bolt recognizes tailcalls and mark them -# in control flow graph. +## Verifies that llvm-bolt recognizes tailcalls and mark them +## in control flow graph. RUN: %clang %cflags %S/Inputs/tailcall.s -o %t.exe RUN: llvm-bolt %t.exe -o %t.null --print-cfg 2>&1 | FileCheck %s diff --git a/bolt/test/X86/unclaimed-jt-entries.s b/bolt/test/X86/unclaimed-jt-entries.s index 454de7e1b30b..2d56167286c3 100644 --- a/bolt/test/X86/unclaimed-jt-entries.s +++ b/bolt/test/X86/unclaimed-jt-entries.s @@ -1,5 +1,5 @@ -# This test ensures that "unclaimed" jump table entries are accounted later -# in postProcessIndirectBranches and the function is marked as non-simple. +## This test ensures that "unclaimed" jump table entries are accounted later +## in postProcessIndirectBranches and the function is marked as non-simple. # The test is compiled from the following source using GCC 12.2 -O3: # https://godbolt.org/z/YcPG131s6 diff --git a/bolt/test/X86/unreachable-jmp.s b/bolt/test/X86/unreachable-jmp.s index 201e99990736..1a96f128e0f7 100644 --- a/bolt/test/X86/unreachable-jmp.s +++ b/bolt/test/X86/unreachable-jmp.s @@ -1,5 +1,5 @@ -# This checks that we don't create an invalid CFG when there is an -# unreachable direct jump right after an indirect one. +## This checks that we don't create an invalid CFG when there is an +## unreachable direct jump right after an indirect one. # REQUIRES: system-linux @@ -25,8 +25,8 @@ _start: b: jmpq *JUMP_TABLE(,%rcx,8) # FDATA: 1 _start #b# 1 _start #hotpath# 0 20 -# Unreachable direct jump here. Our CFG should still make sense and properly -# place this instruction in a new basic block. +## Unreachable direct jump here. Our CFG should still make sense and properly +## place this instruction in a new basic block. jmp .lbb2 .lbb1: je .lexit .lbb2: @@ -60,7 +60,7 @@ JUMP_TABLE: .quad .lbb2 .quad hotpath -# No basic blocks above should have 4 successors! That is a bug. +## No basic blocks above should have 4 successors! That is a bug. # CHECK-NOT: Successors: {{.*}} (mispreds: 0, count: 20), {{.*}} (mispreds: 0, count: 0), {{.*}} (mispreds: 0, count: 0), {{.*}} (mispreds: 0, count: 0) # Check successful removal of stray direct jmp # CHECK: UCE removed 1 block diff --git a/bolt/test/X86/unreachable.test b/bolt/test/X86/unreachable.test index 63b70813c885..3939b5cd338c 100644 --- a/bolt/test/X86/unreachable.test +++ b/bolt/test/X86/unreachable.test @@ -1,4 +1,4 @@ -# Check unreachable code elimination +## Check unreachable code elimination RUN: %clang %cflags %p/../Inputs/stub.c -fPIC -pie -shared -o %t.so RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ diff --git a/bolt/test/X86/vararg.test b/bolt/test/X86/vararg.test index 5df4f3da0421..0b8668a842ed 100644 --- a/bolt/test/X86/vararg.test +++ b/bolt/test/X86/vararg.test @@ -1,6 +1,6 @@ -# Check that a function that references a label inside itself, -# as in the case of vararg handling code generated by GCC 4.5 -# and earlier, is recognized as multi-entry. +## Check that a function that references a label inside itself, +## as in the case of vararg handling code generated by GCC 4.5 +## and earlier, is recognized as multi-entry. REQUIRES: x86_64-linux diff --git a/bolt/test/X86/yaml-multiple-profiles.test b/bolt/test/X86/yaml-multiple-profiles.test index 5684da4226be..6d0a26823fe5 100644 --- a/bolt/test/X86/yaml-multiple-profiles.test +++ b/bolt/test/X86/yaml-multiple-profiles.test @@ -1,5 +1,5 @@ -# This test ensures that a YAML profile with multiple profiles matching the same -# function is handled gracefully. +## This test ensures that a YAML profile with multiple profiles matching the same +## function is handled gracefully. # REQUIRES: system-linux # RUN: split-file %s %t diff --git a/bolt/test/X86/zero-sized-object.s b/bolt/test/X86/zero-sized-object.s index 1f3522bce213..fa381dbeb7b0 100644 --- a/bolt/test/X86/zero-sized-object.s +++ b/bolt/test/X86/zero-sized-object.s @@ -1,5 +1,5 @@ -# Check that references to local (unnamed) objects below are not -# treated as references relative to zero-sized A object. +## Check that references to local (unnamed) objects below are not +## treated as references relative to zero-sized A object. # REQUIRES: system-linux diff --git a/bolt/test/bad-exe.test b/bolt/test/bad-exe.test index fadc5590ea86..2f69fdbcfe39 100644 --- a/bolt/test/bad-exe.test +++ b/bolt/test/bad-exe.test @@ -1,8 +1,8 @@ -# Check that llvm-bolt rejects input that is not a valid ELF executable -# bzip2.debuginfo is the result of running "objcopy --only-keep-debug". +## Check that llvm-bolt rejects input that is not a valid ELF executable +## bzip2.debuginfo is the result of running "objcopy --only-keep-debug". -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags %S/Inputs/icf-jump-tables.c -g -o %t diff --git a/bolt/test/bolt-icf.test b/bolt/test/bolt-icf.test index f7b056e2ddb0..cd80d96744dd 100644 --- a/bolt/test/bolt-icf.test +++ b/bolt/test/bolt-icf.test @@ -1,4 +1,4 @@ -# Check for the replacement of calls to identical functions. +## Check for the replacement of calls to identical functions. REQUIRES: system-linux diff --git a/bolt/test/bolt-info.test b/bolt/test/bolt-info.test index c329c553813d..fff67abbcea0 100644 --- a/bolt/test/bolt-info.test +++ b/bolt/test/bolt-info.test @@ -1,7 +1,7 @@ -# Check that the .bolt_info section is generated properly. +## Check that the .bolt_info section is generated properly. -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags %S/Inputs/icf-jump-tables.c -o %t diff --git a/bolt/test/heatmap.test b/bolt/test/heatmap.test index eb63ab37b413..fa69691a590d 100644 --- a/bolt/test/heatmap.test +++ b/bolt/test/heatmap.test @@ -1,4 +1,4 @@ -# Verifies basic functioning of heatmap mode +## Verifies basic functioning of heatmap mode REQUIRES: system-linux diff --git a/bolt/test/invalid-profile.test b/bolt/test/invalid-profile.test index 1725a08577e3..df94ff08c8da 100644 --- a/bolt/test/invalid-profile.test +++ b/bolt/test/invalid-profile.test @@ -1,7 +1,7 @@ -# Check that llvm-bolt detects bad profile data and aborts +## Check that llvm-bolt detects bad profile data and aborts -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %S/Inputs/icf-jump-tables.c -o %t diff --git a/bolt/test/keep-aranges.test b/bolt/test/keep-aranges.test index 5a9d932bc1af..e5c9faa97bb4 100644 --- a/bolt/test/keep-aranges.test +++ b/bolt/test/keep-aranges.test @@ -1,5 +1,5 @@ -# Check that BOLT generates .debug_aranges section for an input -# where it was removed when .gdb_index was generated. +## Check that BOLT generates .debug_aranges section for an input +## where it was removed when .gdb_index was generated. REQUIRES: system-linux diff --git a/bolt/test/lit.local.cfg b/bolt/test/lit.local.cfg index 4f4d84e49b13..8aa5f15d5ccf 100644 --- a/bolt/test/lit.local.cfg +++ b/bolt/test/lit.local.cfg @@ -1,4 +1,4 @@ -host_linux_triple = config.target_triple.split("-")[0] + "-linux" +host_linux_triple = config.target_triple.split("-")[0] + "-unknown-linux-gnu" common_linker_flags = "-fuse-ld=lld -Wl,--unresolved-symbols=ignore-all" flags = f"--target={host_linux_triple} {common_linker_flags}" diff --git a/bolt/test/lsda-section-name.cpp b/bolt/test/lsda-section-name.cpp index 41fb17665821..929b17f3b63d 100644 --- a/bolt/test/lsda-section-name.cpp +++ b/bolt/test/lsda-section-name.cpp @@ -2,10 +2,10 @@ // disassembled by BOLT. // RUN: %clang++ %cxxflags -O3 -no-pie -c %s -o %t.o -// RUN: %clang++ %cxxflags -no-pie -fuse-ld=lld %t.o -o %t.exe \ -// RUN: -Wl,-q -Wl,--script=%S/Inputs/lsda.ldscript -// RUN: llvm-readelf -SW %t.exe | FileCheck %s -// RUN: llvm-bolt %t.exe -o %t.bolt +// RUN: %clang++ %cxxflags -O3 -no-pie -fuse-ld=lld %t.o -o %t +// RUN: llvm-objcopy --rename-section .gcc_except_table=.gcc_except_table.main %t +// RUN: llvm-readelf -SW %t | FileCheck %s +// RUN: llvm-bolt %t -o %t.bolt // CHECK: .gcc_except_table.main diff --git a/bolt/test/no-relocs.test b/bolt/test/no-relocs.test index 34993eb330cb..3dd4251f7078 100644 --- a/bolt/test/no-relocs.test +++ b/bolt/test/no-relocs.test @@ -1,7 +1,7 @@ -# Verifies that input without relocations is rejected in relocs mode. +## Verifies that input without relocations is rejected in relocs mode. -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags %S/Inputs/icf-jump-tables.c -o %t diff --git a/bolt/test/non-empty-debug-line.test b/bolt/test/non-empty-debug-line.test index e3de8335238d..0650e9ec1c7a 100644 --- a/bolt/test/non-empty-debug-line.test +++ b/bolt/test/non-empty-debug-line.test @@ -1,5 +1,5 @@ -# Verifies that BOLT emits DWARF line table with the same size if -# no functions with debug info were modified. +## Verifies that BOLT emits DWARF line table with the same size if +## no functions with debug info were modified. REQUIRES: system-linux @@ -9,12 +9,12 @@ RUN: llvm-readobj -S %t > %t2 RUN: llvm-readobj -S %t1 >> %t2 RUN: FileCheck %s --input-file %t2 -# Check the input and grab .debug_line size. +## Check the input and grab .debug_line size. CHECK: File: CHECK: Name: .debug_line CHECK: Size: [[SIZE:[0-9]+]] -# Verify .debug_line size is the same after BOLT. +## Verify .debug_line size is the same after BOLT. CHECK: File: CHECK: Name: .debug_line CHECK: Size: diff --git a/bolt/test/pie.test b/bolt/test/pie.test index 0ce2576ee401..7c833c09bbf0 100644 --- a/bolt/test/pie.test +++ b/bolt/test/pie.test @@ -1,7 +1,7 @@ -# Check that we do not reject position-independent executables (PIEs). +## Check that we do not reject position-independent executables (PIEs). -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags -fPIC -pie %p/Inputs/jump_table_icp.cpp -o %t diff --git a/bolt/test/re-optimize.test b/bolt/test/re-optimize.test index 2c436d708df8..41216d81aa4b 100644 --- a/bolt/test/re-optimize.test +++ b/bolt/test/re-optimize.test @@ -1,7 +1,7 @@ -# Check that we detect re-optimization attempt. +## Check that we detect re-optimization attempt. -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags %S/Inputs/icf-jump-tables.c -o %t.exe diff --git a/bolt/test/runtime/X86/asm-dump.c b/bolt/test/runtime/X86/asm-dump.c index e5383b523515..7656fda44d8d 100644 --- a/bolt/test/runtime/X86/asm-dump.c +++ b/bolt/test/runtime/X86/asm-dump.c @@ -1,5 +1,5 @@ /** - * Test for asm-dump functionality. + ** Test for asm-dump functionality. * * REQUIRES: x86_64-linux,bolt-runtime * diff --git a/bolt/test/shared-object.test b/bolt/test/shared-object.test index 361f4ea94f2a..06afff976e4a 100644 --- a/bolt/test/shared-object.test +++ b/bolt/test/shared-object.test @@ -1,7 +1,7 @@ -# Test that llvm-bolt processes *.so without a failure +## Test that llvm-bolt processes *.so without a failure -# This test uses the clang driver without target flags and will only succeed -# on Linux systems where the host triple matches the target. +## This test uses the clang driver without target flags and will only succeed +## on Linux systems where the host triple matches the target. REQUIRES: system-linux RUN: %clang %cflags %S/Inputs/icf-jump-tables.c -o %t.so -shared -fPIC -Wl,--build-id diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp index 6cef21f1318a..d082faa786b3 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp @@ -47,13 +47,15 @@ void UseStdFormatCheck::registerPPCallbacks(const SourceManager &SM, } void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) { + auto CharPointerType = + hasType(pointerType(pointee(matchers::isSimpleChar()))); Finder->addMatcher( - callExpr(argumentCountAtLeast(1), - hasArgument(0, stringLiteral(isOrdinary())), - callee(functionDecl(unless(cxxMethodDecl()), - matchers::matchesAnyListedName( - StrFormatLikeFunctions)) - .bind("func_decl"))) + callExpr( + argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())), + callee(functionDecl( + unless(cxxMethodDecl()), hasParameter(0, CharPointerType), + matchers::matchesAnyListedName(StrFormatLikeFunctions)) + .bind("func_decl"))) .bind("strformat"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp index ff990feadc0c..1ea170c3cd31 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp @@ -95,12 +95,15 @@ unusedReturnValue(clang::ast_matchers::StatementMatcher MatchedCallExpr) { } void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) { + auto CharPointerType = + hasType(pointerType(pointee(matchers::isSimpleChar()))); if (!PrintfLikeFunctions.empty()) Finder->addMatcher( unusedReturnValue( callExpr(argumentCountAtLeast(1), hasArgument(0, stringLiteral(isOrdinary())), callee(functionDecl(unless(cxxMethodDecl()), + hasParameter(0, CharPointerType), matchers::matchesAnyListedName( PrintfLikeFunctions)) .bind("func_decl"))) @@ -113,6 +116,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) { callExpr(argumentCountAtLeast(2), hasArgument(1, stringLiteral(isOrdinary())), callee(functionDecl(unless(cxxMethodDecl()), + hasParameter(1, CharPointerType), matchers::matchesAnyListedName( FprintfLikeFunctions)) .bind("func_decl"))) diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp index 19307b4cdcbe..bbc1b47b97ae 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -150,6 +150,7 @@ void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxMemberCallExpr( + argumentCountIs(0), on(expr(anyOf(hasType(ValidContainer), hasType(pointsTo(ValidContainer)), hasType(references(ValidContainer)))) @@ -163,7 +164,8 @@ void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) { this); Finder->addMatcher( - callExpr(has(cxxDependentScopeMemberExpr( + callExpr(argumentCountIs(0), + has(cxxDependentScopeMemberExpr( hasObjectExpression( expr(anyOf(hasType(ValidContainer), hasType(pointsTo(ValidContainer)), diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp index 845e71c5003b..33f3ea47df1e 100644 --- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp +++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp @@ -208,9 +208,11 @@ FormatStringConverter::FormatStringConverter(ASTContext *ContextIn, assert(ArgsOffset <= NumArgs); FormatExpr = llvm::dyn_cast( Args[FormatArgOffset]->IgnoreImplicitAsWritten()); - assert(FormatExpr); - if (!FormatExpr->isOrdinary()) - return; // No wide string support yet + if (!FormatExpr || !FormatExpr->isOrdinary()) { + // Function must have a narrow string literal as its first argument. + conversionNotPossible("first argument is not a narrow string literal"); + return; + } PrintfFormatString = FormatExpr->getString(); // Assume that the output will be approximately the same size as the input, diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h b/clang-tools-extra/clang-tidy/utils/Matchers.h index 045e3ffbb6a8..5fd98db96787 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.h +++ b/clang-tools-extra/clang-tidy/utils/Matchers.h @@ -49,6 +49,14 @@ AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) { return pointerType(pointee(qualType(isConstQualified()))); } +// Returns QualType matcher for target char type only. +AST_MATCHER(QualType, isSimpleChar) { + const auto ActualType = Node.getTypePtr(); + return ActualType && + (ActualType->isSpecificBuiltinType(BuiltinType::Char_S) || + ActualType->isSpecificBuiltinType(BuiltinType::Char_U)); +} + AST_MATCHER(Expr, hasUnevaluatedContext) { if (isa(Node) || isa(Node)) return true; diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index fef827a801c3..f43f2417df8f 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -179,14 +179,11 @@ deleteTokensWithKind(const syntax::TokenBuffer &TokBuf, tok::TokenKind Kind, // looked up in the context containing the function/method. // FIXME: Drop attributes in function signature. llvm::Expected -getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, +getFunctionSourceCode(const FunctionDecl *FD, const DeclContext *TargetContext, const syntax::TokenBuffer &TokBuf, const HeuristicResolver *Resolver) { auto &AST = FD->getASTContext(); auto &SM = AST.getSourceManager(); - auto TargetContext = findContextForNS(TargetNamespace, FD->getDeclContext()); - if (!TargetContext) - return error("define outline: couldn't find a context for target"); llvm::Error Errors = llvm::Error::success(); tooling::Replacements DeclarationCleanups; @@ -216,7 +213,7 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, } const NamedDecl *ND = Ref.Targets.front(); const std::string Qualifier = - getQualification(AST, *TargetContext, + getQualification(AST, TargetContext, SM.getLocForStartOfFile(SM.getMainFileID()), ND); if (auto Err = DeclarationCleanups.add( tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier))) @@ -232,7 +229,7 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, if (const auto *Destructor = llvm::dyn_cast(FD)) { if (auto Err = DeclarationCleanups.add(tooling::Replacement( SM, Destructor->getLocation(), 0, - getQualification(AST, *TargetContext, + getQualification(AST, TargetContext, SM.getLocForStartOfFile(SM.getMainFileID()), Destructor)))) Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); @@ -319,29 +316,9 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, } struct InsertionPoint { - std::string EnclosingNamespace; + const DeclContext *EnclosingNamespace = nullptr; size_t Offset; }; -// Returns the most natural insertion point for \p QualifiedName in \p Contents. -// This currently cares about only the namespace proximity, but in feature it -// should also try to follow ordering of declarations. For example, if decls -// come in order `foo, bar, baz` then this function should return some point -// between foo and baz for inserting bar. -llvm::Expected getInsertionPoint(llvm::StringRef Contents, - llvm::StringRef QualifiedName, - const LangOptions &LangOpts) { - auto Region = getEligiblePoints(Contents, QualifiedName, LangOpts); - - assert(!Region.EligiblePoints.empty()); - // FIXME: This selection can be made smarter by looking at the definition - // locations for adjacent decls to Source. Unfortunately pseudo parsing in - // getEligibleRegions only knows about namespace begin/end events so we - // can't match function start/end positions yet. - auto Offset = positionToOffset(Contents, Region.EligiblePoints.back()); - if (!Offset) - return Offset.takeError(); - return InsertionPoint{Region.EnclosingNamespace, *Offset}; -} // Returns the range that should be deleted from declaration, which always // contains function body. In addition to that it might contain constructor @@ -409,14 +386,9 @@ public: } bool prepare(const Selection &Sel) override { - // Bail out if we are not in a header file. - // FIXME: We might want to consider moving method definitions below class - // definition even if we are inside a source file. - if (!isHeaderFile(Sel.AST->getSourceManager().getFilename(Sel.Cursor), - Sel.AST->getLangOpts())) - return false; - + SameFile = !isHeaderFile(Sel.AST->tuPath(), Sel.AST->getLangOpts()); Source = getSelectedFunction(Sel.ASTSelection.commonAncestor()); + // Bail out if the selection is not a in-line function definition. if (!Source || !Source->doesThisDeclarationHaveABody() || Source->isOutOfLine()) @@ -429,19 +401,24 @@ public: if (Source->getTemplateSpecializationInfo()) return false; - if (auto *MD = llvm::dyn_cast(Source)) { - // Bail out in templated classes, as it is hard to spell the class name, - // i.e if the template parameter is unnamed. - if (MD->getParent()->isTemplated()) - return false; - - // The refactoring is meaningless for unnamed classes and definitions - // within unnamed namespaces. - for (const DeclContext *DC = MD->getParent(); DC; DC = DC->getParent()) { - if (auto *ND = llvm::dyn_cast(DC)) { - if (ND->getDeclName().isEmpty()) - return false; - } + auto *MD = llvm::dyn_cast(Source); + if (!MD) { + // Can't outline free-standing functions in the same file. + return !SameFile; + } + + // Bail out in templated classes, as it is hard to spell the class name, + // i.e if the template parameter is unnamed. + if (MD->getParent()->isTemplated()) + return false; + + // The refactoring is meaningless for unnamed classes and namespaces, + // unless we're outlining in the same file + for (const DeclContext *DC = MD->getParent(); DC; DC = DC->getParent()) { + if (auto *ND = llvm::dyn_cast(DC)) { + if (ND->getDeclName().isEmpty() && + (!SameFile || !llvm::dyn_cast(ND))) + return false; } } @@ -453,8 +430,8 @@ public: Expected apply(const Selection &Sel) override { const SourceManager &SM = Sel.AST->getSourceManager(); - auto CCFile = getSourceFile(Sel.AST->tuPath(), Sel); - + auto CCFile = SameFile ? Sel.AST->tuPath().str() + : getSourceFile(Sel.AST->tuPath(), Sel); if (!CCFile) return error("Couldn't find a suitable implementation file."); assert(Sel.FS && "FS Must be set in apply"); @@ -464,8 +441,7 @@ public: if (!Buffer) return llvm::errorCodeToError(Buffer.getError()); auto Contents = Buffer->get()->getBuffer(); - auto InsertionPoint = getInsertionPoint( - Contents, Source->getQualifiedNameAsString(), Sel.AST->getLangOpts()); + auto InsertionPoint = getInsertionPoint(Contents, Sel); if (!InsertionPoint) return InsertionPoint.takeError(); @@ -499,17 +475,77 @@ public: HeaderUpdates = HeaderUpdates.merge(*DelInline); } - auto HeaderFE = Effect::fileEdit(SM, SM.getMainFileID(), HeaderUpdates); - if (!HeaderFE) - return HeaderFE.takeError(); - - Effect->ApplyEdits.try_emplace(HeaderFE->first, - std::move(HeaderFE->second)); + if (SameFile) { + tooling::Replacements &R = Effect->ApplyEdits[*CCFile].Replacements; + R = R.merge(HeaderUpdates); + } else { + auto HeaderFE = Effect::fileEdit(SM, SM.getMainFileID(), HeaderUpdates); + if (!HeaderFE) + return HeaderFE.takeError(); + Effect->ApplyEdits.try_emplace(HeaderFE->first, + std::move(HeaderFE->second)); + } return std::move(*Effect); } + // Returns the most natural insertion point for \p QualifiedName in \p + // Contents. This currently cares about only the namespace proximity, but in + // feature it should also try to follow ordering of declarations. For example, + // if decls come in order `foo, bar, baz` then this function should return + // some point between foo and baz for inserting bar. + // FIXME: The selection can be made smarter by looking at the definition + // locations for adjacent decls to Source. Unfortunately pseudo parsing in + // getEligibleRegions only knows about namespace begin/end events so we + // can't match function start/end positions yet. + llvm::Expected getInsertionPoint(llvm::StringRef Contents, + const Selection &Sel) { + // If the definition goes to the same file and there is a namespace, + // we should (and, in the case of anonymous namespaces, need to) + // put the definition into the original namespace block. + if (SameFile) { + auto *Klass = Source->getDeclContext()->getOuterLexicalRecordContext(); + if (!Klass) + return error("moving to same file not supported for free functions"); + const SourceLocation EndLoc = Klass->getBraceRange().getEnd(); + const auto &TokBuf = Sel.AST->getTokens(); + auto Tokens = TokBuf.expandedTokens(); + auto It = llvm::lower_bound( + Tokens, EndLoc, [](const syntax::Token &Tok, SourceLocation EndLoc) { + return Tok.location() < EndLoc; + }); + while (It != Tokens.end()) { + if (It->kind() != tok::semi) { + ++It; + continue; + } + unsigned Offset = Sel.AST->getSourceManager() + .getDecomposedLoc(It->endLocation()) + .second; + return InsertionPoint{Klass->getEnclosingNamespaceContext(), Offset}; + } + return error( + "failed to determine insertion location: no end of class found"); + } + + auto Region = getEligiblePoints( + Contents, Source->getQualifiedNameAsString(), Sel.AST->getLangOpts()); + + assert(!Region.EligiblePoints.empty()); + auto Offset = positionToOffset(Contents, Region.EligiblePoints.back()); + if (!Offset) + return Offset.takeError(); + + auto TargetContext = + findContextForNS(Region.EnclosingNamespace, Source->getDeclContext()); + if (!TargetContext) + return error("define outline: couldn't find a context for target"); + + return InsertionPoint{*TargetContext, *Offset}; + } + private: const FunctionDecl *Source = nullptr; + bool SameFile = false; }; REGISTER_TWEAK(DefineOutline) diff --git a/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp b/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp index 147d9abe6913..32942e6bbfdc 100644 --- a/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp @@ -25,7 +25,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" @@ -42,7 +41,11 @@ #include #include -namespace clang::clangd { +namespace clang { + +class Module; + +namespace clangd { namespace { struct Inclusion { Inclusion(const SourceManager &SM, SourceLocation HashLoc, @@ -170,4 +173,5 @@ TEST(ReplayPreambleTest, IncludesAndSkippedFiles) { } } } // namespace -} // namespace clang::clangd +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp index d1e60b070f20..906ff33db873 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -19,12 +19,47 @@ TWEAK_TEST(DefineOutline); TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) { FileName = "Test.cpp"; - // Not available unless in a header file. + // Not available for free function unless in a header file. EXPECT_UNAVAILABLE(R"cpp( [[void [[f^o^o]]() [[{ return; }]]]])cpp"); + // Available in soure file. + EXPECT_AVAILABLE(R"cpp( + struct Foo { + void f^oo() {} + }; + )cpp"); + + // Available within named namespace in source file. + EXPECT_AVAILABLE(R"cpp( + namespace N { + struct Foo { + void f^oo() {} + }; + } // namespace N + )cpp"); + + // Available within anonymous namespace in source file. + EXPECT_AVAILABLE(R"cpp( + namespace { + struct Foo { + void f^oo() {} + }; + } // namespace + )cpp"); + + // Not available for out-of-line method. + EXPECT_UNAVAILABLE(R"cpp( + class Bar { + void baz(); + }; + + [[void [[Bar::[[b^a^z]]]]() [[{ + return; + }]]]])cpp"); + FileName = "Test.hpp"; // Not available unless function name or fully body is selected. EXPECT_UNAVAILABLE(R"cpp( @@ -100,7 +135,7 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) { }; )cpp"); - // Not available on definitions within unnamed namespaces + // Not available on definitions in header file within unnamed namespaces EXPECT_UNAVAILABLE(R"cpp( namespace { struct Foo { @@ -349,6 +384,40 @@ TEST_F(DefineOutlineTest, ApplyTest) { } } +TEST_F(DefineOutlineTest, InCppFile) { + FileName = "Test.cpp"; + + struct { + llvm::StringRef Test; + llvm::StringRef ExpectedSource; + } Cases[] = { + { + R"cpp( + namespace foo { + namespace { + struct Foo { void ba^r() {} }; + struct Bar { void foo(); }; + void Bar::foo() {} + } + } + )cpp", + R"cpp( + namespace foo { + namespace { + struct Foo { void bar() ; };void Foo::bar() {} + struct Bar { void foo(); }; + void Bar::foo() {} + } + } + )cpp"}, + }; + + for (const auto &Case : Cases) { + SCOPED_TRACE(Case.Test); + EXPECT_EQ(apply(Case.Test, nullptr), Case.ExpectedSource); + } +} + TEST_F(DefineOutlineTest, HandleMacros) { llvm::StringMap EditedFiles; ExtraFiles["Test.cpp"] = ""; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a5e87d26d96c..33b65caf2b02 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -351,6 +351,11 @@ Changes in existing checks ` check to also handle calls to ``compare`` method. +- Improved :doc:`modernize-use-std-print + ` check to not crash if the + format string parameter of the function to be replaced is not of the + expected type. + - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. @@ -368,6 +373,10 @@ Changes in existing checks ` check to eliminate false positives when returning types with const not at the top level. +- Improved :doc:`readability-container-size-empty + ` check to prevent false + positives when utilizing ``size`` or ``length`` methods that accept parameter. + - Improved :doc:`readability-duplicate-include ` check by excluding include directives that form the filename using macro. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp index 815e22b29155..c025113055cc 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format-custom.cpp @@ -2,7 +2,7 @@ // RUN: -std=c++20 %s modernize-use-std-format %t -- \ // RUN: -config="{CheckOptions: { \ // RUN: modernize-use-std-format.StrictMode: true, \ -// RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2', \ +// RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2; bad_format_type_strprintf', \ // RUN: modernize-use-std-format.ReplacementFormatFunction: 'fmt::format', \ // RUN: modernize-use-std-format.FormatHeader: '' \ // RUN: }}" \ @@ -10,7 +10,7 @@ // RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \ // RUN: -std=c++20 %s modernize-use-std-format %t -- \ // RUN: -config="{CheckOptions: { \ -// RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2', \ +// RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2; bad_format_type_strprintf', \ // RUN: modernize-use-std-format.ReplacementFormatFunction: 'fmt::format', \ // RUN: modernize-use-std-format.FormatHeader: '' \ // RUN: }}" \ @@ -50,3 +50,17 @@ std::string A(const std::string &in) { return "_" + in; } + +// Issue #92896: Ensure that the check doesn't assert if the argument is +// promoted to something that isn't a string. +struct S { + S(...); +}; +std::string bad_format_type_strprintf(const S &, ...); + +std::string unsupported_format_parameter_type() +{ + // No fixes here because the format parameter of the function called is not a + // string. + return bad_format_type_strprintf(""); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-custom.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-custom.cpp index 8466217b765a..09720001ab83 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-custom.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print-custom.cpp @@ -1,8 +1,8 @@ // RUN: %check_clang_tidy -std=c++23 %s modernize-use-std-print %t -- \ // RUN: -config="{CheckOptions: \ // RUN: { \ -// RUN: modernize-use-std-print.PrintfLikeFunctions: 'unqualified_printf;::myprintf; mynamespace::myprintf2', \ -// RUN: modernize-use-std-print.FprintfLikeFunctions: '::myfprintf; mynamespace::myfprintf2' \ +// RUN: modernize-use-std-print.PrintfLikeFunctions: 'unqualified_printf;::myprintf; mynamespace::myprintf2; bad_format_type_printf', \ +// RUN: modernize-use-std-print.FprintfLikeFunctions: '::myfprintf; mynamespace::myfprintf2; bad_format_type_fprintf' \ // RUN: } \ // RUN: }" \ // RUN: -- -isystem %clang_tidy_headers @@ -86,3 +86,25 @@ void no_name(const std::string &in) { "A" + in; } + +int myprintf(const wchar_t *, ...); + +void wide_string_not_supported() { + myprintf(L"wide string %s", L"string"); +} + +// Issue #92896: Ensure that the check doesn't assert if the argument is +// promoted to something that isn't a string. +struct S { + S(...) {} +}; +int bad_format_type_printf(const S &, ...); +int bad_format_type_fprintf(FILE *, const S &, ...); + +void unsupported_format_parameter_type() +{ + // No fixes here because the format parameter of the function called is not a + // string. + bad_format_type_printf("Hello %s", "world"); + bad_format_type_fprintf(stderr, "Hello %s", "world"); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp index 84bdbd58b85e..ecaf97fa348c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp @@ -861,3 +861,31 @@ namespace PR72619 { if (0 >= s.size()) {} } } + +namespace PR88203 { + struct SS { + bool empty() const; + int size() const; + int length(int) const; + }; + + struct SU { + bool empty() const; + int size(int) const; + int length() const; + }; + + void f(const SS& s) { + if (0 == s.length(1)) {} + if (0 == s.size()) {} + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] + // CHECK-FIXES: {{^ }}if (s.empty()) {}{{$}} + } + + void f(const SU& s) { + if (0 == s.size(1)) {} + if (0 == s.length()) {} + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'length' [readability-container-size-empty] + // CHECK-FIXES: {{^ }}if (s.empty()) {}{{$}} + } +} diff --git a/clang/README.txt b/clang/README.txt index 63842d42bc20..477f720b193f 100644 --- a/clang/README.txt +++ b/clang/README.txt @@ -23,4 +23,4 @@ on the Clang forums: https://discourse.llvm.org/c/clang/ If you find a bug in Clang, please file it in the LLVM bug tracker: - http://llvm.org/bugs/ + https://github.com/llvm/llvm-project/issues diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index d5546e20873b..66e764968e85 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -19,7 +19,6 @@ set(LLVM_ENABLE_LLD ON CACHE BOOL "") set(LLVM_ENABLE_LTO ON CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_PLUGINS OFF CACHE BOOL "") -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_UNWIND_TABLES OFF CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 30a3b9116a46..4d3af3ad3f40 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -12,7 +12,6 @@ set(LLVM_ENABLE_DIA_SDK OFF CACHE BOOL "") set(LLVM_ENABLE_LIBEDIT OFF CACHE BOOL "") set(LLVM_ENABLE_LIBXML2 OFF CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_UNWIND_TABLES OFF CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") @@ -34,7 +33,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH LibXml2_ROOT LLVM_ENABLE_CURL LLVM_ENABLE_HTTPLIB - LLVM_ENABLE_TERMINFO LLVM_ENABLE_LIBEDIT CURL_ROOT OpenSSL_ROOT @@ -47,11 +45,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH CURSES_LIBRARIES PANEL_LIBRARIES - # Deprecated - Terminfo_ROOT - - Terminfo_LIBRARIES - # Deprecated LibEdit_ROOT diff --git a/clang/cmake/caches/VectorEngine.cmake b/clang/cmake/caches/VectorEngine.cmake index 2f968a21cc40..b429fb0997d7 100644 --- a/clang/cmake/caches/VectorEngine.cmake +++ b/clang/cmake/caches/VectorEngine.cmake @@ -13,9 +13,7 @@ # ninja # -# Disable TERMINFO, ZLIB, and ZSTD for VE since there is no pre-compiled -# libraries. -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") +# Disable ZLIB, and ZSTD for VE since there is no pre-compiled libraries. set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(LLVM_ENABLE_ZSTD OFF CACHE BOOL "") diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 1a7d0e6a05e3..bb00c20922d3 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -1799,8 +1799,8 @@ the configuration (without a prefix: ``Auto``). Never merge functions into a single line. * ``SFS_InlineOnly`` (in configuration: ``InlineOnly``) - Only merge functions defined inside a class. Same as "inline", - except it does not implies "empty": i.e. top level empty functions + Only merge functions defined inside a class. Same as ``inline``, + except it does not implies ``empty``: i.e. top level empty functions are not merged either. .. code-block:: c++ @@ -1825,7 +1825,7 @@ the configuration (without a prefix: ``Auto``). } * ``SFS_Inline`` (in configuration: ``Inline``) - Only merge functions defined inside a class. Implies "empty". + Only merge functions defined inside a class. Implies ``empty``. .. code-block:: c++ @@ -2042,7 +2042,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - AttributeMacros: ['__capability', '__output', '__unused'] + AttributeMacros: [__capability, __output, __unused] .. _BinPackArguments: @@ -3802,7 +3802,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - ForEachMacros: ['RANGES_FOR', 'FOREACH'] + ForEachMacros: [RANGES_FOR, FOREACH] For example: BOOST_FOREACH. @@ -3825,7 +3825,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - IfMacros: ['IF'] + IfMacros: [IF] For example: `KJ_IF_MAYBE `_ @@ -4374,7 +4374,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - JavaImportGroups: ['com.example', 'com', 'org'] + JavaImportGroups: [com.example, com, org] .. code-block:: java @@ -4438,7 +4438,7 @@ the configuration (without a prefix: ``Auto``). VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, - } from 'some/module.js' + } from "some/module.js" false: import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" @@ -5088,7 +5088,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - QualifierOrder: ['inline', 'static', 'type', 'const'] + QualifierOrder: [inline, static, type, const] .. code-block:: c++ @@ -5117,16 +5117,16 @@ the configuration (without a prefix: ``Auto``). .. note:: - it MUST contain 'type'. + It **must** contain ``type``. - Items to the left of 'type' will be placed to the left of the type and - aligned in the order supplied. Items to the right of 'type' will be + Items to the left of ``type`` will be placed to the left of the type and + aligned in the order supplied. Items to the right of ``type`` will be placed to the right of the type and aligned in the order supplied. .. code-block:: yaml - QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ] + QualifierOrder: [inline, static, type, const, volatile] .. _RawStringFormats: @@ -5138,10 +5138,10 @@ the configuration (without a prefix: ``Auto``). name will be reformatted assuming the specified language based on the style for that language defined in the .clang-format file. If no style has been defined in the .clang-format file for the specific language, a - predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not - found, the formatting is based on llvm style. A matching delimiter takes - precedence over a matching enclosing function name for determining the - language of the raw string contents. + predefined style given by ``BasedOnStyle`` is used. If ``BasedOnStyle`` is + not found, the formatting is based on ``LLVM`` style. A matching delimiter + takes precedence over a matching enclosing function name for determining + the language of the raw string contents. If a canonical delimiter is specified, occurrences of other delimiters for the same language will be updated to the canonical if possible. @@ -5156,17 +5156,17 @@ the configuration (without a prefix: ``Auto``). RawStringFormats: - Language: TextProto Delimiters: - - 'pb' - - 'proto' + - pb + - proto EnclosingFunctions: - - 'PARSE_TEXT_PROTO' + - PARSE_TEXT_PROTO BasedOnStyle: google - Language: Cpp Delimiters: - - 'cc' - - 'cpp' - BasedOnStyle: llvm - CanonicalDelimiter: 'cc' + - cc + - cpp + BasedOnStyle: LLVM + CanonicalDelimiter: cc .. _ReferenceAlignment: @@ -5533,7 +5533,7 @@ the configuration (without a prefix: ``Auto``). This determines the maximum length of short namespaces by counting unwrapped lines (i.e. containing neither opening nor closing - namespace brace) and makes "FixNamespaceComments" omit adding + namespace brace) and makes ``FixNamespaceComments`` omit adding end comments for those. .. code-block:: c++ @@ -5645,7 +5645,7 @@ the configuration (without a prefix: ``Auto``). * ``SUD_Lexicographic`` (in configuration: ``Lexicographic``) Using declarations are sorted in the order defined as follows: - Split the strings by "::" and discard any initial empty strings. Sort + Split the strings by ``::`` and discard any initial empty strings. Sort the lists of names lexicographically, and within those groups, names are in case-insensitive lexicographic order. @@ -5659,7 +5659,7 @@ the configuration (without a prefix: ``Auto``). * ``SUD_LexicographicNumeric`` (in configuration: ``LexicographicNumeric``) Using declarations are sorted in the order defined as follows: - Split the strings by "::" and discard any initial empty strings. The + Split the strings by ``::`` and discard any initial empty strings. The last element of each list is a non-namespace name; all others are namespace names. Sort the lists of names lexicographically, where the sort order of individual names is that all non-namespace names come @@ -5699,7 +5699,7 @@ the configuration (without a prefix: ``Auto``). .. _SpaceAfterTemplateKeyword: **SpaceAfterTemplateKeyword** (``Boolean``) :versionbadge:`clang-format 4` :ref:`¶ ` - If ``true``, a space will be inserted after the 'template' keyword. + If ``true``, a space will be inserted after the ``template`` keyword. .. code-block:: c++ @@ -5860,7 +5860,7 @@ the configuration (without a prefix: ``Auto``). * ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``) Put a space before opening parentheses only if the parentheses are not - empty i.e. '()' + empty. .. code-block:: c++ @@ -6245,7 +6245,7 @@ the configuration (without a prefix: ``Auto``). true: false: x = ( int32 )y vs. x = (int32)y - * ``bool InEmptyParentheses`` Put a space in parentheses only if the parentheses are empty i.e. '()' + * ``bool InEmptyParentheses`` Insert a space in empty parentheses, i.e. ``()``. .. code-block:: c++ @@ -6409,10 +6409,10 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml TableGenBreakInsideDAGArg: BreakAll - TableGenBreakingDAGArgOperators: ['ins', 'outs'] + TableGenBreakingDAGArgOperators: [ins, outs] makes the line break only occurs inside DAGArgs beginning with the - specified identifiers 'ins' and 'outs'. + specified identifiers ``ins`` and ``outs``. .. code-block:: c++ @@ -6450,7 +6450,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - TypenameMacros: ['STACK_OF', 'LIST'] + TypenameMacros: [STACK_OF, LIST] For example: OpenSSL STACK_OF, BSD LIST_ENTRY. @@ -6518,7 +6518,7 @@ the configuration (without a prefix: ``Auto``). .. code-block:: yaml - WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE] For example: BOOST_PP_STRINGIZE @@ -6538,7 +6538,7 @@ The goal of the clang-format project is more on the side of supporting a limited set of styles really well as opposed to supporting every single style used by a codebase somewhere in the wild. Of course, we do want to support all major projects and thus have established the following bar for adding style -options. Each new style option must .. +options. Each new style option must: * be used in a project of significant size (have dozens of contributors) * have a publicly accessible style guide diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 44035f48cb3f..32515fbac64f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -251,6 +251,9 @@ Resolutions to C++ Defect Reports - P0522 implementation is enabled by default in all language versions, and provisional wording for CWG2398 is implemented. +- Clang now requires a template argument list after a template keyword. + (`CWG96: Syntactic disambiguation using the template keyword `_). + C Language Changes ------------------ @@ -813,6 +816,14 @@ Bug Fixes to C++ Support - Clang now allows ``@$``` in raw string literals. Fixes (#GH93130). - Fix an assertion failure when checking invalid ``this`` usage in the wrong context. (Fixes #GH91536). - Clang no longer models dependent NTTP arguments as ``TemplateParamObjectDecl`` s. Fixes (#GH84052). +- Fix incorrect merging of modules which contain using declarations which shadow + other declarations. This could manifest as ODR checker false positives. + Fixes (`#80252 `_) +- Fix a regression introduced in Clang 18 causing incorrect overload resolution in the presence of functions only + differering by their constraints when only one of these function was variadic. +- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625). +- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821) +- Fix a crash caused by improper use of ``__array_extent``. (#GH80474) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 80ba70f67126..f954857b0235 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -4430,9 +4430,9 @@ To generate SPIR-V binaries, Clang uses the external ``llvm-spirv`` tool from th Prior to the generation of SPIR-V binary with Clang, ``llvm-spirv`` should be built or installed. Please refer to `the following instructions `_ -for more details. Clang will expect the ``llvm-spirv`` executable to -be present in the ``PATH`` environment variable. Clang uses ``llvm-spirv`` -with `the widely adopted assembly syntax package +for more details. Clang will look for ``llvm-spirv-`` and +``llvm-spirv`` executables, in this order, in the ``PATH`` environment variable. +Clang uses ``llvm-spirv`` with `the widely adopted assembly syntax package `_. `The versioning diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 3a31708a1e9d..1e75c3997a47 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1235,6 +1235,50 @@ Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, mallo .. literalinclude:: checkers/unix_api_example.c :language: c +.. _unix-BlockInCriticalSection: + +unix.BlockInCriticalSection (C, C++) +"""""""""""""""""""""""""""""""""""" +Check for calls to blocking functions inside a critical section. +Blocking functions detected by this checker: ``sleep, getc, fgets, read, recv``. +Critical section handling functions modeled by this checker: +``lock, unlock, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``. + +.. code-block:: c + + void pthread_lock_example(pthread_mutex_t *m) { + pthread_mutex_lock(m); // note: entering critical section here + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } + +.. code-block:: cpp + + void overlapping_critical_sections(mtx_t *m1, std::mutex &m2) { + std::lock_guard lg{m2}; // note: entering critical section here + mtx_lock(m1); // note: entering critical section here + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + mtx_unlock(m1); + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + // still inside of the critical section of the std::lock_guard + } + +**Limitations** + +* The ``trylock`` and ``timedlock`` versions of acquiring locks are currently assumed to always succeed. + This can lead to false positives. + +.. code-block:: c + + void trylock_example(pthread_mutex_t *m) { + if (pthread_mutex_trylock(m) == 0) { // assume trylock always succeeds + sleep(10); // warn: Call to blocking function 'sleep' inside of critical section + pthread_mutex_unlock(m); + } else { + sleep(10); // false positive: Incorrect warning about blocking function inside critical section. + } + } + .. _unix-Errno: unix.Errno (C) @@ -3130,24 +3174,6 @@ For a more detailed description of configuration options, please see the alpha.unix ^^^^^^^^^^ -.. _alpha-unix-BlockInCriticalSection: - -alpha.unix.BlockInCriticalSection (C) -""""""""""""""""""""""""""""""""""""" -Check for calls to blocking functions inside a critical section. -Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,`` -`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock`` - -.. code-block:: c - - void test() { - std::mutex m; - m.lock(); - sleep(3); // warn: a blocking function sleep is called inside a critical - // section - m.unlock(); - } - .. _alpha-unix-Chroot: alpha.unix.Chroot (C) diff --git a/clang/include/clang/APINotes/APINotesManager.h b/clang/include/clang/APINotes/APINotesManager.h index 18375c9e51a1..98592438e90e 100644 --- a/clang/include/clang/APINotes/APINotesManager.h +++ b/clang/include/clang/APINotes/APINotesManager.h @@ -9,7 +9,6 @@ #ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H #define LLVM_CLANG_APINOTES_APINOTESMANAGER_H -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -24,6 +23,7 @@ namespace clang { class DirectoryEntry; class FileEntry; class LangOptions; +class Module; class SourceManager; namespace api_notes { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 4bbb4380cdd7..99093aa17972 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -855,10 +855,14 @@ bool RecursiveASTVisitor::TraverseDeclarationNameInfo( template bool RecursiveASTVisitor::TraverseTemplateName(TemplateName Template) { - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); + } else if (QualifiedTemplateName *QTN = + Template.getAsQualifiedTemplateName()) { + if (QTN->getQualifier()) { + TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); + } + } return true; } diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index 876be463c71d..7aedc086ab7d 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -360,6 +360,10 @@ public: static TemplateName getFromVoidPointer(void *Ptr) { return TemplateName(Ptr); } + + /// Structural equality. + bool operator==(TemplateName Other) const { return Storage == Other.Storage; } + bool operator!=(TemplateName Other) const { return !operator==(Other); } }; /// Insertion operator for diagnostics. This allows sending TemplateName's diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 63fa16c9ec47..caa33abd99e4 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -214,7 +214,8 @@ public: void dumpNestedNameSpecifier(const NestedNameSpecifier *NNS); void dumpConceptReference(const ConceptReference *R); void dumpTemplateArgument(const TemplateArgument &TA); - void dumpTemplateName(TemplateName TN); + void dumpBareTemplateName(TemplateName TN); + void dumpTemplateName(TemplateName TN, StringRef Label = {}); void dumpDeclRef(const Decl *D, StringRef Label = {}); diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index 05748f300a93..925b99af9141 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -15,6 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "llvm/ADT/DenseSet.h" @@ -80,6 +81,52 @@ private: std::optional ImplicitValueInitForUnion; }; +/// Specialization of `RecursiveASTVisitor` that visits those nodes that are +/// relevant to the dataflow analysis; generally, these are the ones that also +/// appear in the CFG. +/// To start the traversal, call `TraverseStmt()` on the statement or body of +/// the function to analyze. Don't call `TraverseDecl()` on the function itself; +/// this won't work as `TraverseDecl()` contains code to avoid traversing nested +/// functions. +template +class AnalysisASTVisitor : public RecursiveASTVisitor { +public: + bool shouldVisitImplicitCode() { return true; } + + bool shouldVisitLambdaBody() const { return false; } + + bool TraverseDecl(Decl *D) { + // Don't traverse nested record or function declarations. + // - We won't be analyzing code contained in these anyway + // - We don't model fields that are used only in these nested declaration, + // so trying to propagate a result object to initializers of such fields + // would cause an error. + if (isa_and_nonnull(D) || isa_and_nonnull(D)) + return true; + + return RecursiveASTVisitor::TraverseDecl(D); + } + + // Don't traverse expressions in unevaluated contexts, as we don't model + // fields that are only used in these. + // Note: The operand of the `noexcept` operator is an unevaluated operand, but + // nevertheless it appears in the Clang CFG, so we don't exclude it here. + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } + bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; } + bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { + return true; + } + + bool TraverseBindingDecl(BindingDecl *BD) { + // `RecursiveASTVisitor` doesn't traverse holding variables for + // `BindingDecl`s by itself, so we need to tell it to. + if (VarDecl *HoldingVar = BD->getHoldingVar()) + TraverseDecl(HoldingVar); + return RecursiveASTVisitor::TraverseBindingDecl(BD); + } +}; + /// A collection of several types of declarations, all referenced from the same /// function. struct ReferencedDecls { diff --git a/clang/include/clang/Basic/ASTSourceDescriptor.h b/clang/include/clang/Basic/ASTSourceDescriptor.h new file mode 100644 index 000000000000..175e0551db76 --- /dev/null +++ b/clang/include/clang/Basic/ASTSourceDescriptor.h @@ -0,0 +1,52 @@ +//===- ASTSourceDescriptor.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules +/// and precompiled header files +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H +#define LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H + +#include "clang/Basic/Module.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +namespace clang { + +/// Abstracts clang modules and precompiled header files and holds +/// everything needed to generate debug info for an imported module +/// or PCH. +class ASTSourceDescriptor { + StringRef PCHModuleName; + StringRef Path; + StringRef ASTFile; + ASTFileSignature Signature; + Module *ClangModule = nullptr; + +public: + ASTSourceDescriptor() = default; + ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, + ASTFileSignature Signature) + : PCHModuleName(std::move(Name)), Path(std::move(Path)), + ASTFile(std::move(ASTFile)), Signature(Signature) {} + ASTSourceDescriptor(Module &M); + + std::string getModuleName() const; + StringRef getPath() const { return Path; } + StringRef getASTFile() const { return ASTFile; } + ASTFileSignature getSignature() const { return Signature; } + Module *getModuleOrNull() const { return ClangModule; } +}; + +} // namespace clang + +#endif // LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ef9df1e9d8b4..c6f08860f203 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1060,18 +1060,10 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { .Case("ShaderModel", "shadermodel") .Default(Platform); } -static llvm::StringRef getPrettyEnviromentName(llvm::StringRef Environment) { - return llvm::StringSwitch(Environment) - .Case("pixel", "pixel shader") - .Case("vertex", "vertex shader") - .Case("geometry", "geometry shader") - .Case("hull", "hull shader") - .Case("domain", "domain shader") - .Case("compute", "compute shader") - .Case("mesh", "mesh shader") - .Case("amplification", "amplification shader") - .Case("library", "shader library") - .Default(Environment); +static llvm::StringRef getPrettyEnviromentName(llvm::Triple::EnvironmentType EnvironmentType) { + if (EnvironmentType >= llvm::Triple::Pixel && EnvironmentType <= llvm::Triple::Amplification) + return llvm::Triple::getEnvironmentTypeName(EnvironmentType); + return ""; } static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environment) { return llvm::StringSwitch(Environment) @@ -1081,6 +1073,12 @@ static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environm .Case("hull", llvm::Triple::Hull) .Case("domain", llvm::Triple::Domain) .Case("compute", llvm::Triple::Compute) + .Case("raygeneration", llvm::Triple::RayGeneration) + .Case("intersection", llvm::Triple::Intersection) + .Case("anyhit", llvm::Triple::AnyHit) + .Case("closesthit", llvm::Triple::ClosestHit) + .Case("miss", llvm::Triple::Miss) + .Case("callable", llvm::Triple::Callable) .Case("mesh", llvm::Triple::Mesh) .Case("amplification", llvm::Triple::Amplification) .Case("library", llvm::Triple::Library) @@ -3070,7 +3068,8 @@ def M68kRTD: DeclOrTypeAttr { let Documentation = [M68kRTDDocs]; } -def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr { +def PreserveNone : DeclOrTypeAttr, + TargetSpecificAttr> { let Spellings = [Clang<"preserve_none">]; let Subjects = SubjectList<[FunctionLike]>; let Documentation = [PreserveNoneDocs]; @@ -4480,6 +4479,29 @@ def HLSLShader : InheritableAttr { "Miss", "Callable", "Mesh", "Amplification"]> ]; let Documentation = [HLSLSV_ShaderTypeAttrDocs]; + let AdditionalMembers = +[{ + static const unsigned ShaderTypeMaxValue = (unsigned)HLSLShaderAttr::Amplification; + + static llvm::Triple::EnvironmentType getTypeAsEnvironment(HLSLShaderAttr::ShaderType ShaderType) { + switch (ShaderType) { + case HLSLShaderAttr::Pixel: return llvm::Triple::Pixel; + case HLSLShaderAttr::Vertex: return llvm::Triple::Vertex; + case HLSLShaderAttr::Geometry: return llvm::Triple::Geometry; + case HLSLShaderAttr::Hull: return llvm::Triple::Hull; + case HLSLShaderAttr::Domain: return llvm::Triple::Domain; + case HLSLShaderAttr::Compute: return llvm::Triple::Compute; + case HLSLShaderAttr::RayGeneration: return llvm::Triple::RayGeneration; + case HLSLShaderAttr::Intersection: return llvm::Triple::Intersection; + case HLSLShaderAttr::AnyHit: return llvm::Triple::AnyHit; + case HLSLShaderAttr::ClosestHit: return llvm::Triple::ClosestHit; + case HLSLShaderAttr::Miss: return llvm::Triple::Miss; + case HLSLShaderAttr::Callable: return llvm::Triple::Callable; + case HLSLShaderAttr::Mesh: return llvm::Triple::Mesh; + case HLSLShaderAttr::Amplification: return llvm::Triple::Amplification; + } + } +}]; } def HLSLResource : InheritableAttr { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index a313e811c9d2..70d5dfa8aaf8 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5660,18 +5660,21 @@ experimental at this time. def PreserveNoneDocs : Documentation { let Category = DocCatCallingConvs; let Content = [{ -On X86-64 target, this attribute changes the calling convention of a function. +On X86-64 and AArch64 targets, this attribute changes the calling convention of a function. The ``preserve_none`` calling convention tries to preserve as few general registers as possible. So all general registers are caller saved registers. It also uses more general registers to pass arguments. This attribute doesn't -impact floating-point registers (XMMs/YMMs). Floating-point registers still -follow the c calling convention. ``preserve_none``'s ABI is still unstable, and +impact floating-point registers. ``preserve_none``'s ABI is still unstable, and may be changed in the future. -- Only RSP and RBP are preserved by callee. - -- Register R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can - be used to pass function arguments. +- On X86-64, only RSP and RBP are preserved by the callee. + Registers R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can + be used to pass function arguments. Floating-point registers (XMMs/YMMs) still + follow the C calling convention. +- On AArch64, only LR and FP are preserved by the callee. + Registers X19-X28, X0-X7, and X9-X15 are used to pass function arguments. + X8, X16-X18, SIMD and floating-point registers follow the AAPCS calling + convention. }]; } diff --git a/clang/include/clang/Basic/CustomizableOptional.h b/clang/include/clang/Basic/CustomizableOptional.h index 84d40025ee41..2d6ae6a781a5 100644 --- a/clang/include/clang/Basic/CustomizableOptional.h +++ b/clang/include/clang/Basic/CustomizableOptional.h @@ -97,14 +97,6 @@ public: template T value_or(U &&alt) && { return has_value() ? std::move(operator*()) : std::forward(alt); } - - // Allow conversion to std::optional. - explicit operator std::optional &() const & { - return *this ? **this : std::optional(); - } - explicit operator std::optional &&() const && { - return *this ? std::move(**this) : std::optional(); - } }; template diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 6b595a356793..7d5ba7869ec3 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1517,6 +1517,9 @@ def HLSLMixPackOffset : DiagGroup<"mix-packoffset">; // Warnings for DXIL validation def DXILValidation : DiagGroup<"dxil-validation">; +// Warning for HLSL API availability +def HLSLAvailability : DiagGroup<"hlsl-availability">; + // Warnings and notes related to const_var_decl_type attribute checks def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index f8328be5890d..d8c3fee7841f 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -887,6 +887,10 @@ def err_requires_expr_in_simple_requirement : Error< "requires expression in requirement body; did " "you intend to place it in a nested requirement? (add another 'requires' " "before the expression)">; +def missing_template_arg_list_after_template_kw : Extension< + "a template argument list is expected after a name prefixed by the template " + "keyword">, InGroup>, + DefaultError; def err_missing_dependent_template_keyword : Error< "use 'template' keyword to treat '%0' as a dependent template name">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f15cba63624e..e34eb692941b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12239,6 +12239,13 @@ def err_hlsl_param_qualifier_mismatch : def warn_hlsl_impcast_vector_truncation : Warning< "implicit conversion truncates vector: %0 to %1">, InGroup; +def warn_hlsl_availability : Warning< + "%0 is only available %select{|in %4 environment }3on %1 %2 or newer">, + InGroup, DefaultError; +def warn_hlsl_availability_unavailable : + Warning, + InGroup, DefaultError; + // Layout randomization diagnostics. def err_non_designated_init_used : Error< "a randomized struct can only be initialized with a designated initializer">; diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 2d62d05cd919..e86f4303d732 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -868,32 +868,6 @@ private: unsigned Generation = 0; }; -/// Abstracts clang modules and precompiled header files and holds -/// everything needed to generate debug info for an imported module -/// or PCH. -class ASTSourceDescriptor { - StringRef PCHModuleName; - StringRef Path; - StringRef ASTFile; - ASTFileSignature Signature; - Module *ClangModule = nullptr; - -public: - ASTSourceDescriptor() = default; - ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, - ASTFileSignature Signature) - : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(Module &M); - - std::string getModuleName() const; - StringRef getPath() const { return Path; } - StringRef getASTFile() const { return ASTFile; } - ASTFileSignature getSignature() const { return Signature; } - Module *getModuleOrNull() const { return ClangModule; } -}; - - } // namespace clang #endif // LLVM_CLANG_BASIC_MODULE_H diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f64d7c60783e..57f37c502311 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6284,6 +6284,8 @@ def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf"]>; def mno_apxf : Flag<["-"], "mno-apxf">, Alias, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf"]>; +def mapx_inline_asm_use_gpr32 : Flag<["-"], "mapx-inline-asm-use-gpr32">, Group, + HelpText<"Enable use of GPR32 in inline assembly for APX">; } // let Flags = [TargetSpecific] // VE feature flags diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index 27e9167ca1ad..f8759bf2d8f2 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -17,7 +17,6 @@ #ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H #define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H -#include "clang/Basic/Module.h" #include "clang/ExtractAPI/API.h" #include "clang/ExtractAPI/APIIgnoresList.h" #include "clang/ExtractAPI/Serialization/APISetVisitor.h" diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index eb6647038403..4fd6e013df25 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -814,8 +814,8 @@ struct FormatStyle { enum ShortFunctionStyle : int8_t { /// Never merge functions into a single line. SFS_None, - /// Only merge functions defined inside a class. Same as "inline", - /// except it does not implies "empty": i.e. top level empty functions + /// Only merge functions defined inside a class. Same as ``inline``, + /// except it does not implies ``empty``: i.e. top level empty functions /// are not merged either. /// \code /// class Foo { @@ -836,7 +836,7 @@ struct FormatStyle { /// } /// \endcode SFS_Empty, - /// Only merge functions defined inside a class. Implies "empty". + /// Only merge functions defined inside a class. Implies ``empty``. /// \code /// class Foo { /// void f() { foo(); } @@ -1167,7 +1167,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// AttributeMacros: ['__capability', '__output', '__unused'] + /// AttributeMacros: [__capability, __output, __unused] /// \endcode /// /// \version 12 @@ -2631,7 +2631,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// ForEachMacros: ['RANGES_FOR', 'FOREACH'] + /// ForEachMacros: [RANGES_FOR, FOREACH] /// \endcode /// /// For example: BOOST_FOREACH. @@ -2653,7 +2653,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// IfMacros: ['IF'] + /// IfMacros: [IF] /// \endcode /// /// For example: `KJ_IF_MAYBE @@ -3030,7 +3030,7 @@ struct FormatStyle { /// in the following yaml example. This will result in imports being /// formatted as in the Java example below. /// \code{.yaml} - /// JavaImportGroups: ['com.example', 'com', 'org'] + /// JavaImportGroups: [com.example, com, org] /// \endcode /// /// \code{.java} @@ -3086,7 +3086,7 @@ struct FormatStyle { /// VeryLongImportsAreAnnoying, /// VeryLongImportsAreAnnoying, /// VeryLongImportsAreAnnoying, - /// } from 'some/module.js' + /// } from "some/module.js" /// /// false: /// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" @@ -3615,7 +3615,7 @@ struct FormatStyle { /// Change specifiers/qualifiers to be aligned based on ``QualifierOrder``. /// With: /// \code{.yaml} - /// QualifierOrder: ['inline', 'static', 'type', 'const'] + /// QualifierOrder: [inline, static, type, const] /// \endcode /// /// \code @@ -3650,15 +3650,15 @@ struct FormatStyle { /// * type /// /// \note - /// it MUST contain 'type'. + /// It **must** contain ``type``. /// \endnote /// - /// Items to the left of 'type' will be placed to the left of the type and - /// aligned in the order supplied. Items to the right of 'type' will be + /// Items to the left of ``type`` will be placed to the left of the type and + /// aligned in the order supplied. Items to the right of ``type`` will be /// placed to the right of the type and aligned in the order supplied. /// /// \code{.yaml} - /// QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ] + /// QualifierOrder: [inline, static, type, const, volatile] /// \endcode /// \version 14 std::vector QualifierOrder; @@ -3692,10 +3692,10 @@ struct FormatStyle { /// name will be reformatted assuming the specified language based on the /// style for that language defined in the .clang-format file. If no style has /// been defined in the .clang-format file for the specific language, a - /// predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not - /// found, the formatting is based on llvm style. A matching delimiter takes - /// precedence over a matching enclosing function name for determining the - /// language of the raw string contents. + /// predefined style given by ``BasedOnStyle`` is used. If ``BasedOnStyle`` is + /// not found, the formatting is based on ``LLVM`` style. A matching delimiter + /// takes precedence over a matching enclosing function name for determining + /// the language of the raw string contents. /// /// If a canonical delimiter is specified, occurrences of other delimiters for /// the same language will be updated to the canonical if possible. @@ -3708,17 +3708,17 @@ struct FormatStyle { /// RawStringFormats: /// - Language: TextProto /// Delimiters: - /// - 'pb' - /// - 'proto' + /// - pb + /// - proto /// EnclosingFunctions: - /// - 'PARSE_TEXT_PROTO' + /// - PARSE_TEXT_PROTO /// BasedOnStyle: google /// - Language: Cpp /// Delimiters: - /// - 'cc' - /// - 'cpp' - /// BasedOnStyle: llvm - /// CanonicalDelimiter: 'cc' + /// - cc + /// - cpp + /// BasedOnStyle: LLVM + /// CanonicalDelimiter: cc /// \endcode /// \version 6 std::vector RawStringFormats; @@ -4046,7 +4046,7 @@ struct FormatStyle { /// /// This determines the maximum length of short namespaces by counting /// unwrapped lines (i.e. containing neither opening nor closing - /// namespace brace) and makes "FixNamespaceComments" omit adding + /// namespace brace) and makes ``FixNamespaceComments`` omit adding /// end comments for those. /// \code /// ShortNamespaceLines: 1 vs. ShortNamespaceLines: 0 @@ -4138,7 +4138,7 @@ struct FormatStyle { /// \endcode SUD_Never, /// Using declarations are sorted in the order defined as follows: - /// Split the strings by "::" and discard any initial empty strings. Sort + /// Split the strings by ``::`` and discard any initial empty strings. Sort /// the lists of names lexicographically, and within those groups, names are /// in case-insensitive lexicographic order. /// \code @@ -4150,7 +4150,7 @@ struct FormatStyle { /// \endcode SUD_Lexicographic, /// Using declarations are sorted in the order defined as follows: - /// Split the strings by "::" and discard any initial empty strings. The + /// Split the strings by ``::`` and discard any initial empty strings. The /// last element of each list is a non-namespace name; all others are /// namespace names. Sort the lists of names lexicographically, where the /// sort order of individual names is that all non-namespace names come @@ -4186,7 +4186,7 @@ struct FormatStyle { /// \version 9 bool SpaceAfterLogicalNot; - /// If \c true, a space will be inserted after the 'template' keyword. + /// If \c true, a space will be inserted after the ``template`` keyword. /// \code /// true: false: /// template void foo(); vs. template void foo(); @@ -4316,7 +4316,7 @@ struct FormatStyle { /// \endcode SBPO_ControlStatementsExceptControlMacros, /// Put a space before opening parentheses only if the parentheses are not - /// empty i.e. '()' + /// empty. /// \code /// void() { /// if (true) { @@ -4668,7 +4668,7 @@ struct FormatStyle { /// x = ( int32 )y vs. x = (int32)y /// \endcode bool InCStyleCasts; - /// Put a space in parentheses only if the parentheses are empty i.e. '()' + /// Insert a space in empty parentheses, i.e. ``()``. /// \code /// true: false: /// void f( ) { vs. void f() { @@ -4804,11 +4804,11 @@ struct FormatStyle { /// For example the configuration, /// \code{.yaml} /// TableGenBreakInsideDAGArg: BreakAll - /// TableGenBreakingDAGArgOperators: ['ins', 'outs'] + /// TableGenBreakingDAGArgOperators: [ins, outs] /// \endcode /// /// makes the line break only occurs inside DAGArgs beginning with the - /// specified identifiers 'ins' and 'outs'. + /// specified identifiers ``ins`` and ``outs``. /// /// \code /// let DAGArgIns = (ins @@ -4873,7 +4873,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// TypenameMacros: ['STACK_OF', 'LIST'] + /// TypenameMacros: [STACK_OF, LIST] /// \endcode /// /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY. @@ -4929,7 +4929,7 @@ struct FormatStyle { /// /// In the .clang-format configuration file, this can be configured like: /// \code{.yaml} - /// WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + /// WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE] /// \endcode /// /// For example: BOOST_PP_STRINGIZE diff --git a/clang/include/clang/Lex/DependencyDirectivesScanner.h b/clang/include/clang/Lex/DependencyDirectivesScanner.h index 0e115906fbfe..2f8354dec939 100644 --- a/clang/include/clang/Lex/DependencyDirectivesScanner.h +++ b/clang/include/clang/Lex/DependencyDirectivesScanner.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H #define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H +#include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" @@ -117,7 +118,7 @@ struct Directive { bool scanSourceForDependencyDirectives( StringRef Input, SmallVectorImpl &Tokens, SmallVectorImpl &Directives, - DiagnosticsEngine *Diags = nullptr, + const LangOptions &LangOpts, DiagnosticsEngine *Diags = nullptr, SourceLocation InputSourceLoc = SourceLocation()); /// Print the previously scanned dependency directives as minimized source text. diff --git a/clang/include/clang/Sema/Attr.h b/clang/include/clang/Sema/Attr.h new file mode 100644 index 000000000000..1133862568a6 --- /dev/null +++ b/clang/include/clang/Sema/Attr.h @@ -0,0 +1,36 @@ +//===----- Attr.h --- Helper functions for attribute handling in Sema -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides helpers for Sema functions that handle attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_ATTR_H +#define LLVM_CLANG_SEMA_ATTR_H + +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "llvm/Support/Casting.h" + +namespace clang { + +/// isFuncOrMethodForAttrSubject - Return true if the given decl has function +/// type (function or function-typed variable) or an Objective-C +/// method. +inline bool isFuncOrMethodForAttrSubject(const Decl *D) { + return (D->getFunctionType() != nullptr) || llvm::isa(D); +} + +/// Return true if the given decl has function type (function or +/// function-typed variable) or an Objective-C method or a block. +inline bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D) { + return isFuncOrMethodForAttrSubject(D) || llvm::isa(D); +} + +} // namespace clang +#endif // LLVM_CLANG_SEMA_ATTR_H diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e6296868000c..7dea2b6826cf 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -67,6 +67,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/TinyPtrVector.h" #include #include @@ -168,15 +169,25 @@ class Preprocessor; class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; +class SemaAMDGPU; +class SemaARM; +class SemaBPF; class SemaCodeCompletion; class SemaCUDA; class SemaHLSL; +class SemaHexagon; +class SemaLoongArch; +class SemaMIPS; +class SemaNVPTX; class SemaObjC; class SemaOpenACC; class SemaOpenMP; +class SemaPPC; class SemaPseudoObject; class SemaRISCV; class SemaSYCL; +class SemaSystemZ; +class SemaWasm; class SemaX86; class StandardConversionSequence; class Stmt; @@ -884,9 +895,6 @@ public: void disable() { Active = false; } }; - /// Build a partial diagnostic. - PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h - sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.empty() ? nullptr : FunctionScopes.back(); } @@ -993,6 +1001,21 @@ public: /// CurContext - This is the current declaration context of parsing. DeclContext *CurContext; + SemaAMDGPU &AMDGPU() { + assert(AMDGPUPtr); + return *AMDGPUPtr; + } + + SemaARM &ARM() { + assert(ARMPtr); + return *ARMPtr; + } + + SemaBPF &BPF() { + assert(BPFPtr); + return *BPFPtr; + } + SemaCodeCompletion &CodeCompletion() { assert(CodeCompletionPtr); return *CodeCompletionPtr; @@ -1008,6 +1031,26 @@ public: return *HLSLPtr; } + SemaHexagon &Hexagon() { + assert(HexagonPtr); + return *HexagonPtr; + } + + SemaLoongArch &LoongArch() { + assert(LoongArchPtr); + return *LoongArchPtr; + } + + SemaMIPS &MIPS() { + assert(MIPSPtr); + return *MIPSPtr; + } + + SemaNVPTX &NVPTX() { + assert(NVPTXPtr); + return *NVPTXPtr; + } + SemaObjC &ObjC() { assert(ObjCPtr); return *ObjCPtr; @@ -1023,6 +1066,11 @@ public: return *OpenMPPtr; } + SemaPPC &PPC() { + assert(PPCPtr); + return *PPCPtr; + } + SemaPseudoObject &PseudoObject() { assert(PseudoObjectPtr); return *PseudoObjectPtr; @@ -1038,6 +1086,16 @@ public: return *SYCLPtr; } + SemaSystemZ &SystemZ() { + assert(SystemZPtr); + return *SystemZPtr; + } + + SemaWasm &Wasm() { + assert(WasmPtr); + return *WasmPtr; + } + SemaX86 &X86() { assert(X86Ptr); return *X86Ptr; @@ -1073,15 +1131,25 @@ private: mutable IdentifierInfo *Ident_super; + std::unique_ptr AMDGPUPtr; + std::unique_ptr ARMPtr; + std::unique_ptr BPFPtr; std::unique_ptr CodeCompletionPtr; std::unique_ptr CUDAPtr; std::unique_ptr HLSLPtr; + std::unique_ptr HexagonPtr; + std::unique_ptr LoongArchPtr; + std::unique_ptr MIPSPtr; + std::unique_ptr NVPTXPtr; std::unique_ptr ObjCPtr; std::unique_ptr OpenACCPtr; std::unique_ptr OpenMPPtr; + std::unique_ptr PPCPtr; std::unique_ptr PseudoObjectPtr; std::unique_ptr RISCVPtr; std::unique_ptr SYCLPtr; + std::unique_ptr SystemZPtr; + std::unique_ptr WasmPtr; std::unique_ptr X86Ptr; ///@} @@ -2074,6 +2142,8 @@ public: unsigned MaxArgCount); bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount); + bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum); + private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, @@ -2087,8 +2157,6 @@ private: ArrayRef Args, const FunctionProtoType *Proto, SourceLocation Loc); - void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg); - void CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, StringRef ParamName, QualType ArgTy, QualType ParamTy); @@ -2102,54 +2170,13 @@ private: void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); - bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, - unsigned MaxWidth); - bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool ParseSVEImmChecks(CallExpr *TheCall, - SmallVector, 3> &ImmChecks); - bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, - bool WantCDE); - bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - - bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); - bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); - bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - - bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, CallExpr *TheCall); - bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall); - bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - bool BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall); bool BuiltinVAStartARMMicrosoft(CallExpr *Call); bool BuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID); bool BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, unsigned BuiltinID); bool BuiltinComplex(CallExpr *TheCall); - bool BuiltinVSX(CallExpr *TheCall); bool BuiltinOSLogFormat(CallExpr *TheCall); - bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum); bool BuiltinPrefetch(CallExpr *TheCall); bool BuiltinAllocaWithAlign(CallExpr *TheCall); @@ -2162,13 +2189,6 @@ private: ExprResult BuiltinNontemporalOverloaded(ExprResult TheCallResult); ExprResult AtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op); - bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, - unsigned ExpectedFieldNum, bool AllowName); - bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); - bool BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, - const char *TypeDesc); - - bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc); bool BuiltinElementwiseMath(CallExpr *TheCall); bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, @@ -2185,16 +2205,6 @@ private: ExprResult BuiltinMatrixColumnMajorStore(CallExpr *TheCall, ExprResult CallResult); - // WebAssembly builtin handling. - bool BuiltinWasmRefNullExtern(CallExpr *TheCall); - bool BuiltinWasmRefNullFunc(CallExpr *TheCall); - bool BuiltinWasmTableGet(CallExpr *TheCall); - bool BuiltinWasmTableSet(CallExpr *TheCall); - bool BuiltinWasmTableSize(CallExpr *TheCall); - bool BuiltinWasmTableGrow(CallExpr *TheCall); - bool BuiltinWasmTableFill(CallExpr *TheCall); - bool BuiltinWasmTableCopy(CallExpr *TheCall); - bool CheckFormatArguments(const FormatAttr *Format, ArrayRef Args, bool IsCXXMember, VariadicCallType CallType, SourceLocation Loc, @@ -3548,6 +3558,53 @@ public: BuiltinFunction }; + /// A helper function to provide Attribute Location for the Attr types + /// AND the ParsedAttr. + template + static std::enable_if_t, SourceLocation> + getAttrLoc(const AttrInfo &AL) { + return AL.getLocation(); + } + SourceLocation getAttrLoc(const ParsedAttr &AL); + + /// If Expr is a valid integer constant, get the value of the integer + /// expression and return success or failure. May output an error. + /// + /// Negative argument is implicitly converted to unsigned, unless + /// \p StrictlyUnsigned is true. + template + bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val, + unsigned Idx = UINT_MAX, + bool StrictlyUnsigned = false) { + std::optional I = llvm::APSInt(32); + if (Expr->isTypeDependent() || + !(I = Expr->getIntegerConstantExpr(Context))) { + if (Idx != UINT_MAX) + Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) + << &AI << Idx << AANT_ArgumentIntegerConstant + << Expr->getSourceRange(); + else + Diag(getAttrLoc(AI), diag::err_attribute_argument_type) + << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange(); + return false; + } + + if (!I->isIntN(32)) { + Diag(Expr->getExprLoc(), diag::err_ice_too_large) + << toString(*I, 10, false) << 32 << /* Unsigned */ 1; + return false; + } + + if (StrictlyUnsigned && I->isSigned() && I->isNegative()) { + Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer) + << &AI << /*non-negative*/ 1; + return false; + } + + Val = (uint32_t)I->getZExtValue(); + return true; + } + /// WeakTopLevelDecl - Translation-unit scoped declarations generated by /// \#pragma weak during processing of other Decls. /// I couldn't figure out a clean way to generate these in-line, so @@ -3705,41 +3762,6 @@ public: BTFDeclTagAttr *mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL); - WebAssemblyImportNameAttr * - mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL); - WebAssemblyImportModuleAttr * - mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL); - - /// Create an AMDGPUWavesPerEUAttr attribute. - AMDGPUFlatWorkGroupSizeAttr * - CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, - Expr *Max); - - /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size - /// attribute to a particular declaration. - void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *Min, Expr *Max); - - /// Create an AMDGPUWavesPerEUAttr attribute. - AMDGPUWavesPerEUAttr * - CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, - Expr *Max); - - /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a - /// particular declaration. - void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *Min, Expr *Max); - - /// Create an AMDGPUMaxNumWorkGroupsAttr attribute. - AMDGPUMaxNumWorkGroupsAttr * - CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, - Expr *YExpr, Expr *ZExpr); - - /// addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups - /// attribute to a particular declaration. - void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *XExpr, Expr *YExpr, Expr *ZExpr); - DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI); DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI); MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D, diff --git a/clang/include/clang/Sema/SemaAMDGPU.h b/clang/include/clang/Sema/SemaAMDGPU.h new file mode 100644 index 000000000000..969078f552c6 --- /dev/null +++ b/clang/include/clang/Sema/SemaAMDGPU.h @@ -0,0 +1,68 @@ +//===----- SemaAMDGPU.h --- AMDGPU target-specific routines ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to AMDGPU. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAAMDGPU_H +#define LLVM_CLANG_SEMA_SEMAAMDGPU_H + +#include "clang/AST/Attr.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" +#include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Sema/ParsedAttr.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaAMDGPU : public SemaBase { +public: + SemaAMDGPU(Sema &S); + + bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + + /// Create an AMDGPUWavesPerEUAttr attribute. + AMDGPUFlatWorkGroupSizeAttr * + CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, + Expr *Max); + + /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size + /// attribute to a particular declaration. + void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *Min, Expr *Max); + + /// Create an AMDGPUWavesPerEUAttr attribute. + AMDGPUWavesPerEUAttr * + CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, + Expr *Max); + + /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a + /// particular declaration. + void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *Min, Expr *Max); + + /// Create an AMDGPUMaxNumWorkGroupsAttr attribute. + AMDGPUMaxNumWorkGroupsAttr * + CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, + Expr *YExpr, Expr *ZExpr); + + /// addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups + /// attribute to a particular declaration. + void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *XExpr, Expr *YExpr, Expr *ZExpr); + + void handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL); + void handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL); + void handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL); + void handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, const ParsedAttr &AL); + void handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, const ParsedAttr &AL); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAAMDGPU_H diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h new file mode 100644 index 000000000000..02698a33abd5 --- /dev/null +++ b/clang/include/clang/Sema/SemaARM.h @@ -0,0 +1,63 @@ +//===----- SemaARM.h ------- ARM target-specific routines -----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to ARM. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAARM_H +#define LLVM_CLANG_SEMA_SEMAARM_H + +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" +#include "llvm/ADT/SmallVector.h" +#include + +namespace clang { + +class SemaARM : public SemaBase { +public: + SemaARM(Sema &S); + + enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 + }; + + bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, + unsigned MaxWidth); + bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool + ParseSVEImmChecks(CallExpr *TheCall, + llvm::SmallVector, 3> &ImmChecks); + bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, + bool WantCDE); + bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + + bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, + unsigned ExpectedFieldNum, bool AllowName); + bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); +}; + +SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); + +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAARM_H diff --git a/clang/include/clang/Sema/SemaBPF.h b/clang/include/clang/Sema/SemaBPF.h new file mode 100644 index 000000000000..a3bf59128d25 --- /dev/null +++ b/clang/include/clang/Sema/SemaBPF.h @@ -0,0 +1,28 @@ +//===----- SemaBPF.h ------- BPF target-specific routines -----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to BPF. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMABPF_H +#define LLVM_CLANG_SEMA_SEMABPF_H + +#include "clang/AST/Expr.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaBPF : public SemaBase { +public: + SemaBPF(Sema &S); + + bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMABPF_H diff --git a/clang/include/clang/Sema/SemaBase.h b/clang/include/clang/Sema/SemaBase.h index 3220f71dd797..0b05245ab968 100644 --- a/clang/include/clang/Sema/SemaBase.h +++ b/clang/include/clang/Sema/SemaBase.h @@ -217,6 +217,9 @@ public: /// Emit a partial diagnostic. SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic &PD, bool DeferHint = false); + + /// Build a partial diagnostic. + PartialDiagnostic PDiag(unsigned DiagID = 0); }; } // namespace clang diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 34acaf19517f..eac1f7c07c85 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -49,6 +49,7 @@ public: void DiagnoseAttrStageMismatch( const Attr *A, HLSLShaderAttr::ShaderType Stage, std::initializer_list AllowedStages); + void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); }; } // namespace clang diff --git a/clang/include/clang/Sema/SemaHexagon.h b/clang/include/clang/Sema/SemaHexagon.h new file mode 100644 index 000000000000..2d4a04f824bc --- /dev/null +++ b/clang/include/clang/Sema/SemaHexagon.h @@ -0,0 +1,29 @@ +//===----- SemaHexagon.h -- Hexagon target-specific routines --*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to Hexagon. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAHEXAGON_H +#define LLVM_CLANG_SEMA_SEMAHEXAGON_H + +#include "clang/AST/Expr.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaHexagon : public SemaBase { +public: + SemaHexagon(Sema &S); + + bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAHEXAGON_H diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 842eec099540..d994d1819b44 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -21,10 +21,6 @@ namespace clang { -inline PartialDiagnostic Sema::PDiag(unsigned DiagID) { - return PartialDiagnostic(DiagID, Context.getDiagAllocator()); -} - inline bool FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) { return FTI.NumParams == 1 && !FTI.isVariadic && diff --git a/clang/include/clang/Sema/SemaLoongArch.h b/clang/include/clang/Sema/SemaLoongArch.h new file mode 100644 index 000000000000..aef0df9e8710 --- /dev/null +++ b/clang/include/clang/Sema/SemaLoongArch.h @@ -0,0 +1,30 @@ +//===-- SemaLoongArch.h -- LoongArch target-specific routines --*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to LoongArch. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMALOONGARCH_H +#define LLVM_CLANG_SEMA_SEMALOONGARCH_H + +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaLoongArch : public SemaBase { +public: + SemaLoongArch(Sema &S); + + bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMALOONGARCH_H diff --git a/clang/include/clang/Sema/SemaMIPS.h b/clang/include/clang/Sema/SemaMIPS.h new file mode 100644 index 000000000000..3f1781b36efd --- /dev/null +++ b/clang/include/clang/Sema/SemaMIPS.h @@ -0,0 +1,33 @@ +//===----- SemaMIPS.h ------ MIPS target-specific routines ----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to MIPS. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAMIPS_H +#define LLVM_CLANG_SEMA_SEMAMIPS_H + +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaMIPS : public SemaBase { +public: + SemaMIPS(Sema &S); + + bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAMIPS_H diff --git a/clang/include/clang/Sema/SemaNVPTX.h b/clang/include/clang/Sema/SemaNVPTX.h new file mode 100644 index 000000000000..a663c694179d --- /dev/null +++ b/clang/include/clang/Sema/SemaNVPTX.h @@ -0,0 +1,30 @@ +//===----- SemaNVPTX.h ----- NVPTX target-specific routines ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to NVPTX. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMANVPTX_H +#define LLVM_CLANG_SEMA_SEMANVPTX_H + +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaNVPTX : public SemaBase { +public: + SemaNVPTX(Sema &S); + + bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMANVPTX_H diff --git a/clang/include/clang/Sema/SemaPPC.h b/clang/include/clang/Sema/SemaPPC.h new file mode 100644 index 000000000000..3e8929d5b6de --- /dev/null +++ b/clang/include/clang/Sema/SemaPPC.h @@ -0,0 +1,58 @@ +//===----- SemaPPC.h ------- PPC target-specific routines -----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to PowerPC. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAPPC_H +#define LLVM_CLANG_SEMA_SEMAPPC_H + +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaPPC : public SemaBase { +public: + SemaPPC(Sema &S); + + bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + // 16 byte ByVal alignment not due to a vector member is not honoured by XL + // on AIX. Emit a warning here that users are generating binary incompatible + // code to be safe. + // Here we try to get information about the alignment of the struct member + // from the struct passed to the caller function. We only warn when the struct + // is passed byval, hence the series of checks and early returns if we are a + // not passing a struct byval. + void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg); + + /// BuiltinPPCMMACall - Check the call to a PPC MMA builtin for validity. + /// Emit an error and return true on failure; return false on success. + /// TypeStr is a string containing the type descriptor of the value returned + /// by the builtin and the descriptors of the expected type of the arguments. + bool BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, + const char *TypeDesc); + + bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc); + + // Customized Sema Checking for VSX builtins that have the following + // signature: vector [...] builtinName(vector [...], vector [...], const int); + // Which takes the same type of vectors (any legal vector type) for the first + // two arguments and takes compile time constant for the third argument. + // Example builtins are : + // vector double vec_xxpermdi(vector double, vector double, int); + // vector short vec_xxsldwi(vector short, vector short, int); + bool BuiltinVSX(CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAPPC_H diff --git a/clang/include/clang/Sema/SemaSystemZ.h b/clang/include/clang/Sema/SemaSystemZ.h new file mode 100644 index 000000000000..8945471d53d6 --- /dev/null +++ b/clang/include/clang/Sema/SemaSystemZ.h @@ -0,0 +1,28 @@ +//===----- SemaSystemZ.h -- SystemZ target-specific routines --*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to SystemZ. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMASYSTEMZ_H +#define LLVM_CLANG_SEMA_SEMASYSTEMZ_H + +#include "clang/AST/Expr.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaSystemZ : public SemaBase { +public: + SemaSystemZ(Sema &S); + + bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMASYSTEMZ_H diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h new file mode 100644 index 000000000000..c3c781535024 --- /dev/null +++ b/clang/include/clang/Sema/SemaWasm.h @@ -0,0 +1,52 @@ +//===----- SemaWasm.h ------ Wasm target-specific routines ----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to Wasm. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAWASM_H +#define LLVM_CLANG_SEMA_SEMAWASM_H + +#include "clang/AST/Attr.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/ParsedAttr.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaWasm : public SemaBase { +public: + SemaWasm(Sema &S); + + bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall); + + bool BuiltinWasmRefNullExtern(CallExpr *TheCall); + bool BuiltinWasmRefNullFunc(CallExpr *TheCall); + bool BuiltinWasmTableGet(CallExpr *TheCall); + bool BuiltinWasmTableSet(CallExpr *TheCall); + bool BuiltinWasmTableSize(CallExpr *TheCall); + bool BuiltinWasmTableGrow(CallExpr *TheCall); + bool BuiltinWasmTableFill(CallExpr *TheCall); + bool BuiltinWasmTableCopy(CallExpr *TheCall); + + WebAssemblyImportNameAttr * + mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL); + WebAssemblyImportModuleAttr * + mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL); + + void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL); + void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL); + void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAWASM_H diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 4ece4593f073..bea58d60d36c 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -429,6 +429,9 @@ private: FileManager &FileMgr; const PCHContainerReader &PCHContainerRdr; DiagnosticsEngine &Diags; + // Sema has duplicate logic, but SemaObj can sometimes be null so ASTReader + // has its own version. + bool WarnedStackExhausted = false; /// The semantic analysis object that will be processing the /// AST files and the translation unit that uses it. @@ -2135,6 +2138,8 @@ public: /// Report a diagnostic. DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const; + void warnStackExhausted(SourceLocation Loc); + IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); IdentifierInfo *readIdentifier(ModuleFile &M, const RecordData &Record, diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 88192e439a3f..fcc007d6f863 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -18,7 +18,6 @@ #include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" diff --git a/clang/include/clang/Serialization/ModuleManager.h b/clang/include/clang/Serialization/ModuleManager.h index 3bd379acf7ed..d770bc52eaf4 100644 --- a/clang/include/clang/Serialization/ModuleManager.h +++ b/clang/include/clang/Serialization/ModuleManager.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ModuleFile.h" #include "llvm/ADT/DenseMap.h" diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 40f443047bd4..668e9f6cf071 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -509,6 +509,10 @@ def UnixAPIMisuseChecker : Checker<"API">, HelpText<"Check calls to various UNIX/Posix functions">, Documentation; +def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, + HelpText<"Check for calls to blocking functions inside a critical section">, + Documentation; + def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">, HelpText<"The base of several malloc() related checkers. On it's own it " "emits no reports, but adds valuable information to the analysis " @@ -619,10 +623,6 @@ def SimpleStreamChecker : Checker<"SimpleStream">, HelpText<"Check for misuses of stream APIs">, Documentation; -def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, - HelpText<"Check for calls to blocking functions inside a critical section">, - Documentation; - } // end "alpha.unix" //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h index f7b4510d7f7b..9dc20065a09a 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -363,7 +363,8 @@ public: /// /// Returns true if the directive tokens are populated for this file entry, /// false if not (i.e. this entry is not a file or its scan fails). - bool ensureDirectiveTokensArePopulated(EntryRef Entry); + bool ensureDirectiveTokensArePopulated(EntryRef Entry, + const LangOptions &LangOpts); /// Check whether \p Path exists. By default checks cached result of \c /// status(), and falls back on FS if unable to do so. diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 789bb97d81de..039d09fa7cf5 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -12,6 +12,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceMgrAdapter.h" #include "clang/Basic/Version.h" diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 06780ceba407..73d3b152c49f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -6794,7 +6794,7 @@ bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const { // Using shadow declarations with the same target match. if (const auto *USX = dyn_cast(X)) { const auto *USY = cast(Y); - return USX->getTargetDecl() == USY->getTargetDecl(); + return declaresSameEntity(USX->getTargetDecl(), USY->getTargetDecl()); } // Using declarations with the same qualifier match. (We already know that diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 6efc5bb92e28..c8973fdeda35 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -17,7 +17,6 @@ #include "clang/AST/DeclLookups.h" #include "clang/AST/JSONNodeDumper.h" #include "clang/Basic/Builtins.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 41fbfe281ef6..0a35ed536a6a 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2408,9 +2408,11 @@ Expr *VarDecl::getInit() { return cast(S); auto *Eval = getEvaluatedStmt(); - return cast(Eval->Value.isOffset() - ? Eval->Value.get(getASTContext().getExternalSource()) - : Eval->Value.get(nullptr)); + + return cast_if_present( + Eval->Value.isOffset() + ? Eval->Value.get(getASTContext().getExternalSource()) + : Eval->Value.get(nullptr)); } Stmt **VarDecl::getInitAddress() { diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 65d5eeb6354e..ffb22194bce5 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -669,7 +669,8 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, IdentifierInfo *IIEnv = A->getEnvironment(); StringRef TargetEnv = Context.getTargetInfo().getTriple().getEnvironmentName(); - StringRef EnvName = AvailabilityAttr::getPrettyEnviromentName(TargetEnv); + StringRef EnvName = AvailabilityAttr::getPrettyEnviromentName( + Context.getTargetInfo().getTriple().getEnvironment()); // Matching environment or no environment on attribute if (!IIEnv || (!TargetEnv.empty() && IIEnv->getName() == TargetEnv)) { if (Message) { diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index e96a47496851..a5b6f80bde69 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -15,10 +15,10 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/ErrorHandling.h" #include diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp index 066377423df7..18ac4b1eb57e 100644 --- a/clang/lib/AST/QualTypeNames.cpp +++ b/clang/lib/AST/QualTypeNames.cpp @@ -65,8 +65,9 @@ static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, assert(ArgTDecl != nullptr); QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName(); - if (QTName && !QTName->hasTemplateKeyword()) { - NNS = QTName->getQualifier(); + if (QTName && + !QTName->hasTemplateKeyword() && + (NNS = QTName->getQualifier())) { NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier( Ctx, NNS, WithGlobalNsPrefix); if (QNNS != NNS) { diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index a0eedc71ea22..0e0e0a86f5cf 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1126,7 +1126,32 @@ void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) { dumpTemplateArgument(TA); } -void TextNodeDumper::dumpTemplateName(TemplateName TN) { +void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) { + AddChild(Label, [=] { + { + llvm::SmallString<128> Str; + { + llvm::raw_svector_ostream SS(Str); + TN.print(SS, PrintPolicy); + } + OS << " '" << Str << "'"; + + if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN); + CanonTN != TN) { + llvm::SmallString<128> CanonStr; + { + llvm::raw_svector_ostream SS(CanonStr); + CanonTN.print(SS, PrintPolicy); + } + if (CanonStr != Str) + OS << ":'" << CanonStr << "'"; + } + } + dumpBareTemplateName(TN); + }); +} + +void TextNodeDumper::dumpBareTemplateName(TemplateName TN) { switch (TN.getKind()) { case TemplateName::Template: AddChild([=] { Visit(TN.getAsTemplateDecl()); }); @@ -1143,7 +1168,7 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN) { if (QTN->hasTemplateKeyword()) OS << " keyword"; dumpNestedNameSpecifier(QTN->getQualifier()); - dumpTemplateName(QTN->getUnderlyingTemplate()); + dumpBareTemplateName(QTN->getUnderlyingTemplate()); return; } case TemplateName::DependentTemplate: { @@ -1162,7 +1187,7 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN) { if (const TemplateTemplateParmDecl *P = STS->getParameter()) AddChild("parameter", [=] { Visit(P); }); dumpDeclRef(STS->getAssociatedDecl(), "associated"); - AddChild("replacement", [=] { dumpTemplateName(STS->getReplacement()); }); + dumpTemplateName(STS->getReplacement(), "replacement"); return; } // FIXME: Implement these. @@ -1182,14 +1207,14 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN) { void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) { OS << " template"; dumpTemplateArgument(TA); - dumpTemplateName(TA.getAsTemplate()); + dumpBareTemplateName(TA.getAsTemplate()); } void TextNodeDumper::VisitTemplateExpansionTemplateArgument( const TemplateArgument &TA) { OS << " template expansion"; dumpTemplateArgument(TA); - dumpTemplateName(TA.getAsTemplateOrTemplatePattern()); + dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern()); } void TextNodeDumper::VisitExpressionTemplateArgument( @@ -1989,18 +2014,14 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) { void TextNodeDumper::VisitDeducedTemplateSpecializationType( const DeducedTemplateSpecializationType *T) { - if (T->getTemplateName().getAsUsingShadowDecl()) - OS << " using"; + dumpTemplateName(T->getTemplateName(), "name"); } void TextNodeDumper::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { if (T->isTypeAlias()) OS << " alias"; - if (T->getTemplateName().getAsUsingShadowDecl()) - OS << " using"; - OS << " "; - T->getTemplateName().dump(OS); + dumpTemplateName(T->getTemplateName(), "name"); } void TextNodeDumper::VisitInjectedClassNameType( diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index bd1676583ecc..38b5f51b7b2f 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -188,90 +188,96 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) { return nullptr; } -static void getReferencedDecls(const Decl &D, ReferencedDecls &Referenced) { - insertIfGlobal(D, Referenced.Globals); - insertIfFunction(D, Referenced.Functions); - if (const auto *Decomp = dyn_cast(&D)) - for (const auto *B : Decomp->bindings()) - if (auto *ME = dyn_cast_or_null(B->getBinding())) - // FIXME: should we be using `E->getFoundDecl()`? - if (const auto *FD = dyn_cast(ME->getMemberDecl())) - Referenced.Fields.insert(FD); -} +class ReferencedDeclsVisitor + : public AnalysisASTVisitor { +public: + ReferencedDeclsVisitor(ReferencedDecls &Referenced) + : Referenced(Referenced) {} + + void TraverseConstructorInits(const CXXConstructorDecl *Ctor) { + for (const CXXCtorInitializer *Init : Ctor->inits()) { + if (Init->isMemberInitializer()) { + Referenced.Fields.insert(Init->getMember()); + } else if (Init->isIndirectMemberInitializer()) { + for (const auto *I : Init->getIndirectMember()->chain()) + Referenced.Fields.insert(cast(I)); + } + + Expr *InitExpr = Init->getInit(); + + // Also collect declarations referenced in `InitExpr`. + TraverseStmt(InitExpr); -/// Traverses `S` and inserts into `Referenced` any declarations that are -/// declared in or referenced from sub-statements. -static void getReferencedDecls(const Stmt &S, ReferencedDecls &Referenced) { - for (auto *Child : S.children()) - if (Child != nullptr) - getReferencedDecls(*Child, Referenced); - if (const auto *DefaultArg = dyn_cast(&S)) - getReferencedDecls(*DefaultArg->getExpr(), Referenced); - if (const auto *DefaultInit = dyn_cast(&S)) - getReferencedDecls(*DefaultInit->getExpr(), Referenced); - - if (auto *DS = dyn_cast(&S)) { - if (DS->isSingleDecl()) - getReferencedDecls(*DS->getSingleDecl(), Referenced); - else - for (auto *D : DS->getDeclGroup()) - getReferencedDecls(*D, Referenced); - } else if (auto *E = dyn_cast(&S)) { + // If this is a `CXXDefaultInitExpr`, also collect declarations referenced + // within the default expression. + if (auto *DefaultInit = dyn_cast(InitExpr)) + TraverseStmt(DefaultInit->getExpr()); + } + } + + bool VisitDecl(Decl *D) { + insertIfGlobal(*D, Referenced.Globals); + insertIfFunction(*D, Referenced.Functions); + return true; + } + + bool VisitDeclRefExpr(DeclRefExpr *E) { insertIfGlobal(*E->getDecl(), Referenced.Globals); insertIfFunction(*E->getDecl(), Referenced.Functions); - } else if (const auto *C = dyn_cast(&S)) { + return true; + } + + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) { // If this is a method that returns a member variable but does nothing else, // model the field of the return value. if (MemberExpr *E = getMemberForAccessor(*C)) if (const auto *FD = dyn_cast(E->getMemberDecl())) Referenced.Fields.insert(FD); - } else if (auto *E = dyn_cast(&S)) { + return true; + } + + bool VisitMemberExpr(MemberExpr *E) { // FIXME: should we be using `E->getFoundDecl()`? const ValueDecl *VD = E->getMemberDecl(); insertIfGlobal(*VD, Referenced.Globals); insertIfFunction(*VD, Referenced.Functions); if (const auto *FD = dyn_cast(VD)) Referenced.Fields.insert(FD); - } else if (auto *InitList = dyn_cast(&S)) { + return true; + } + + bool VisitInitListExpr(InitListExpr *InitList) { if (InitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(InitList)) Referenced.Fields.insert(FD); - } else if (auto *ParenInitList = dyn_cast(&S)) { + return true; + } + + bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) { if (ParenInitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(ParenInitList)) Referenced.Fields.insert(FD); + return true; } -} + +private: + ReferencedDecls &Referenced; +}; ReferencedDecls getReferencedDecls(const FunctionDecl &FD) { ReferencedDecls Result; - // Look for global variable and field references in the - // constructor-initializers. - if (const auto *CtorDecl = dyn_cast(&FD)) { - for (const auto *Init : CtorDecl->inits()) { - if (Init->isMemberInitializer()) { - Result.Fields.insert(Init->getMember()); - } else if (Init->isIndirectMemberInitializer()) { - for (const auto *I : Init->getIndirectMember()->chain()) - Result.Fields.insert(cast(I)); - } - const Expr *E = Init->getInit(); - assert(E != nullptr); - getReferencedDecls(*E, Result); - } - // Add all fields mentioned in default member initializers. - for (const FieldDecl *F : CtorDecl->getParent()->fields()) - if (const auto *I = F->getInClassInitializer()) - getReferencedDecls(*I, Result); - } - getReferencedDecls(*FD.getBody(), Result); + ReferencedDeclsVisitor Visitor(Result); + Visitor.TraverseStmt(FD.getBody()); + if (const auto *CtorDecl = dyn_cast(&FD)) + Visitor.TraverseConstructorInits(CtorDecl); return Result; } ReferencedDecls getReferencedDecls(const Stmt &S) { ReferencedDecls Result; - getReferencedDecls(S, Result); + ReferencedDeclsVisitor Visitor(Result); + Visitor.TraverseStmt(const_cast(&S)); return Result; } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 338a85525b38..0d7967c8b934 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -297,7 +297,7 @@ namespace { // Visitor that builds a map from record prvalues to result objects. // For each result object that it encounters, it propagates the storage location // of the result object to all record prvalues that can initialize it. -class ResultObjectVisitor : public RecursiveASTVisitor { +class ResultObjectVisitor : public AnalysisASTVisitor { public: // `ResultObjectMap` will be filled with a map from record prvalues to result // object. If this visitor will traverse a function that returns a record by @@ -310,10 +310,6 @@ public: : ResultObjectMap(ResultObjectMap), LocForRecordReturnVal(LocForRecordReturnVal), DACtx(DACtx) {} - bool shouldVisitImplicitCode() { return true; } - - bool shouldVisitLambdaBody() const { return false; } - // Traverse all member and base initializers of `Ctor`. This function is not // called by `RecursiveASTVisitor`; it should be called manually if we are // analyzing a constructor. `ThisPointeeLoc` is the storage location that @@ -342,37 +338,6 @@ public: } } - bool TraverseDecl(Decl *D) { - // Don't traverse nested record or function declarations. - // - We won't be analyzing code contained in these anyway - // - We don't model fields that are used only in these nested declaration, - // so trying to propagate a result object to initializers of such fields - // would cause an error. - if (isa_and_nonnull(D) || isa_and_nonnull(D)) - return true; - - return RecursiveASTVisitor::TraverseDecl(D); - } - - // Don't traverse expressions in unevaluated contexts, as we don't model - // fields that are only used in these. - // Note: The operand of the `noexcept` operator is an unevaluated operand, but - // nevertheless it appears in the Clang CFG, so we don't exclude it here. - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } - bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; } - bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { - return true; - } - - bool TraverseBindingDecl(BindingDecl *BD) { - // `RecursiveASTVisitor` doesn't traverse holding variables for - // `BindingDecl`s by itself, so we need to tell it to. - if (VarDecl *HoldingVar = BD->getHoldingVar()) - TraverseDecl(HoldingVar); - return RecursiveASTVisitor::TraverseBindingDecl(BD); - } - bool VisitVarDecl(VarDecl *VD) { if (VD->getType()->isRecordType() && VD->hasInit()) PropagateResultObject( diff --git a/clang/lib/Basic/ASTSourceDescriptor.cpp b/clang/lib/Basic/ASTSourceDescriptor.cpp new file mode 100644 index 000000000000..8072c08a51d3 --- /dev/null +++ b/clang/lib/Basic/ASTSourceDescriptor.cpp @@ -0,0 +1,33 @@ +//===- ASTSourceDescriptor.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules +/// and precompiled header files +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ASTSourceDescriptor.h" + +namespace clang { + +ASTSourceDescriptor::ASTSourceDescriptor(Module &M) + : Signature(M.Signature), ClangModule(&M) { + if (M.Directory) + Path = M.Directory->getName(); + if (auto File = M.getASTFile()) + ASTFile = File->getName(); +} + +std::string ASTSourceDescriptor::getModuleName() const { + if (ClangModule) + return ClangModule->Name; + else + return std::string(PCHModuleName); +} + +} // namespace clang diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 824d4a0e2eee..f30680552e0f 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -55,6 +55,7 @@ if(CLANG_VENDOR) endif() add_clang_library(clangBasic + ASTSourceDescriptor.cpp Attributes.cpp Builtins.cpp CLWarnings.cpp diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 045ef580f9c3..90b7b0d24bb6 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -724,18 +724,3 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, }; VisitModule({M, nullptr}); } - -ASTSourceDescriptor::ASTSourceDescriptor(Module &M) - : Signature(M.Signature), ClangModule(&M) { - if (M.Directory) - Path = M.Directory->getName(); - if (auto File = M.getASTFile()) - ASTFile = File->getName(); -} - -std::string ASTSourceDescriptor::getModuleName() const { - if (ClangModule) - return ClangModule->Name; - else - return std::string(PCHModuleName); -} diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 5db1ce78c657..0db16d4a8971 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1203,6 +1203,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { case CC_SwiftAsync: case CC_PreserveMost: case CC_PreserveAll: + case CC_PreserveNone: case CC_OpenCLKernel: case CC_AArch64VectorCall: case CC_AArch64SVEPCS: diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 08e44360bfbe..036a655a4d07 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -441,6 +441,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasFullBFloat16 = true; } else if (Feature == "+egpr") { HasEGPR = true; + } else if (Feature == "+inline-asm-use-gpr32") { + HasInlineAsmUseGPR32 = true; } else if (Feature == "+push2pop2") { HasPush2Pop2 = true; } else if (Feature == "+ppx") { @@ -963,6 +965,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, // Condition here is aligned with the feature set of mapxf in Options.td if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF) Builder.defineMacro("__APX_F__"); + if (HasEGPR && HasInlineAsmUseGPR32) + Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1478,6 +1482,18 @@ bool X86TargetInfo::validateAsmConstraint( case 'C': // SSE floating point constant. case 'G': // x87 floating point constant. return true; + case 'j': + Name++; + switch (*Name) { + default: + return false; + case 'r': + Info.setAllowsRegister(); + return true; + case 'R': + Info.setAllowsRegister(); + return true; + } case '@': // CC condition changes. if (auto Len = matchAsmCCConstraint(Name)) { @@ -1750,6 +1766,21 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("^") + std::string(Constraint++, 2); } [[fallthrough]]; + case 'j': + switch (Constraint[1]) { + default: + // Break from inner switch and fall through (copy single char), + // continue parsing after copying the current constraint into + // the return string. + break; + case 'r': + case 'R': + // "^" hints llvm that this is a 2 letter constraint. + // "Constraint++" is used to promote the string iterator + // to the next constraint. + return std::string("^") + std::string(Constraint++, 2); + } + [[fallthrough]]; default: return std::string(1, *Constraint); } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 0633b7e0da96..9b2ae87adb2e 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -172,6 +172,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasCCMP = false; bool HasNF = false; bool HasCF = false; + bool HasInlineAsmUseGPR32 = false; protected: llvm::X86::CPUKind CPU = llvm::X86::CK_None; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 90985c08fe7f..b09680086248 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -85,7 +85,6 @@ #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/JumpThreading.h" #include "llvm/Transforms/Utils/Debugify.h" -#include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include #include @@ -983,22 +982,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( /*DropTypeTests=*/true)); }); - if (CodeGenOpts.InstrumentFunctions || - CodeGenOpts.InstrumentFunctionEntryBare || - CodeGenOpts.InstrumentFunctionsAfterInlining || - CodeGenOpts.InstrumentForProfiling) { - PB.registerPipelineStartEPCallback( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(createModuleToFunctionPassAdaptor( - EntryExitInstrumenterPass(/*PostInlining=*/false))); - }); - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(createModuleToFunctionPassAdaptor( - EntryExitInstrumenterPass(/*PostInlining=*/true))); - }); - } - // Register callbacks to schedule sanitizer passes at the appropriate part // of the pipeline. if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 266bf41fd557..37d0c478e033 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5978,11 +5978,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, auto Name = CGM.getCUDARuntime().getDeviceSideName( cast(E->getArg(0)->IgnoreImpCasts())->getDecl()); auto Str = CGM.GetAddrOfConstantCString(Name, ""); - llvm::Constant *Zeros[] = {llvm::ConstantInt::get(SizeTy, 0), - llvm::ConstantInt::get(SizeTy, 0)}; - auto *Ptr = llvm::ConstantExpr::getGetElementPtr(Str.getElementType(), - Str.getPointer(), Zeros); - return RValue::get(Ptr); + return RValue::get(Str.getPointer()); } } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 670bc4bf72ce..43dfbbb90dd5 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -71,8 +71,6 @@ private: bool RelocatableDeviceCode; /// Mangle context for device. std::unique_ptr DeviceMC; - /// Some zeros used for GEPs. - llvm::Constant *Zeros[2]; llvm::FunctionCallee getSetupArgumentFn() const; llvm::FunctionCallee getLaunchFn() const; @@ -91,9 +89,7 @@ private: /// where the C code specifies const char*. llvm::Constant *makeConstantString(const std::string &Str, const std::string &Name = "") { - auto ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str()); - return llvm::ConstantExpr::getGetElementPtr(ConstStr.getElementType(), - ConstStr.getPointer(), Zeros); + return CGM.GetAddrOfConstantCString(Str, Name.c_str()).getPointer(); } /// Helper function which generates an initialized constant array from Str, @@ -117,7 +113,7 @@ private: } if (Alignment) GV->setAlignment(llvm::Align(Alignment)); - return llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Zeros); + return GV; } /// Helper function that generates an empty dummy function returning void. @@ -230,8 +226,6 @@ CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) IntTy = CGM.IntTy; SizeTy = CGM.SizeTy; VoidTy = CGM.VoidTy; - Zeros[0] = llvm::ConstantInt::get(SizeTy, 0); - Zeros[1] = Zeros[0]; PtrTy = CGM.UnqualPtrTy; } diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 614316f3fc7f..da466837aa3c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -20,8 +20,8 @@ #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/CodeGenOptions.h" -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -38,6 +38,7 @@ class MDNode; namespace clang { class ClassTemplateSpecializationDecl; class GlobalDecl; +class Module; class ModuleMap; class ObjCInterfaceDecl; class UsingDecl; diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 7a92fc3dfb4a..5b2039af6128 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -448,11 +448,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { AggValueSlot Dest = EnsureSlot(E->getType()); LValue DestLV = CGF.MakeAddrLValue(Dest.getAddress(), E->getType()); LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field); - llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0); - llvm::Value *IdxStart[] = { Zero, Zero }; - llvm::Value *ArrayStart = Builder.CreateInBoundsGEP( - ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxStart, - "arraystart"); + llvm::Value *ArrayStart = ArrayPtr.emitRawPointer(CGF); CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start); ++Field; @@ -467,6 +463,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { Ctx.hasSameType(Field->getType()->getPointeeType(), ArrayType->getElementType())) { // End pointer. + llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0); llvm::Value *IdxEnd[] = { Zero, Size }; llvm::Value *ArrayEnd = Builder.CreateInBoundsGEP( ArrayPtr.getElementType(), ArrayPtr.emitRawPointer(CGF), IdxEnd, diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 43dd38659518..6540ac69f2d9 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -199,8 +199,7 @@ protected: llvm::Constant *MakeConstantString(StringRef Str, const char *Name = "") { ConstantAddress Array = CGM.GetAddrOfConstantCString(std::string(Str), Name); - return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(), - Array.getPointer(), Zeros); + return Array.getPointer(); } /// Emits a linkonce_odr string, whose name is the prefix followed by the @@ -221,8 +220,7 @@ protected: GV->setVisibility(llvm::GlobalValue::HiddenVisibility); ConstStr = GV; } - return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(), - ConstStr, Zeros); + return ConstStr; } /// Returns a property name and encoding string. @@ -1477,8 +1475,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { GV->setVisibility(llvm::GlobalValue::HiddenVisibility); TypesGlobal = GV; } - return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(), - TypesGlobal, Zeros); + return TypesGlobal; } llvm::Constant *GetConstantSelector(Selector Sel, const std::string &TypeEncoding) override { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0b0b659e1fd4..be7bf0b72dc0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1853,18 +1853,24 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, break; case MultiVersionKind::Target: { auto *Attr = FD->getAttr(); + assert(Attr && "Expected TargetAttr to be present " + "for attribute mangling"); const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); Info.appendAttributeMangling(Attr, Out); break; } case MultiVersionKind::TargetVersion: { auto *Attr = FD->getAttr(); + assert(Attr && "Expected TargetVersionAttr to be present " + "for attribute mangling"); const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); Info.appendAttributeMangling(Attr, Out); break; } case MultiVersionKind::TargetClones: { auto *Attr = FD->getAttr(); + assert(Attr && "Expected TargetClonesAttr to be present " + "for attribute mangling"); unsigned Index = GD.getMultiVersionIndex(); const ABIInfo &Info = CGM.getTargetCodeGenInfo().getABIInfo(); Info.appendAttributeMangling(Attr, Index, Out); @@ -6131,9 +6137,6 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { return ConstantAddress( C, C->getValueType(), CharUnits::fromQuantity(C->getAlignment())); - llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty); - llvm::Constant *Zeros[] = { Zero, Zero }; - const ASTContext &Context = getContext(); const llvm::Triple &Triple = getTriple(); @@ -6204,8 +6207,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { // Decay array -> ptr CFConstantStringClassRef = - IsSwiftABI ? llvm::ConstantExpr::getPtrToInt(C, Ty) - : llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); + IsSwiftABI ? llvm::ConstantExpr::getPtrToInt(C, Ty) : C; } QualType CFTy = Context.getCFConstantStringType(); @@ -6261,10 +6263,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { GV->setSection(".rodata"); // String. - llvm::Constant *Str = - llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Zeros); - - Fields.add(Str); + Fields.add(GV); // String length. llvm::IntegerType *LengthTy = diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 0f68418130ea..dc24971a3c18 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -24,7 +24,6 @@ #include "clang/AST/Mangle.h" #include "clang/Basic/ABI.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/Module.h" #include "clang/Basic/NoSanitizeList.h" #include "clang/Basic/ProfileList.h" #include "clang/Basic/TargetInfo.h" diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 8295d001ec6f..75f9c99d5d0b 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -310,4 +310,6 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, Features.push_back("+prefer-no-gather"); if (Args.hasArg(options::OPT_mno_scatter)) Features.push_back("+prefer-no-scatter"); + if (Args.hasArg(options::OPT_mapx_inline_asm_use_gpr32)) + Features.push_back("+inline-asm-use-gpr32"); } diff --git a/clang/lib/Driver/ToolChains/SPIRV.cpp b/clang/lib/Driver/ToolChains/SPIRV.cpp index 27de69550853..ce900600cbee 100644 --- a/clang/lib/Driver/ToolChains/SPIRV.cpp +++ b/clang/lib/Driver/ToolChains/SPIRV.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "SPIRV.h" #include "CommonArgs.h" +#include "clang/Basic/Version.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/InputInfo.h" @@ -32,8 +33,15 @@ void SPIRV::constructTranslateCommand(Compilation &C, const Tool &T, CmdArgs.append({"-o", Output.getFilename()}); - const char *Exec = - C.getArgs().MakeArgString(T.getToolChain().GetProgramPath("llvm-spirv")); + // Try to find "llvm-spirv-". Otherwise, fall back to + // plain "llvm-spirv". + using namespace std::string_literals; + auto VersionedTool = "llvm-spirv-"s + std::to_string(LLVM_VERSION_MAJOR); + std::string ExeCand = T.getToolChain().GetProgramPath(VersionedTool.c_str()); + if (!llvm::sys::fs::can_execute(ExeCand)) + ExeCand = T.getToolChain().GetProgramPath("llvm-spirv"); + + const char *Exec = C.getArgs().MakeArgString(ExeCand); C.addCommand(std::make_unique(JA, T, ResponseFileSupport::None(), Exec, CmdArgs, Input, Output)); } diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 96bef967d859..ab1108f663de 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -14,7 +14,6 @@ #include "clang/ExtractAPI/API.h" #include "clang/AST/RawCommentList.h" -#include "clang/Basic/Module.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 8792f4c75074..e4a4f27e502b 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -727,6 +727,29 @@ public: return isOneOf(tok::star, tok::amp, tok::ampamp); } + bool isCppAlternativeOperatorKeyword() const { + assert(!TokenText.empty()); + if (!isalpha(TokenText[0])) + return false; + + switch (Tok.getKind()) { + case tok::ampamp: + case tok::ampequal: + case tok::amp: + case tok::pipe: + case tok::tilde: + case tok::exclaim: + case tok::exclaimequal: + case tok::pipepipe: + case tok::pipeequal: + case tok::caret: + case tok::caretequal: + return true; + default: + return false; + } + } + bool isUnaryOperator() const { switch (Tok.getKind()) { case tok::plus: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 7c4c76a91f2c..26c0aa36bdcb 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4846,8 +4846,12 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Right.is(TT_TemplateOpener)) { return true; } - if (Left.Tok.getIdentifierInfo() && Right.is(tok::numeric_constant)) + // C++ Core Guidelines suppression tag, e.g. `[[suppress(type.5)]]`. + if (Left.is(tok::identifier) && Right.is(tok::numeric_constant)) return Right.TokenText[0] != '.'; + // `Left` is a keyword (including C++ alternative operator) or identifier. + if (Left.Tok.getIdentifierInfo() && Right.Tok.isLiteral()) + return true; } else if (Style.isProto()) { if (Right.is(tok::period) && Left.isOneOf(Keywords.kw_optional, Keywords.kw_required, diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b6f7567adc14..d6061c2666c2 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1410,13 +1410,6 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { } } -static bool isAltOperator(const FormatToken &Tok) { - return isalpha(Tok.TokenText[0]) && - Tok.isOneOf(tok::ampamp, tok::ampequal, tok::amp, tok::pipe, - tok::tilde, tok::exclaim, tok::exclaimequal, tok::pipepipe, - tok::pipeequal, tok::caret, tok::caretequal); -} - void UnwrappedLineParser::parseStructuralElement( const FormatToken *OpeningBrace, IfStmtKind *IfKind, FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) { @@ -1699,7 +1692,7 @@ void UnwrappedLineParser::parseStructuralElement( for (const bool InRequiresExpression = OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace); !eof();) { - if (IsCpp && isAltOperator(*FormatTok)) { + if (IsCpp && FormatTok->isCppAlternativeOperatorKeyword()) { if (auto *Next = Tokens->peekNextToken(/*SkipComment=*/true); Next && Next->isBinaryOperator()) { FormatTok->Tok.setKind(tok::identifier); @@ -2243,7 +2236,7 @@ bool UnwrappedLineParser::tryToParseLambda() { bool InTemplateParameterList = false; while (FormatTok->isNot(tok::l_brace)) { - if (FormatTok->isTypeName(LangOpts)) { + if (FormatTok->isTypeName(LangOpts) || FormatTok->isAttribute()) { nextToken(); continue; } @@ -4000,8 +3993,10 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { case tok::coloncolon: break; default: - if (!ClassName && Previous->is(tok::identifier)) + if (!ClassName && Previous->is(tok::identifier) && + Previous->isNot(TT_AttributeMacro)) { ClassName = Previous; + } } } @@ -4026,6 +4021,9 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (AngleNestingLevel == 0) { if (FormatTok->is(tok::colon)) { IsDerived = true; + } else if (FormatTok->is(tok::identifier) && + FormatTok->Previous->is(tok::coloncolon)) { + ClassName = FormatTok; } else if (FormatTok->is(tok::l_paren) && IsNonMacroIdentifier(FormatTok->Previous)) { break; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 454653a31534..1812b85860f6 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -273,9 +273,6 @@ std::unique_ptr GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::vector> Consumers; - Consumers.push_back(std::make_unique( - CI.getPreprocessor(), CI.getModuleCache(), - CI.getFrontendOpts().OutputFile)); if (CI.getFrontendOpts().GenReducedBMI && !CI.getFrontendOpts().ModuleOutputPath.empty()) { @@ -284,6 +281,10 @@ GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI, CI.getFrontendOpts().ModuleOutputPath)); } + Consumers.push_back(std::make_unique( + CI.getPreprocessor(), CI.getModuleCache(), + CI.getFrontendOpts().OutputFile)); + return std::make_unique(std::move(Consumers)); } @@ -1168,8 +1169,8 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { llvm::SmallVector Tokens; llvm::SmallVector Directives; if (scanSourceForDependencyDirectives( - FromFile.getBuffer(), Tokens, Directives, &CI.getDiagnostics(), - SM.getLocForStartOfFile(SM.getMainFileID()))) { + FromFile.getBuffer(), Tokens, Directives, CI.getLangOpts(), + &CI.getDiagnostics(), SM.getLocForStartOfFile(SM.getMainFileID()))) { assert(CI.getDiagnostics().hasErrorOccurred() && "no errors reported for failure"); diff --git a/clang/lib/Headers/cuda_wrappers/algorithm b/clang/lib/Headers/cuda_wrappers/algorithm index f14a0b00bb04..3f59f28ae35b 100644 --- a/clang/lib/Headers/cuda_wrappers/algorithm +++ b/clang/lib/Headers/cuda_wrappers/algorithm @@ -99,7 +99,7 @@ template __attribute__((enable_if(true, ""))) inline _CPP14_CONSTEXPR __host__ __device__ const __T & min(const __T &__a, const __T &__b) { - return __a < __b ? __a : __b; + return __b < __a ? __b : __a; } #pragma pop_macro("_CPP14_CONSTEXPR") diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index 5ceb986a1f65..1227f45d5432 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -329,6 +329,25 @@ static __inline__ void __DEFAULT_FN_ATTRS __stosq(unsigned __int64 *__dst, static __inline__ void __DEFAULT_FN_ATTRS __halt(void) { __asm__ volatile("hlt"); } + +static inline int _inp(unsigned short port) { + int ret; + __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline unsigned short _inpw(unsigned short port) { + unsigned short ret; + __asm__ volatile("inw %w1, %w0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +static inline unsigned long _inpd(unsigned short port) { + unsigned long ret; + __asm__ volatile("inl %w1, %k0" : "=a"(ret) : "Nd"(port)); + return ret; +} + #endif #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index 56c3c3636c9b..a9d182aa2447 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -15,6 +15,19 @@ typedef enum { ptrauth_key_asib = 1, ptrauth_key_asda = 2, ptrauth_key_asdb = 3, + + /* A process-independent key which can be used to sign code pointers. */ + ptrauth_key_process_independent_code = ptrauth_key_asia, + + /* A process-specific key which can be used to sign code pointers. */ + ptrauth_key_process_dependent_code = ptrauth_key_asib, + + /* A process-independent key which can be used to sign data pointers. */ + ptrauth_key_process_independent_data = ptrauth_key_asda, + + /* A process-specific key which can be used to sign data pointers. */ + ptrauth_key_process_dependent_data = ptrauth_key_asdb, + } ptrauth_key; /* An integer type of the appropriate size for a discriminator argument. */ diff --git a/clang/lib/Lex/DependencyDirectivesScanner.cpp b/clang/lib/Lex/DependencyDirectivesScanner.cpp index 0971daa1f366..fda54d314eef 100644 --- a/clang/lib/Lex/DependencyDirectivesScanner.cpp +++ b/clang/lib/Lex/DependencyDirectivesScanner.cpp @@ -62,14 +62,17 @@ struct DirectiveWithTokens { struct Scanner { Scanner(StringRef Input, SmallVectorImpl &Tokens, - DiagnosticsEngine *Diags, SourceLocation InputSourceLoc) + DiagnosticsEngine *Diags, SourceLocation InputSourceLoc, + const LangOptions &LangOpts) : Input(Input), Tokens(Tokens), Diags(Diags), - InputSourceLoc(InputSourceLoc), LangOpts(getLangOptsForDepScanning()), - TheLexer(InputSourceLoc, LangOpts, Input.begin(), Input.begin(), + InputSourceLoc(InputSourceLoc), + LangOpts(getLangOptsForDepScanning(LangOpts)), + TheLexer(InputSourceLoc, this->LangOpts, Input.begin(), Input.begin(), Input.end()) {} - static LangOptions getLangOptsForDepScanning() { - LangOptions LangOpts; + static LangOptions + getLangOptsForDepScanning(const LangOptions &invocationLangOpts) { + LangOptions LangOpts(invocationLangOpts); // Set the lexer to use 'tok::at' for '@', instead of 'tok::unknown'. LangOpts.ObjC = true; LangOpts.LineComment = true; @@ -700,7 +703,7 @@ bool Scanner::lex_Pragma(const char *&First, const char *const End) { SmallVector DiscardTokens; const char *Begin = Buffer.c_str(); Scanner PragmaScanner{StringRef(Begin, Buffer.size()), DiscardTokens, Diags, - InputSourceLoc}; + InputSourceLoc, LangOptions()}; PragmaScanner.TheLexer.setParsingPreprocessorDirective(true); if (PragmaScanner.lexPragma(Begin, Buffer.end())) @@ -950,9 +953,10 @@ bool Scanner::scan(SmallVectorImpl &Directives) { bool clang::scanSourceForDependencyDirectives( StringRef Input, SmallVectorImpl &Tokens, - SmallVectorImpl &Directives, DiagnosticsEngine *Diags, - SourceLocation InputSourceLoc) { - return Scanner(Input, Tokens, Diags, InputSourceLoc).scan(Directives); + SmallVectorImpl &Directives, const LangOptions &LangOpts, + DiagnosticsEngine *Diags, SourceLocation InputSourceLoc) { + return Scanner(Input, Tokens, Diags, InputSourceLoc, LangOpts) + .scan(Directives); } void clang::printDependencyDirectivesAsSource( diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index e149b1a0fb5e..6f21a4f9bd82 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/PrettyStackTrace.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Parse/ParseDiagnostic.h" @@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, SS, ObjectType, ObjectHadErrors, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, EnteringContext, Result, TemplateSpecified); - else if (TemplateSpecified && - Actions.ActOnTemplateName( - getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, - EnteringContext, Template, - /*AllowInjectedClassName*/ true) == TNK_Non_template) - return true; + if (TemplateSpecified) { + TemplateNameKind TNK = + Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result, + ObjectType, EnteringContext, Template, + /*AllowInjectedClassName=*/true); + if (TNK == TNK_Non_template) + return true; + + // C++2c [tem.names]p6 + // A name prefixed by the keyword template shall be followed by a template + // argument list or refer to a class template or an alias template. + if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name || + TNK == TNK_Var_template) && + !Tok.is(tok::less)) + Diag(IdLoc, diag::missing_template_arg_list_after_template_kw); + } return false; } @@ -4000,6 +4011,9 @@ ExprResult Parser::ParseArrayTypeTrait() { ExprResult DimExpr = ParseExpression(); T.consumeClose(); + if (DimExpr.isInvalid()) + return ExprError(); + return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), T.getCloseLocation()); } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index cd8df3332724..50a872fedebf 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -21,12 +21,13 @@ #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaAMDGPU.h" #include "clang/Sema/SemaCodeCompletion.h" #include "clang/Sema/SemaOpenMP.h" -#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/OpenMP/OMPAssume.h" #include "llvm/Frontend/OpenMP/OMPContext.h" +#include #include using namespace clang; @@ -1645,19 +1646,17 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind, SmallVectorImpl &Clauses, SourceLocation Loc) { - SmallVector, - llvm::omp::Clause_enumSize + 1> - FirstClauses(llvm::omp::Clause_enumSize + 1); + std::bitset SeenClauses; while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.OpenMP().StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = + ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + SeenClauses[unsigned(CKind)] = true; if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2113,19 +2112,17 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( /*AllowScopeSpecifier=*/true)) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { - SmallVector, - llvm::omp::Clause_enumSize + 1> - FirstClauses(llvm::omp::Clause_enumSize + 1); + std::bitset SeenClauses; while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.OpenMP().StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !SeenClauses[unsigned(CKind)]); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + SeenClauses[unsigned(CKind)] = true; if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2149,9 +2146,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; - SmallVector, - llvm::omp::Clause_enumSize + 1> - FirstClauses(llvm::omp::Clause_enumSize + 1); + std::bitset SeenClauses; if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -2162,11 +2157,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.OpenMP().StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, + !SeenClauses[unsigned(CKind)]); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + SeenClauses[unsigned(CKind)] = true; if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2509,9 +2504,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; - SmallVector, - llvm::omp::Clause_enumSize + 1> - FirstClauses(llvm::omp::Clause_enumSize + 1); + std::bitset SeenClauses; unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ReadDirectiveWithinMetadirective @@ -2716,19 +2709,17 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( /*AllowScopeSpecifier=*/false)) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { - SmallVector, - llvm::omp::Clause_enumSize + 1> - FirstClauses(llvm::omp::Clause_enumSize + 1); + std::bitset SeenClauses; while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.OpenMP().StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !SeenClauses[unsigned(CKind)]); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + SeenClauses[unsigned(CKind)] = true; if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2925,13 +2916,11 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( ImplicitClauseAllowed = false; Actions.OpenMP().StartOpenMPClause(CKind); HasImplicitClause = false; - OMPClause *Clause = ParseOpenMPClause( - DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); - FirstClauses[unsigned(CKind)].setInt(true); - if (Clause) { - FirstClauses[unsigned(CKind)].setPointer(Clause); + OMPClause *Clause = + ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]); + SeenClauses[unsigned(CKind)] = true; + if (Clause) Clauses.push_back(Clause); - } // Skip ',' if any. if (Tok.is(tok::comma)) @@ -2947,7 +2936,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( // If the depend or doacross clause is specified, the ordered construct // is a stand-alone directive. for (auto CK : {OMPC_depend, OMPC_doacross}) { - if (FirstClauses[unsigned(CK)].getInt()) { + if (SeenClauses[unsigned(CK)]) { if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) @@ -2959,7 +2948,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( } } - if (DKind == OMPD_tile && !FirstClauses[unsigned(OMPC_sizes)].getInt()) { + if (DKind == OMPD_tile && !SeenClauses[unsigned(OMPC_sizes)]) { Diag(Loc, diag::err_omp_required_clause) << getOpenMPDirectiveName(OMPD_tile) << "sizes"; } @@ -3757,7 +3746,7 @@ OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) { case ParsedAttr::AT_AMDGPUFlatWorkGroupSize: if (!PA.checkExactlyNumArgs(Actions, 2)) continue; - if (auto *A = Actions.CreateAMDGPUFlatWorkGroupSizeAttr( + if (auto *A = Actions.AMDGPU().CreateAMDGPUFlatWorkGroupSizeAttr( PA, PA.getArgAsExpr(0), PA.getArgAsExpr(1))) Attrs.push_back(A); continue; @@ -3765,7 +3754,7 @@ OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) { if (!PA.checkAtLeastNumArgs(Actions, 1) || !PA.checkAtMostNumArgs(Actions, 2)) continue; - if (auto *A = Actions.CreateAMDGPUWavesPerEUAttr( + if (auto *A = Actions.AMDGPU().CreateAMDGPUWavesPerEUAttr( PA, PA.getArgAsExpr(0), PA.getNumArgs() > 1 ? PA.getArgAsExpr(1) : nullptr)) Attrs.push_back(A); diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index fe6471c81ff0..c9abf58fcbd2 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -26,10 +26,13 @@ add_clang_library(clangSema Scope.cpp ScopeInfo.cpp Sema.cpp + SemaAMDGPU.cpp + SemaARM.cpp SemaAccess.cpp SemaAttr.cpp SemaAPINotes.cpp SemaAvailability.cpp + SemaBPF.cpp SemaBase.cpp SemaCXXScopeSpec.cpp SemaCast.cpp @@ -50,27 +53,34 @@ add_clang_library(clangSema SemaExprObjC.cpp SemaFixItUtils.cpp SemaHLSL.cpp + SemaHexagon.cpp SemaInit.cpp SemaLambda.cpp SemaLookup.cpp + SemaLoongArch.cpp + SemaMIPS.cpp SemaModule.cpp + SemaNVPTX.cpp SemaObjC.cpp SemaObjCProperty.cpp SemaOpenACC.cpp SemaOpenMP.cpp SemaOverload.cpp + SemaPPC.cpp SemaPseudoObject.cpp SemaRISCV.cpp SemaStmt.cpp SemaStmtAsm.cpp SemaStmtAttr.cpp SemaSYCL.cpp + SemaSystemZ.cpp SemaTemplate.cpp SemaTemplateDeduction.cpp SemaTemplateInstantiate.cpp SemaTemplateInstantiateDecl.cpp SemaTemplateVariadic.cpp SemaType.cpp + SemaWasm.cpp SemaX86.cpp TypeLocBuilder.cpp diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index d1fb21bb1ae1..582adcfa84c4 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -41,17 +41,27 @@ #include "clang/Sema/RISCVIntrinsicManager.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaAMDGPU.h" +#include "clang/Sema/SemaARM.h" +#include "clang/Sema/SemaBPF.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaCodeCompletion.h" #include "clang/Sema/SemaConsumer.h" #include "clang/Sema/SemaHLSL.h" +#include "clang/Sema/SemaHexagon.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaLoongArch.h" +#include "clang/Sema/SemaMIPS.h" +#include "clang/Sema/SemaNVPTX.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaPPC.h" #include "clang/Sema/SemaPseudoObject.h" #include "clang/Sema/SemaRISCV.h" #include "clang/Sema/SemaSYCL.h" +#include "clang/Sema/SemaSystemZ.h" +#include "clang/Sema/SemaWasm.h" #include "clang/Sema/SemaX86.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TemplateInstCallback.h" @@ -206,16 +216,26 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr), CurScope(nullptr), Ident_super(nullptr), + AMDGPUPtr(std::make_unique(*this)), + ARMPtr(std::make_unique(*this)), + BPFPtr(std::make_unique(*this)), CodeCompletionPtr( std::make_unique(*this, CodeCompleter)), CUDAPtr(std::make_unique(*this)), HLSLPtr(std::make_unique(*this)), + HexagonPtr(std::make_unique(*this)), + LoongArchPtr(std::make_unique(*this)), + MIPSPtr(std::make_unique(*this)), + NVPTXPtr(std::make_unique(*this)), ObjCPtr(std::make_unique(*this)), OpenACCPtr(std::make_unique(*this)), OpenMPPtr(std::make_unique(*this)), + PPCPtr(std::make_unique(*this)), PseudoObjectPtr(std::make_unique(*this)), RISCVPtr(std::make_unique(*this)), SYCLPtr(std::make_unique(*this)), + SystemZPtr(std::make_unique(*this)), + WasmPtr(std::make_unique(*this)), X86Ptr(std::make_unique(*this)), MSPointerToMemberRepresentationMethod( LangOpts.getMSPointerToMemberRepresentationMethod()), @@ -1357,6 +1377,10 @@ void Sema::ActOnEndOfTranslationUnit() { Consumer.CompleteExternalDeclaration(D); } + if (LangOpts.HLSL) + HLSL().DiagnoseAvailabilityViolations( + getASTContext().getTranslationUnitDecl()); + // If there were errors, disable 'unused' warnings since they will mostly be // noise. Don't warn for a use from a module: either we should warn on all // file-scope declarations in modules or not at all, but whether the diff --git a/clang/lib/Sema/SemaAMDGPU.cpp b/clang/lib/Sema/SemaAMDGPU.cpp new file mode 100644 index 000000000000..c446cc1d042a --- /dev/null +++ b/clang/lib/Sema/SemaAMDGPU.cpp @@ -0,0 +1,311 @@ +//===------ SemaAMDGPU.cpp ------- AMDGPU target-specific routines --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to AMDGPU. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaAMDGPU.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/Sema.h" +#include "llvm/Support/AtomicOrdering.h" +#include + +namespace clang { + +SemaAMDGPU::SemaAMDGPU(Sema &S) : SemaBase(S) {} + +bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + // position of memory order and scope arguments in the builtin + unsigned OrderIndex, ScopeIndex; + switch (BuiltinID) { + case AMDGPU::BI__builtin_amdgcn_global_load_lds: { + constexpr const int SizeIdx = 2; + llvm::APSInt Size; + Expr *ArgExpr = TheCall->getArg(SizeIdx); + ExprResult R = SemaRef.VerifyIntegerConstantExpression(ArgExpr, &Size); + if (R.isInvalid()) + return true; + switch (Size.getSExtValue()) { + case 1: + case 2: + case 4: + return false; + default: + Diag(ArgExpr->getExprLoc(), + diag::err_amdgcn_global_load_lds_size_invalid_value) + << ArgExpr->getSourceRange(); + Diag(ArgExpr->getExprLoc(), + diag::note_amdgcn_global_load_lds_size_valid_value) + << ArgExpr->getSourceRange(); + return true; + } + } + case AMDGPU::BI__builtin_amdgcn_get_fpenv: + case AMDGPU::BI__builtin_amdgcn_set_fpenv: + return false; + case AMDGPU::BI__builtin_amdgcn_atomic_inc32: + case AMDGPU::BI__builtin_amdgcn_atomic_inc64: + case AMDGPU::BI__builtin_amdgcn_atomic_dec32: + case AMDGPU::BI__builtin_amdgcn_atomic_dec64: + OrderIndex = 2; + ScopeIndex = 3; + break; + case AMDGPU::BI__builtin_amdgcn_fence: + OrderIndex = 0; + ScopeIndex = 1; + break; + default: + return false; + } + + ExprResult Arg = TheCall->getArg(OrderIndex); + auto ArgExpr = Arg.get(); + Expr::EvalResult ArgResult; + + if (!ArgExpr->EvaluateAsInt(ArgResult, getASTContext())) + return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int) + << ArgExpr->getType(); + auto Ord = ArgResult.Val.getInt().getZExtValue(); + + // Check validity of memory ordering as per C11 / C++11's memody model. + // Only fence needs check. Atomic dec/inc allow all memory orders. + if (!llvm::isValidAtomicOrderingCABI(Ord)) + return Diag(ArgExpr->getBeginLoc(), + diag::warn_atomic_op_has_invalid_memory_order) + << 0 << ArgExpr->getSourceRange(); + switch (static_cast(Ord)) { + case llvm::AtomicOrderingCABI::relaxed: + case llvm::AtomicOrderingCABI::consume: + if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence) + return Diag(ArgExpr->getBeginLoc(), + diag::warn_atomic_op_has_invalid_memory_order) + << 0 << ArgExpr->getSourceRange(); + break; + case llvm::AtomicOrderingCABI::acquire: + case llvm::AtomicOrderingCABI::release: + case llvm::AtomicOrderingCABI::acq_rel: + case llvm::AtomicOrderingCABI::seq_cst: + break; + } + + Arg = TheCall->getArg(ScopeIndex); + ArgExpr = Arg.get(); + Expr::EvalResult ArgResult1; + // Check that sync scope is a constant literal + if (!ArgExpr->EvaluateAsConstantExpr(ArgResult1, getASTContext())) + return Diag(ArgExpr->getExprLoc(), diag::err_expr_not_string_literal) + << ArgExpr->getType(); + + return false; +} + +static bool +checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, + const AMDGPUFlatWorkGroupSizeAttr &Attr) { + // Accept template arguments for now as they depend on something else. + // We'll get to check them when they eventually get instantiated. + if (MinExpr->isValueDependent() || MaxExpr->isValueDependent()) + return false; + + uint32_t Min = 0; + if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0)) + return true; + + uint32_t Max = 0; + if (!S.checkUInt32Argument(Attr, MaxExpr, Max, 1)) + return true; + + if (Min == 0 && Max != 0) { + S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) + << &Attr << 0; + return true; + } + if (Min > Max) { + S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) + << &Attr << 1; + return true; + } + + return false; +} + +AMDGPUFlatWorkGroupSizeAttr * +SemaAMDGPU::CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, + Expr *MinExpr, Expr *MaxExpr) { + ASTContext &Context = getASTContext(); + AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr); + + if (checkAMDGPUFlatWorkGroupSizeArguments(SemaRef, MinExpr, MaxExpr, TmpAttr)) + return nullptr; + return ::new (Context) + AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr); +} + +void SemaAMDGPU::addAMDGPUFlatWorkGroupSizeAttr(Decl *D, + const AttributeCommonInfo &CI, + Expr *MinExpr, Expr *MaxExpr) { + if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr)) + D->addAttr(Attr); +} + +void SemaAMDGPU::handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, + const ParsedAttr &AL) { + Expr *MinExpr = AL.getArgAsExpr(0); + Expr *MaxExpr = AL.getArgAsExpr(1); + + addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr); +} + +static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr, + Expr *MaxExpr, + const AMDGPUWavesPerEUAttr &Attr) { + if (S.DiagnoseUnexpandedParameterPack(MinExpr) || + (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr))) + return true; + + // Accept template arguments for now as they depend on something else. + // We'll get to check them when they eventually get instantiated. + if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent())) + return false; + + uint32_t Min = 0; + if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0)) + return true; + + uint32_t Max = 0; + if (MaxExpr && !S.checkUInt32Argument(Attr, MaxExpr, Max, 1)) + return true; + + if (Min == 0 && Max != 0) { + S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) + << &Attr << 0; + return true; + } + if (Max != 0 && Min > Max) { + S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) + << &Attr << 1; + return true; + } + + return false; +} + +AMDGPUWavesPerEUAttr * +SemaAMDGPU::CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, + Expr *MinExpr, Expr *MaxExpr) { + ASTContext &Context = getASTContext(); + AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr); + + if (checkAMDGPUWavesPerEUArguments(SemaRef, MinExpr, MaxExpr, TmpAttr)) + return nullptr; + + return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr); +} + +void SemaAMDGPU::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, + Expr *MinExpr, Expr *MaxExpr) { + if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr)) + D->addAttr(Attr); +} + +void SemaAMDGPU::handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL) { + if (!AL.checkAtLeastNumArgs(SemaRef, 1) || !AL.checkAtMostNumArgs(SemaRef, 2)) + return; + + Expr *MinExpr = AL.getArgAsExpr(0); + Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; + + addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr); +} + +void SemaAMDGPU::handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL) { + uint32_t NumSGPR = 0; + Expr *NumSGPRExpr = AL.getArgAsExpr(0); + if (!SemaRef.checkUInt32Argument(AL, NumSGPRExpr, NumSGPR)) + return; + + D->addAttr(::new (getASTContext()) + AMDGPUNumSGPRAttr(getASTContext(), AL, NumSGPR)); +} + +void SemaAMDGPU::handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL) { + uint32_t NumVGPR = 0; + Expr *NumVGPRExpr = AL.getArgAsExpr(0); + if (!SemaRef.checkUInt32Argument(AL, NumVGPRExpr, NumVGPR)) + return; + + D->addAttr(::new (getASTContext()) + AMDGPUNumVGPRAttr(getASTContext(), AL, NumVGPR)); +} + +static bool +checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, + Expr *ZExpr, + const AMDGPUMaxNumWorkGroupsAttr &Attr) { + if (S.DiagnoseUnexpandedParameterPack(XExpr) || + (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) || + (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr))) + return true; + + // Accept template arguments for now as they depend on something else. + // We'll get to check them when they eventually get instantiated. + if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) || + (ZExpr && ZExpr->isValueDependent())) + return false; + + uint32_t NumWG = 0; + Expr *Exprs[3] = {XExpr, YExpr, ZExpr}; + for (int i = 0; i < 3; i++) { + if (Exprs[i]) { + if (!S.checkUInt32Argument(Attr, Exprs[i], NumWG, i, + /*StrictlyUnsigned=*/true)) + return true; + if (NumWG == 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) + << &Attr << Exprs[i]->getSourceRange(); + return true; + } + } + } + + return false; +} + +AMDGPUMaxNumWorkGroupsAttr *SemaAMDGPU::CreateAMDGPUMaxNumWorkGroupsAttr( + const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr) { + ASTContext &Context = getASTContext(); + AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr); + + if (checkAMDGPUMaxNumWorkGroupsArguments(SemaRef, XExpr, YExpr, ZExpr, + TmpAttr)) + return nullptr; + + return ::new (Context) + AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr); +} + +void SemaAMDGPU::addAMDGPUMaxNumWorkGroupsAttr(Decl *D, + const AttributeCommonInfo &CI, + Expr *XExpr, Expr *YExpr, + Expr *ZExpr) { + if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr)) + D->addAttr(Attr); +} + +void SemaAMDGPU::handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, + const ParsedAttr &AL) { + Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; + Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr; + addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr); +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp new file mode 100644 index 000000000000..da37ccef051a --- /dev/null +++ b/clang/lib/Sema/SemaARM.cpp @@ -0,0 +1,1088 @@ +//===------ SemaARM.cpp ---------- ARM target-specific routines -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to ARM. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaARM.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Initialization.h" +#include "clang/Sema/Sema.h" + +namespace clang { + +SemaARM::SemaARM(Sema &S) : SemaBase(S) {} + +/// BuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions +bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, + CallExpr *TheCall) { + ASTContext &Context = getASTContext(); + + if (BuiltinID == AArch64::BI__builtin_arm_irg) { + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + Expr *Arg0 = TheCall->getArg(0); + Expr *Arg1 = TheCall->getArg(1); + + ExprResult FirstArg = SemaRef.DefaultFunctionArrayLvalueConversion(Arg0); + if (FirstArg.isInvalid()) + return true; + QualType FirstArgType = FirstArg.get()->getType(); + if (!FirstArgType->isAnyPointerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) + << "first" << FirstArgType << Arg0->getSourceRange(); + TheCall->setArg(0, FirstArg.get()); + + ExprResult SecArg = SemaRef.DefaultLvalueConversion(Arg1); + if (SecArg.isInvalid()) + return true; + QualType SecArgType = SecArg.get()->getType(); + if (!SecArgType->isIntegerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) + << "second" << SecArgType << Arg1->getSourceRange(); + + // Derive the return type from the pointer argument. + TheCall->setType(FirstArgType); + return false; + } + + if (BuiltinID == AArch64::BI__builtin_arm_addg) { + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + + Expr *Arg0 = TheCall->getArg(0); + ExprResult FirstArg = SemaRef.DefaultFunctionArrayLvalueConversion(Arg0); + if (FirstArg.isInvalid()) + return true; + QualType FirstArgType = FirstArg.get()->getType(); + if (!FirstArgType->isAnyPointerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) + << "first" << FirstArgType << Arg0->getSourceRange(); + TheCall->setArg(0, FirstArg.get()); + + // Derive the return type from the pointer argument. + TheCall->setType(FirstArgType); + + // Second arg must be an constant in range [0,15] + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + } + + if (BuiltinID == AArch64::BI__builtin_arm_gmi) { + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + Expr *Arg0 = TheCall->getArg(0); + Expr *Arg1 = TheCall->getArg(1); + + ExprResult FirstArg = SemaRef.DefaultFunctionArrayLvalueConversion(Arg0); + if (FirstArg.isInvalid()) + return true; + QualType FirstArgType = FirstArg.get()->getType(); + if (!FirstArgType->isAnyPointerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) + << "first" << FirstArgType << Arg0->getSourceRange(); + + QualType SecArgType = Arg1->getType(); + if (!SecArgType->isIntegerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) + << "second" << SecArgType << Arg1->getSourceRange(); + TheCall->setType(Context.IntTy); + return false; + } + + if (BuiltinID == AArch64::BI__builtin_arm_ldg || + BuiltinID == AArch64::BI__builtin_arm_stg) { + if (SemaRef.checkArgCount(TheCall, 1)) + return true; + Expr *Arg0 = TheCall->getArg(0); + ExprResult FirstArg = SemaRef.DefaultFunctionArrayLvalueConversion(Arg0); + if (FirstArg.isInvalid()) + return true; + + QualType FirstArgType = FirstArg.get()->getType(); + if (!FirstArgType->isAnyPointerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) + << "first" << FirstArgType << Arg0->getSourceRange(); + TheCall->setArg(0, FirstArg.get()); + + // Derive the return type from the pointer argument. + if (BuiltinID == AArch64::BI__builtin_arm_ldg) + TheCall->setType(FirstArgType); + return false; + } + + if (BuiltinID == AArch64::BI__builtin_arm_subp) { + Expr *ArgA = TheCall->getArg(0); + Expr *ArgB = TheCall->getArg(1); + + ExprResult ArgExprA = SemaRef.DefaultFunctionArrayLvalueConversion(ArgA); + ExprResult ArgExprB = SemaRef.DefaultFunctionArrayLvalueConversion(ArgB); + + if (ArgExprA.isInvalid() || ArgExprB.isInvalid()) + return true; + + QualType ArgTypeA = ArgExprA.get()->getType(); + QualType ArgTypeB = ArgExprB.get()->getType(); + + auto isNull = [&](Expr *E) -> bool { + return E->isNullPointerConstant(Context, + Expr::NPC_ValueDependentIsNotNull); + }; + + // argument should be either a pointer or null + if (!ArgTypeA->isAnyPointerType() && !isNull(ArgA)) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer) + << "first" << ArgTypeA << ArgA->getSourceRange(); + + if (!ArgTypeB->isAnyPointerType() && !isNull(ArgB)) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer) + << "second" << ArgTypeB << ArgB->getSourceRange(); + + // Ensure Pointee types are compatible + if (ArgTypeA->isAnyPointerType() && !isNull(ArgA) && + ArgTypeB->isAnyPointerType() && !isNull(ArgB)) { + QualType pointeeA = ArgTypeA->getPointeeType(); + QualType pointeeB = ArgTypeB->getPointeeType(); + if (!Context.typesAreCompatible( + Context.getCanonicalType(pointeeA).getUnqualifiedType(), + Context.getCanonicalType(pointeeB).getUnqualifiedType())) { + return Diag(TheCall->getBeginLoc(), + diag::err_typecheck_sub_ptr_compatible) + << ArgTypeA << ArgTypeB << ArgA->getSourceRange() + << ArgB->getSourceRange(); + } + } + + // at least one argument should be pointer type + if (!ArgTypeA->isAnyPointerType() && !ArgTypeB->isAnyPointerType()) + return Diag(TheCall->getBeginLoc(), diag::err_memtag_any2arg_pointer) + << ArgTypeA << ArgTypeB << ArgA->getSourceRange(); + + if (isNull(ArgA)) // adopt type of the other pointer + ArgExprA = + SemaRef.ImpCastExprToType(ArgExprA.get(), ArgTypeB, CK_NullToPointer); + + if (isNull(ArgB)) + ArgExprB = + SemaRef.ImpCastExprToType(ArgExprB.get(), ArgTypeA, CK_NullToPointer); + + TheCall->setArg(0, ArgExprA.get()); + TheCall->setArg(1, ArgExprB.get()); + TheCall->setType(Context.LongLongTy); + return false; + } + assert(false && "Unhandled ARM MTE intrinsic"); + return true; +} + +/// BuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr +/// TheCall is an ARM/AArch64 special register string literal. +bool SemaARM::BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, + int ArgNum, unsigned ExpectedFieldNum, + bool AllowName) { + bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 || + BuiltinID == ARM::BI__builtin_arm_wsr64 || + BuiltinID == ARM::BI__builtin_arm_rsr || + BuiltinID == ARM::BI__builtin_arm_rsrp || + BuiltinID == ARM::BI__builtin_arm_wsr || + BuiltinID == ARM::BI__builtin_arm_wsrp; + bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 || + BuiltinID == AArch64::BI__builtin_arm_wsr64 || + BuiltinID == AArch64::BI__builtin_arm_rsr128 || + BuiltinID == AArch64::BI__builtin_arm_wsr128 || + BuiltinID == AArch64::BI__builtin_arm_rsr || + BuiltinID == AArch64::BI__builtin_arm_rsrp || + BuiltinID == AArch64::BI__builtin_arm_wsr || + BuiltinID == AArch64::BI__builtin_arm_wsrp; + assert((IsARMBuiltin || IsAArch64Builtin) && "Unexpected ARM builtin."); + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check if the argument is a string literal. + if (!isa(Arg->IgnoreParenImpCasts())) + return Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) + << Arg->getSourceRange(); + + // Check the type of special register given. + StringRef Reg = cast(Arg->IgnoreParenImpCasts())->getString(); + SmallVector Fields; + Reg.split(Fields, ":"); + + if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1)) + return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) + << Arg->getSourceRange(); + + // If the string is the name of a register then we cannot check that it is + // valid here but if the string is of one the forms described in ACLE then we + // can check that the supplied fields are integers and within the valid + // ranges. + if (Fields.size() > 1) { + bool FiveFields = Fields.size() == 5; + + bool ValidString = true; + if (IsARMBuiltin) { + ValidString &= Fields[0].starts_with_insensitive("cp") || + Fields[0].starts_with_insensitive("p"); + if (ValidString) + Fields[0] = Fields[0].drop_front( + Fields[0].starts_with_insensitive("cp") ? 2 : 1); + + ValidString &= Fields[2].starts_with_insensitive("c"); + if (ValidString) + Fields[2] = Fields[2].drop_front(1); + + if (FiveFields) { + ValidString &= Fields[3].starts_with_insensitive("c"); + if (ValidString) + Fields[3] = Fields[3].drop_front(1); + } + } + + SmallVector Ranges; + if (FiveFields) + Ranges.append({IsAArch64Builtin ? 1 : 15, 7, 15, 15, 7}); + else + Ranges.append({15, 7, 15}); + + for (unsigned i = 0; i < Fields.size(); ++i) { + int IntField; + ValidString &= !Fields[i].getAsInteger(10, IntField); + ValidString &= (IntField >= 0 && IntField <= Ranges[i]); + } + + if (!ValidString) + return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) + << Arg->getSourceRange(); + } else if (IsAArch64Builtin && Fields.size() == 1) { + // This code validates writes to PSTATE registers. + + // Not a write. + if (TheCall->getNumArgs() != 2) + return false; + + // The 128-bit system register accesses do not touch PSTATE. + if (BuiltinID == AArch64::BI__builtin_arm_rsr128 || + BuiltinID == AArch64::BI__builtin_arm_wsr128) + return false; + + // These are the named PSTATE accesses using "MSR (immediate)" instructions, + // along with the upper limit on the immediates allowed. + auto MaxLimit = llvm::StringSwitch>(Reg) + .CaseLower("spsel", 15) + .CaseLower("daifclr", 15) + .CaseLower("daifset", 15) + .CaseLower("pan", 15) + .CaseLower("uao", 15) + .CaseLower("dit", 15) + .CaseLower("ssbs", 15) + .CaseLower("tco", 15) + .CaseLower("allint", 1) + .CaseLower("pm", 1) + .Default(std::nullopt); + + // If this is not a named PSTATE, just continue without validating, as this + // will be lowered to an "MSR (register)" instruction directly + if (!MaxLimit) + return false; + + // Here we only allow constants in the range for that pstate, as required by + // the ACLE. + // + // While clang also accepts the names of system registers in its ACLE + // intrinsics, we prevent this with the PSTATE names used in MSR (immediate) + // as the value written via a register is different to the value used as an + // immediate to have the same effect. e.g., for the instruction `msr tco, + // x0`, it is bit 25 of register x0 that is written into PSTATE.TCO, but + // with `msr tco, #imm`, it is bit 0 of xN that is written into PSTATE.TCO. + // + // If a programmer wants to codegen the MSR (register) form of `msr tco, + // xN`, they can still do so by specifying the register using five + // colon-separated numbers in a string. + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, *MaxLimit); + } + + return false; +} + +// Get the valid immediate range for the specified NEON type code. +static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { + NeonTypeFlags Type(t); + int IsQuad = ForceQuad ? true : Type.isQuad(); + switch (Type.getEltType()) { + case NeonTypeFlags::Int8: + case NeonTypeFlags::Poly8: + return shift ? 7 : (8 << IsQuad) - 1; + case NeonTypeFlags::Int16: + case NeonTypeFlags::Poly16: + return shift ? 15 : (4 << IsQuad) - 1; + case NeonTypeFlags::Int32: + return shift ? 31 : (2 << IsQuad) - 1; + case NeonTypeFlags::Int64: + case NeonTypeFlags::Poly64: + return shift ? 63 : (1 << IsQuad) - 1; + case NeonTypeFlags::Poly128: + return shift ? 127 : (1 << IsQuad) - 1; + case NeonTypeFlags::Float16: + assert(!shift && "cannot shift float types!"); + return (4 << IsQuad) - 1; + case NeonTypeFlags::Float32: + assert(!shift && "cannot shift float types!"); + return (2 << IsQuad) - 1; + case NeonTypeFlags::Float64: + assert(!shift && "cannot shift float types!"); + return (1 << IsQuad) - 1; + case NeonTypeFlags::BFloat16: + assert(!shift && "cannot shift float types!"); + return (4 << IsQuad) - 1; + } + llvm_unreachable("Invalid NeonTypeFlag!"); +} + +/// getNeonEltType - Return the QualType corresponding to the elements of +/// the vector type specified by the NeonTypeFlags. This is used to check +/// the pointer arguments for Neon load/store intrinsics. +static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, + bool IsPolyUnsigned, bool IsInt64Long) { + switch (Flags.getEltType()) { + case NeonTypeFlags::Int8: + return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; + case NeonTypeFlags::Int16: + return Flags.isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy; + case NeonTypeFlags::Int32: + return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy; + case NeonTypeFlags::Int64: + if (IsInt64Long) + return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy; + else + return Flags.isUnsigned() ? Context.UnsignedLongLongTy + : Context.LongLongTy; + case NeonTypeFlags::Poly8: + return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy; + case NeonTypeFlags::Poly16: + return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy; + case NeonTypeFlags::Poly64: + if (IsInt64Long) + return Context.UnsignedLongTy; + else + return Context.UnsignedLongLongTy; + case NeonTypeFlags::Poly128: + break; + case NeonTypeFlags::Float16: + return Context.HalfTy; + case NeonTypeFlags::Float32: + return Context.FloatTy; + case NeonTypeFlags::Float64: + return Context.DoubleTy; + case NeonTypeFlags::BFloat16: + return Context.BFloat16Ty; + } + llvm_unreachable("Invalid NeonTypeFlag!"); +} + +enum ArmSMEState : unsigned { + ArmNoState = 0, + + ArmInZA = 0b01, + ArmOutZA = 0b10, + ArmInOutZA = 0b11, + ArmZAMask = 0b11, + + ArmInZT0 = 0b01 << 2, + ArmOutZT0 = 0b10 << 2, + ArmInOutZT0 = 0b11 << 2, + ArmZT0Mask = 0b11 << 2 +}; + +bool SemaARM::ParseSVEImmChecks( + CallExpr *TheCall, SmallVector, 3> &ImmChecks) { + // Perform all the immediate checks for this builtin call. + bool HasError = false; + for (auto &I : ImmChecks) { + int ArgNum, CheckTy, ElementSizeInBits; + std::tie(ArgNum, CheckTy, ElementSizeInBits) = I; + + typedef bool (*OptionSetCheckFnTy)(int64_t Value); + + // Function that checks whether the operand (ArgNum) is an immediate + // that is one of the predefined values. + auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm, + int ErrDiag) -> bool { + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + llvm::APSInt Imm; + if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Imm)) + return true; + + if (!CheckImm(Imm.getSExtValue())) + return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); + return false; + }; + + switch ((SVETypeFlags::ImmCheckType)CheckTy) { + case SVETypeFlags::ImmCheck0_31: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_13: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 13)) + HasError = true; + break; + case SVETypeFlags::ImmCheck1_16: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 16)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_7: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 7)) + HasError = true; + break; + case SVETypeFlags::ImmCheck1_1: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheck1_3: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 3)) + HasError = true; + break; + case SVETypeFlags::ImmCheck1_7: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, 7)) + HasError = true; + break; + case SVETypeFlags::ImmCheckExtract: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, + (2048 / ElementSizeInBits) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckShiftRight: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, + ElementSizeInBits)) + HasError = true; + break; + case SVETypeFlags::ImmCheckShiftRightNarrow: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 1, + ElementSizeInBits / 2)) + HasError = true; + break; + case SVETypeFlags::ImmCheckShiftLeft: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, + ElementSizeInBits - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckLaneIndex: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (1 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckLaneIndexCompRotate: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (2 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckLaneIndexDot: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, + (128 / (4 * ElementSizeInBits)) - 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheckComplexRot90_270: + if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; }, + diag::err_rotation_argument_to_cadd)) + HasError = true; + break; + case SVETypeFlags::ImmCheckComplexRotAll90: + if (CheckImmediateInSet( + [](int64_t V) { + return V == 0 || V == 90 || V == 180 || V == 270; + }, + diag::err_rotation_argument_to_cmla)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_1: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 1)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_2: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 2)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_3: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 3)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_0: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 0)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_15: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 15)) + HasError = true; + break; + case SVETypeFlags::ImmCheck0_255: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, 255)) + HasError = true; + break; + case SVETypeFlags::ImmCheck2_4_Mul2: + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 2, 4) || + SemaRef.BuiltinConstantArgMultiple(TheCall, ArgNum, 2)) + HasError = true; + break; + } + } + + return HasError; +} + +SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) { + if (FD->hasAttr()) + return SemaARM::ArmStreaming; + if (const Type *Ty = FD->getType().getTypePtrOrNull()) { + if (const auto *FPT = Ty->getAs()) { + if (FPT->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMEnabledMask) + return SemaARM::ArmStreaming; + if (FPT->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMCompatibleMask) + return SemaARM::ArmStreamingCompatible; + } + } + return SemaARM::ArmNonStreaming; +} + +static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, + const FunctionDecl *FD, + SemaARM::ArmStreamingType BuiltinType) { + SemaARM::ArmStreamingType FnType = getArmStreamingFnType(FD); + if (BuiltinType == SemaARM::ArmStreamingOrSVE2p1) { + // Check intrinsics that are available in [sve2p1 or sme/sme2]. + llvm::StringMap CallerFeatureMap; + S.Context.getFunctionFeatureMap(CallerFeatureMap, FD); + if (Builtin::evaluateRequiredTargetFeatures("sve2p1", CallerFeatureMap)) + BuiltinType = SemaARM::ArmStreamingCompatible; + else + BuiltinType = SemaARM::ArmStreaming; + } + + if (FnType == SemaARM::ArmStreaming && + BuiltinType == SemaARM::ArmNonStreaming) + S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) + << TheCall->getSourceRange() << "streaming"; + else if (FnType == SemaARM::ArmNonStreaming && BuiltinType == SemaARM::ArmStreaming) + S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) + << TheCall->getSourceRange() << "non-streaming"; + else if (FnType == SemaARM::ArmStreamingCompatible && + BuiltinType != SemaARM::ArmStreamingCompatible) + S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) + << TheCall->getSourceRange() << "streaming compatible"; +} + +static bool hasArmZAState(const FunctionDecl *FD) { + const auto *T = FD->getType()->getAs(); + return (T && FunctionType::getArmZAState(T->getAArch64SMEAttributes()) != + FunctionType::ARM_None) || + (FD->hasAttr() && FD->getAttr()->isNewZA()); +} + +static bool hasArmZT0State(const FunctionDecl *FD) { + const auto *T = FD->getType()->getAs(); + return (T && FunctionType::getArmZT0State(T->getAArch64SMEAttributes()) != + FunctionType::ARM_None) || + (FD->hasAttr() && FD->getAttr()->isNewZT0()); +} + +static ArmSMEState getSMEState(unsigned BuiltinID) { + switch (BuiltinID) { + default: + return ArmNoState; +#define GET_SME_BUILTIN_GET_STATE +#include "clang/Basic/arm_sme_builtins_za_state.inc" +#undef GET_SME_BUILTIN_GET_STATE + } +} + +bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + std::optional BuiltinType; + + switch (BuiltinID) { +#define GET_SME_STREAMING_ATTRS +#include "clang/Basic/arm_sme_streaming_attrs.inc" +#undef GET_SME_STREAMING_ATTRS + } + + if (BuiltinType) + checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType); + + if ((getSMEState(BuiltinID) & ArmZAMask) && !hasArmZAState(FD)) + Diag(TheCall->getBeginLoc(), + diag::warn_attribute_arm_za_builtin_no_za_state) + << TheCall->getSourceRange(); + + if ((getSMEState(BuiltinID) & ArmZT0Mask) && !hasArmZT0State(FD)) + Diag(TheCall->getBeginLoc(), + diag::warn_attribute_arm_zt0_builtin_no_zt0_state) + << TheCall->getSourceRange(); + } + + // Range check SME intrinsics that take immediate values. + SmallVector, 3> ImmChecks; + + switch (BuiltinID) { + default: + return false; +#define GET_SME_IMMEDIATE_CHECK +#include "clang/Basic/arm_sme_sema_rangechecks.inc" +#undef GET_SME_IMMEDIATE_CHECK + } + + return ParseSVEImmChecks(TheCall, ImmChecks); +} + +bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + std::optional BuiltinType; + + switch (BuiltinID) { +#define GET_SVE_STREAMING_ATTRS +#include "clang/Basic/arm_sve_streaming_attrs.inc" +#undef GET_SVE_STREAMING_ATTRS + } + if (BuiltinType) + checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType); + } + // Range check SVE intrinsics that take immediate values. + SmallVector, 3> ImmChecks; + + switch (BuiltinID) { + default: + return false; +#define GET_SVE_IMMEDIATE_CHECK +#include "clang/Basic/arm_sve_sema_rangechecks.inc" +#undef GET_SVE_IMMEDIATE_CHECK + } + + return ParseSVEImmChecks(TheCall, ImmChecks); +} + +bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + + switch (BuiltinID) { + default: + break; +#define GET_NEON_BUILTINS +#define TARGET_BUILTIN(id, ...) case NEON::BI##id: +#define BUILTIN(id, ...) case NEON::BI##id: +#include "clang/Basic/arm_neon.inc" + checkArmStreamingBuiltin(SemaRef, TheCall, FD, ArmNonStreaming); + break; +#undef TARGET_BUILTIN +#undef BUILTIN +#undef GET_NEON_BUILTINS + } + } + + llvm::APSInt Result; + uint64_t mask = 0; + unsigned TV = 0; + int PtrArgNum = -1; + bool HasConstPtr = false; + switch (BuiltinID) { +#define GET_NEON_OVERLOAD_CHECK +#include "clang/Basic/arm_fp16.inc" +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_OVERLOAD_CHECK + } + + // For NEON intrinsics which are overloaded on vector element type, validate + // the immediate which specifies which variant to emit. + unsigned ImmArg = TheCall->getNumArgs() - 1; + if (mask) { + if (SemaRef.BuiltinConstantArg(TheCall, ImmArg, Result)) + return true; + + TV = Result.getLimitedValue(64); + if ((TV > 63) || (mask & (1ULL << TV)) == 0) + return Diag(TheCall->getBeginLoc(), diag::err_invalid_neon_type_code) + << TheCall->getArg(ImmArg)->getSourceRange(); + } + + if (PtrArgNum >= 0) { + // Check that pointer arguments have the specified type. + Expr *Arg = TheCall->getArg(PtrArgNum); + if (ImplicitCastExpr *ICE = dyn_cast(Arg)) + Arg = ICE->getSubExpr(); + ExprResult RHS = SemaRef.DefaultFunctionArrayLvalueConversion(Arg); + QualType RHSTy = RHS.get()->getType(); + + llvm::Triple::ArchType Arch = TI.getTriple().getArch(); + bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 || + Arch == llvm::Triple::aarch64_32 || + Arch == llvm::Triple::aarch64_be; + bool IsInt64Long = TI.getInt64Type() == TargetInfo::SignedLong; + QualType EltTy = getNeonEltType(NeonTypeFlags(TV), getASTContext(), + IsPolyUnsigned, IsInt64Long); + if (HasConstPtr) + EltTy = EltTy.withConst(); + QualType LHSTy = getASTContext().getPointerType(EltTy); + Sema::AssignConvertType ConvTy; + ConvTy = SemaRef.CheckSingleAssignmentConstraints(LHSTy, RHS); + if (RHS.isInvalid()) + return true; + if (SemaRef.DiagnoseAssignmentResult(ConvTy, Arg->getBeginLoc(), LHSTy, + RHSTy, RHS.get(), Sema::AA_Assigning)) + return true; + } + + // For NEON intrinsics which take an immediate value as part of the + // instruction, range check them here. + unsigned i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: + return false; +#define GET_NEON_IMMEDIATE_CHECK +#include "clang/Basic/arm_fp16.inc" +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_IMMEDIATE_CHECK + } + + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l); +} + +bool SemaARM::CheckMVEBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + switch (BuiltinID) { + default: + return false; +#include "clang/Basic/arm_mve_builtin_sema.inc" + } +} + +bool SemaARM::CheckCDEBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + bool Err = false; + switch (BuiltinID) { + default: + return false; +#include "clang/Basic/arm_cde_builtin_sema.inc" + } + + if (Err) + return true; + + return CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), /*WantCDE*/ true); +} + +bool SemaARM::CheckARMCoprocessorImmediate(const TargetInfo &TI, + const Expr *CoprocArg, + bool WantCDE) { + ASTContext &Context = getASTContext(); + if (SemaRef.isConstantEvaluatedContext()) + return false; + + // We can't check the value of a dependent argument. + if (CoprocArg->isTypeDependent() || CoprocArg->isValueDependent()) + return false; + + llvm::APSInt CoprocNoAP = *CoprocArg->getIntegerConstantExpr(Context); + int64_t CoprocNo = CoprocNoAP.getExtValue(); + assert(CoprocNo >= 0 && "Coprocessor immediate must be non-negative"); + + uint32_t CDECoprocMask = TI.getARMCDECoprocMask(); + bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo)); + + if (IsCDECoproc != WantCDE) + return Diag(CoprocArg->getBeginLoc(), diag::err_arm_invalid_coproc) + << (int)CoprocNo << (int)WantCDE << CoprocArg->getSourceRange(); + + return false; +} + +bool SemaARM::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, + CallExpr *TheCall, + unsigned MaxWidth) { + assert((BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM::BI__builtin_arm_ldaex || + BuiltinID == ARM::BI__builtin_arm_strex || + BuiltinID == ARM::BI__builtin_arm_stlex || + BuiltinID == AArch64::BI__builtin_arm_ldrex || + BuiltinID == AArch64::BI__builtin_arm_ldaex || + BuiltinID == AArch64::BI__builtin_arm_strex || + BuiltinID == AArch64::BI__builtin_arm_stlex) && + "unexpected ARM builtin"); + bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM::BI__builtin_arm_ldaex || + BuiltinID == AArch64::BI__builtin_arm_ldrex || + BuiltinID == AArch64::BI__builtin_arm_ldaex; + + ASTContext &Context = getASTContext(); + DeclRefExpr *DRE = + cast(TheCall->getCallee()->IgnoreParenCasts()); + + // Ensure that we have the proper number of arguments. + if (SemaRef.checkArgCount(TheCall, IsLdrex ? 1 : 2)) + return true; + + // Inspect the pointer argument of the atomic builtin. This should always be + // a pointer type, whose element is an integral scalar or pointer type. + // Because it is a pointer type, we don't have to worry about any implicit + // casts here. + Expr *PointerArg = TheCall->getArg(IsLdrex ? 0 : 1); + ExprResult PointerArgRes = + SemaRef.DefaultFunctionArrayLvalueConversion(PointerArg); + if (PointerArgRes.isInvalid()) + return true; + PointerArg = PointerArgRes.get(); + + const PointerType *pointerType = PointerArg->getType()->getAs(); + if (!pointerType) { + Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) + << PointerArg->getType() << 0 << PointerArg->getSourceRange(); + return true; + } + + // ldrex takes a "const volatile T*" and strex takes a "volatile T*". Our next + // task is to insert the appropriate casts into the AST. First work out just + // what the appropriate type is. + QualType ValType = pointerType->getPointeeType(); + QualType AddrType = ValType.getUnqualifiedType().withVolatile(); + if (IsLdrex) + AddrType.addConst(); + + // Issue a warning if the cast is dodgy. + CastKind CastNeeded = CK_NoOp; + if (!AddrType.isAtLeastAsQualifiedAs(ValType)) { + CastNeeded = CK_BitCast; + Diag(DRE->getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers) + << PointerArg->getType() << Context.getPointerType(AddrType) + << Sema::AA_Passing << PointerArg->getSourceRange(); + } + + // Finally, do the cast and replace the argument with the corrected version. + AddrType = Context.getPointerType(AddrType); + PointerArgRes = SemaRef.ImpCastExprToType(PointerArg, AddrType, CastNeeded); + if (PointerArgRes.isInvalid()) + return true; + PointerArg = PointerArgRes.get(); + + TheCall->setArg(IsLdrex ? 0 : 1, PointerArg); + + // In general, we allow ints, floats and pointers to be loaded and stored. + if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && + !ValType->isBlockPointerType() && !ValType->isFloatingType()) { + Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr) + << PointerArg->getType() << 0 << PointerArg->getSourceRange(); + return true; + } + + // But ARM doesn't have instructions to deal with 128-bit versions. + if (Context.getTypeSize(ValType) > MaxWidth) { + assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); + Diag(DRE->getBeginLoc(), diag::err_atomic_exclusive_builtin_pointer_size) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + switch (ValType.getObjCLifetime()) { + case Qualifiers::OCL_None: + case Qualifiers::OCL_ExplicitNone: + // okay + break; + + case Qualifiers::OCL_Weak: + case Qualifiers::OCL_Strong: + case Qualifiers::OCL_Autoreleasing: + Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) + << ValType << PointerArg->getSourceRange(); + return true; + } + + if (IsLdrex) { + TheCall->setType(ValType); + return false; + } + + // Initialize the argument to be stored. + ExprResult ValArg = TheCall->getArg(0); + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, ValType, /*consume*/ false); + ValArg = SemaRef.PerformCopyInitialization(Entity, SourceLocation(), ValArg); + if (ValArg.isInvalid()) + return true; + TheCall->setArg(0, ValArg.get()); + + // __builtin_arm_strex always returns an int. It's marked as such in the .def, + // but the custom checker bypasses all default analysis. + TheCall->setType(Context.IntTy); + return false; +} + +bool SemaARM::CheckARMBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + if (BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM::BI__builtin_arm_ldaex || + BuiltinID == ARM::BI__builtin_arm_strex || + BuiltinID == ARM::BI__builtin_arm_stlex) { + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); + } + + if (BuiltinID == ARM::BI__builtin_arm_prefetch) { + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1); + } + + if (BuiltinID == ARM::BI__builtin_arm_rsr64 || + BuiltinID == ARM::BI__builtin_arm_wsr64) + return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 3, false); + + if (BuiltinID == ARM::BI__builtin_arm_rsr || + BuiltinID == ARM::BI__builtin_arm_rsrp || + BuiltinID == ARM::BI__builtin_arm_wsr || + BuiltinID == ARM::BI__builtin_arm_wsrp) + return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); + + if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) + return true; + if (CheckMVEBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + if (CheckCDEBuiltinFunctionCall(TI, BuiltinID, TheCall)) + return true; + + // For intrinsics which take an immediate value as part of the instruction, + // range check them here. + // FIXME: VFP Intrinsics should error if VFP not present. + switch (BuiltinID) { + default: + return false; + case ARM::BI__builtin_arm_ssat: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 32); + case ARM::BI__builtin_arm_usat: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case ARM::BI__builtin_arm_ssat16: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16); + case ARM::BI__builtin_arm_usat16: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case ARM::BI__builtin_arm_vcvtr_f: + case ARM::BI__builtin_arm_vcvtr_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); + case ARM::BI__builtin_arm_dmb: + case ARM::BI__builtin_arm_dsb: + case ARM::BI__builtin_arm_isb: + case ARM::BI__builtin_arm_dbg: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15); + case ARM::BI__builtin_arm_cdp: + case ARM::BI__builtin_arm_cdp2: + case ARM::BI__builtin_arm_mcr: + case ARM::BI__builtin_arm_mcr2: + case ARM::BI__builtin_arm_mrc: + case ARM::BI__builtin_arm_mrc2: + case ARM::BI__builtin_arm_mcrr: + case ARM::BI__builtin_arm_mcrr2: + case ARM::BI__builtin_arm_mrrc: + case ARM::BI__builtin_arm_mrrc2: + case ARM::BI__builtin_arm_ldc: + case ARM::BI__builtin_arm_ldcl: + case ARM::BI__builtin_arm_ldc2: + case ARM::BI__builtin_arm_ldc2l: + case ARM::BI__builtin_arm_stc: + case ARM::BI__builtin_arm_stcl: + case ARM::BI__builtin_arm_stc2: + case ARM::BI__builtin_arm_stc2l: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) || + CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), + /*WantCDE*/ false); + } +} + +bool SemaARM::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + if (BuiltinID == AArch64::BI__builtin_arm_ldrex || + BuiltinID == AArch64::BI__builtin_arm_ldaex || + BuiltinID == AArch64::BI__builtin_arm_strex || + BuiltinID == AArch64::BI__builtin_arm_stlex) { + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); + } + + if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 1) || + SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 1); + } + + if (BuiltinID == AArch64::BI__builtin_arm_rsr64 || + BuiltinID == AArch64::BI__builtin_arm_wsr64 || + BuiltinID == AArch64::BI__builtin_arm_rsr128 || + BuiltinID == AArch64::BI__builtin_arm_wsr128) + return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); + + // Memory Tagging Extensions (MTE) Intrinsics + if (BuiltinID == AArch64::BI__builtin_arm_irg || + BuiltinID == AArch64::BI__builtin_arm_addg || + BuiltinID == AArch64::BI__builtin_arm_gmi || + BuiltinID == AArch64::BI__builtin_arm_ldg || + BuiltinID == AArch64::BI__builtin_arm_stg || + BuiltinID == AArch64::BI__builtin_arm_subp) { + return BuiltinARMMemoryTaggingCall(BuiltinID, TheCall); + } + + if (BuiltinID == AArch64::BI__builtin_arm_rsr || + BuiltinID == AArch64::BI__builtin_arm_rsrp || + BuiltinID == AArch64::BI__builtin_arm_wsr || + BuiltinID == AArch64::BI__builtin_arm_wsrp) + return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); + + // Only check the valid encoding range. Any constant in this range would be + // converted to a register of the form S1_2_C3_C4_5. Let the hardware throw + // an exception for incorrect registers. This matches MSVC behavior. + if (BuiltinID == AArch64::BI_ReadStatusReg || + BuiltinID == AArch64::BI_WriteStatusReg) + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff); + + if (BuiltinID == AArch64::BI__getReg) + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31); + + if (BuiltinID == AArch64::BI__break) + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff); + + if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) + return true; + + if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + + if (CheckSMEBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + + // For intrinsics which take an immediate value as part of the instruction, + // range check them here. + unsigned i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: return false; + case AArch64::BI__builtin_arm_dmb: + case AArch64::BI__builtin_arm_dsb: + case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break; + case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break; + } + + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l); +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 22f5a2f66347..330cd602297d 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -15,6 +15,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DelayedDiagnostic.h" @@ -228,8 +229,9 @@ shouldDiagnoseAvailabilityByDefault(const ASTContext &Context, ForceAvailabilityFromVersion = VersionTuple(/*Major=*/10, /*Minor=*/13); break; case llvm::Triple::ShaderModel: - // Always enable availability diagnostics for shader models. - return true; + // FIXME: This will be updated when HLSL strict diagnostic mode + // is implemented (issue #90096) + return false; default: // New targets should always warn about availability. return Triple.getVendor() == llvm::Triple::Apple; @@ -409,10 +411,11 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, std::string PlatformName( AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName())); llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName( - TI.getTriple().getEnvironmentName())); + TI.getTriple().getEnvironment())); llvm::StringRef AttrEnvironment = AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName( - AA->getEnvironment()->getName()) + AvailabilityAttr::getEnvironmentType( + AA->getEnvironment()->getName())) : ""; bool UseEnvironment = (!AttrEnvironment.empty() && !TargetEnvironment.empty()); @@ -438,6 +441,10 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, << S.Context.getTargetInfo().getPlatformMinVersion().getAsString() << UseEnvironment << AttrEnvironment << TargetEnvironment; + // Do not offer to silence the warning or fixits for HLSL + if (S.getLangOpts().HLSL) + return; + if (const auto *Enclosing = findEnclosingDeclToAnnotate(Ctx)) { if (const auto *TD = dyn_cast(Enclosing)) if (TD->getDeclName().isEmpty()) { @@ -839,10 +846,11 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( std::string PlatformName( AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName())); llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName( - TI.getTriple().getEnvironmentName())); + TI.getTriple().getEnvironment())); llvm::StringRef AttrEnvironment = AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName( - AA->getEnvironment()->getName()) + AvailabilityAttr::getEnvironmentType( + AA->getEnvironment()->getName())) : ""; bool UseEnvironment = (!AttrEnvironment.empty() && !TargetEnvironment.empty()); @@ -865,6 +873,10 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( << SemaRef.Context.getTargetInfo().getPlatformMinVersion().getAsString() << UseEnvironment << AttrEnvironment << TargetEnvironment; + // Do not offer to silence the warning or fixits for HLSL + if (SemaRef.getLangOpts().HLSL) + return; + auto FixitDiag = SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence) << Range << D diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp new file mode 100644 index 000000000000..bde1a26f1ebc --- /dev/null +++ b/clang/lib/Sema/SemaBPF.cpp @@ -0,0 +1,174 @@ +//===------ SemaBPF.cpp ---------- BPF target-specific routines -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to BPF. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaBPF.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/APSInt.h" +#include + +namespace clang { + +SemaBPF::SemaBPF(Sema &S) : SemaBase(S) {} + +static bool isValidPreserveFieldInfoArg(Expr *Arg) { + if (Arg->getType()->getAsPlaceholderType()) + return false; + + // The first argument needs to be a record field access. + // If it is an array element access, we delay decision + // to BPF backend to check whether the access is a + // field access or not. + return (Arg->IgnoreParens()->getObjectKind() == OK_BitField || + isa(Arg->IgnoreParens()) || + isa(Arg->IgnoreParens())); +} + +static bool isValidPreserveTypeInfoArg(Expr *Arg) { + QualType ArgType = Arg->getType(); + if (ArgType->getAsPlaceholderType()) + return false; + + // for TYPE_EXISTENCE/TYPE_MATCH/TYPE_SIZEOF reloc type + // format: + // 1. __builtin_preserve_type_info(*( *)0, flag); + // 2. var; + // __builtin_preserve_type_info(var, flag); + if (!isa(Arg->IgnoreParens()) && + !isa(Arg->IgnoreParens())) + return false; + + // Typedef type. + if (ArgType->getAs()) + return true; + + // Record type or Enum type. + const Type *Ty = ArgType->getUnqualifiedDesugaredType(); + if (const auto *RT = Ty->getAs()) { + if (!RT->getDecl()->getDeclName().isEmpty()) + return true; + } else if (const auto *ET = Ty->getAs()) { + if (!ET->getDecl()->getDeclName().isEmpty()) + return true; + } + + return false; +} + +static bool isValidPreserveEnumValueArg(Expr *Arg) { + QualType ArgType = Arg->getType(); + if (ArgType->getAsPlaceholderType()) + return false; + + // for ENUM_VALUE_EXISTENCE/ENUM_VALUE reloc type + // format: + // __builtin_preserve_enum_value(*( *), + // flag); + const auto *UO = dyn_cast(Arg->IgnoreParens()); + if (!UO) + return false; + + const auto *CE = dyn_cast(UO->getSubExpr()); + if (!CE) + return false; + if (CE->getCastKind() != CK_IntegralToPointer && + CE->getCastKind() != CK_NullToPointer) + return false; + + // The integer must be from an EnumConstantDecl. + const auto *DR = dyn_cast(CE->getSubExpr()); + if (!DR) + return false; + + const EnumConstantDecl *Enumerator = + dyn_cast(DR->getDecl()); + if (!Enumerator) + return false; + + // The type must be EnumType. + const Type *Ty = ArgType->getUnqualifiedDesugaredType(); + const auto *ET = Ty->getAs(); + if (!ET) + return false; + + // The enum value must be supported. + return llvm::is_contained(ET->getDecl()->enumerators(), Enumerator); +} + +bool SemaBPF::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + assert((BuiltinID == BPF::BI__builtin_preserve_field_info || + BuiltinID == BPF::BI__builtin_btf_type_id || + BuiltinID == BPF::BI__builtin_preserve_type_info || + BuiltinID == BPF::BI__builtin_preserve_enum_value) && + "unexpected BPF builtin"); + ASTContext &Context = getASTContext(); + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + + // The second argument needs to be a constant int + Expr *Arg = TheCall->getArg(1); + std::optional Value = Arg->getIntegerConstantExpr(Context); + diag::kind kind; + if (!Value) { + if (BuiltinID == BPF::BI__builtin_preserve_field_info) + kind = diag::err_preserve_field_info_not_const; + else if (BuiltinID == BPF::BI__builtin_btf_type_id) + kind = diag::err_btf_type_id_not_const; + else if (BuiltinID == BPF::BI__builtin_preserve_type_info) + kind = diag::err_preserve_type_info_not_const; + else + kind = diag::err_preserve_enum_value_not_const; + Diag(Arg->getBeginLoc(), kind) << 2 << Arg->getSourceRange(); + return true; + } + + // The first argument + Arg = TheCall->getArg(0); + bool InvalidArg = false; + bool ReturnUnsignedInt = true; + if (BuiltinID == BPF::BI__builtin_preserve_field_info) { + if (!isValidPreserveFieldInfoArg(Arg)) { + InvalidArg = true; + kind = diag::err_preserve_field_info_not_field; + } + } else if (BuiltinID == BPF::BI__builtin_preserve_type_info) { + if (!isValidPreserveTypeInfoArg(Arg)) { + InvalidArg = true; + kind = diag::err_preserve_type_info_invalid; + } + } else if (BuiltinID == BPF::BI__builtin_preserve_enum_value) { + if (!isValidPreserveEnumValueArg(Arg)) { + InvalidArg = true; + kind = diag::err_preserve_enum_value_invalid; + } + ReturnUnsignedInt = false; + } else if (BuiltinID == BPF::BI__builtin_btf_type_id) { + ReturnUnsignedInt = false; + } + + if (InvalidArg) { + Diag(Arg->getBeginLoc(), kind) << 1 << Arg->getSourceRange(); + return true; + } + + if (ReturnUnsignedInt) + TheCall->setType(Context.UnsignedIntTy); + else + TheCall->setType(Context.UnsignedLongTy); + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaBase.cpp b/clang/lib/Sema/SemaBase.cpp index 0442fb2929e3..a2f12d622e8c 100644 --- a/clang/lib/Sema/SemaBase.cpp +++ b/clang/lib/Sema/SemaBase.cpp @@ -29,6 +29,10 @@ SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() { SemaRef.EmitCurrentDiagnostic(DiagID); } +PartialDiagnostic SemaBase::PDiag(unsigned DiagID) { + return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator()); +} + const SemaBase::SemaDiagnosticBuilder & operator<<(const SemaBase::SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD) { diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 7db6b1dfe923..f03dcf05411d 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1093,9 +1093,10 @@ static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, return true; // Allow integral type mismatch if their size are equal. - if (SrcType->isIntegralType(Context) && DestType->isIntegralType(Context)) - if (Context.getTypeInfoInChars(SrcType).Width == - Context.getTypeInfoInChars(DestType).Width) + if ((SrcType->isIntegralType(Context) || SrcType->isEnumeralType()) && + (DestType->isIntegralType(Context) || DestType->isEnumeralType())) + if (Context.getTypeSizeInChars(SrcType) == + Context.getTypeSizeInChars(DestType)) return true; return Context.hasSameUnqualifiedType(SrcType, DestType); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c3251f3cc9d8..300af0223977 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -61,9 +61,19 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaAMDGPU.h" +#include "clang/Sema/SemaARM.h" +#include "clang/Sema/SemaBPF.h" +#include "clang/Sema/SemaHexagon.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaLoongArch.h" +#include "clang/Sema/SemaMIPS.h" +#include "clang/Sema/SemaNVPTX.h" #include "clang/Sema/SemaObjC.h" +#include "clang/Sema/SemaPPC.h" #include "clang/Sema/SemaRISCV.h" +#include "clang/Sema/SemaSystemZ.h" +#include "clang/Sema/SemaWasm.h" #include "clang/Sema/SemaX86.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -2259,23 +2269,23 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: - return CheckARMBuiltinFunctionCall(TI, BuiltinID, TheCall); + return ARM().CheckARMBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::aarch64: case llvm::Triple::aarch64_32: case llvm::Triple::aarch64_be: - return CheckAArch64BuiltinFunctionCall(TI, BuiltinID, TheCall); + return ARM().CheckAArch64BuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::bpfeb: case llvm::Triple::bpfel: - return CheckBPFBuiltinFunctionCall(BuiltinID, TheCall); + return BPF().CheckBPFBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::hexagon: - return CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall); + return Hexagon().CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: - return CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall); + return MIPS().CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::systemz: - return CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall); + return SystemZ().CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::x86: case llvm::Triple::x86_64: return X86().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall); @@ -2283,21 +2293,22 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, case llvm::Triple::ppcle: case llvm::Triple::ppc64: case llvm::Triple::ppc64le: - return CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall); + return PPC().CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::amdgcn: - return CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall); + return AMDGPU().CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::riscv32: case llvm::Triple::riscv64: return RISCV().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::loongarch32: case llvm::Triple::loongarch64: - return CheckLoongArchBuiltinFunctionCall(TI, BuiltinID, TheCall); + return LoongArch().CheckLoongArchBuiltinFunctionCall(TI, BuiltinID, + TheCall); case llvm::Triple::wasm32: case llvm::Triple::wasm64: - return CheckWebAssemblyBuiltinFunctionCall(TI, BuiltinID, TheCall); + return Wasm().CheckWebAssemblyBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::nvptx: case llvm::Triple::nvptx64: - return CheckNVPTXBuiltinFunctionCall(TI, BuiltinID, TheCall); + return NVPTX().CheckNVPTXBuiltinFunctionCall(TI, BuiltinID, TheCall); } } @@ -3287,1988 +3298,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return TheCallResult; } -// Get the valid immediate range for the specified NEON type code. -static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { - NeonTypeFlags Type(t); - int IsQuad = ForceQuad ? true : Type.isQuad(); - switch (Type.getEltType()) { - case NeonTypeFlags::Int8: - case NeonTypeFlags::Poly8: - return shift ? 7 : (8 << IsQuad) - 1; - case NeonTypeFlags::Int16: - case NeonTypeFlags::Poly16: - return shift ? 15 : (4 << IsQuad) - 1; - case NeonTypeFlags::Int32: - return shift ? 31 : (2 << IsQuad) - 1; - case NeonTypeFlags::Int64: - case NeonTypeFlags::Poly64: - return shift ? 63 : (1 << IsQuad) - 1; - case NeonTypeFlags::Poly128: - return shift ? 127 : (1 << IsQuad) - 1; - case NeonTypeFlags::Float16: - assert(!shift && "cannot shift float types!"); - return (4 << IsQuad) - 1; - case NeonTypeFlags::Float32: - assert(!shift && "cannot shift float types!"); - return (2 << IsQuad) - 1; - case NeonTypeFlags::Float64: - assert(!shift && "cannot shift float types!"); - return (1 << IsQuad) - 1; - case NeonTypeFlags::BFloat16: - assert(!shift && "cannot shift float types!"); - return (4 << IsQuad) - 1; - } - llvm_unreachable("Invalid NeonTypeFlag!"); -} - -/// getNeonEltType - Return the QualType corresponding to the elements of -/// the vector type specified by the NeonTypeFlags. This is used to check -/// the pointer arguments for Neon load/store intrinsics. -static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, - bool IsPolyUnsigned, bool IsInt64Long) { - switch (Flags.getEltType()) { - case NeonTypeFlags::Int8: - return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; - case NeonTypeFlags::Int16: - return Flags.isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy; - case NeonTypeFlags::Int32: - return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy; - case NeonTypeFlags::Int64: - if (IsInt64Long) - return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy; - else - return Flags.isUnsigned() ? Context.UnsignedLongLongTy - : Context.LongLongTy; - case NeonTypeFlags::Poly8: - return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy; - case NeonTypeFlags::Poly16: - return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy; - case NeonTypeFlags::Poly64: - if (IsInt64Long) - return Context.UnsignedLongTy; - else - return Context.UnsignedLongLongTy; - case NeonTypeFlags::Poly128: - break; - case NeonTypeFlags::Float16: - return Context.HalfTy; - case NeonTypeFlags::Float32: - return Context.FloatTy; - case NeonTypeFlags::Float64: - return Context.DoubleTy; - case NeonTypeFlags::BFloat16: - return Context.BFloat16Ty; - } - llvm_unreachable("Invalid NeonTypeFlag!"); -} - -enum ArmStreamingType { - ArmNonStreaming, - ArmStreaming, - ArmStreamingCompatible, - ArmStreamingOrSVE2p1 -}; - -enum ArmSMEState : unsigned { - ArmNoState = 0, - - ArmInZA = 0b01, - ArmOutZA = 0b10, - ArmInOutZA = 0b11, - ArmZAMask = 0b11, - - ArmInZT0 = 0b01 << 2, - ArmOutZT0 = 0b10 << 2, - ArmInOutZT0 = 0b11 << 2, - ArmZT0Mask = 0b11 << 2 -}; - -bool Sema::ParseSVEImmChecks( - CallExpr *TheCall, SmallVector, 3> &ImmChecks) { - // Perform all the immediate checks for this builtin call. - bool HasError = false; - for (auto &I : ImmChecks) { - int ArgNum, CheckTy, ElementSizeInBits; - std::tie(ArgNum, CheckTy, ElementSizeInBits) = I; - - typedef bool (*OptionSetCheckFnTy)(int64_t Value); - - // Function that checks whether the operand (ArgNum) is an immediate - // that is one of the predefined values. - auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm, - int ErrDiag) -> bool { - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check constant-ness first. - llvm::APSInt Imm; - if (BuiltinConstantArg(TheCall, ArgNum, Imm)) - return true; - - if (!CheckImm(Imm.getSExtValue())) - return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); - return false; - }; - - switch ((SVETypeFlags::ImmCheckType)CheckTy) { - case SVETypeFlags::ImmCheck0_31: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_13: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 13)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_16: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, 16)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_7: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 7)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_1: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_3: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, 3)) - HasError = true; - break; - case SVETypeFlags::ImmCheck1_7: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, 7)) - HasError = true; - break; - case SVETypeFlags::ImmCheckExtract: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, - (2048 / ElementSizeInBits) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftRight: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, ElementSizeInBits)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftRightNarrow: - if (BuiltinConstantArgRange(TheCall, ArgNum, 1, ElementSizeInBits / 2)) - HasError = true; - break; - case SVETypeFlags::ImmCheckShiftLeft: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, ElementSizeInBits - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndex: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (1 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndexCompRotate: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (2 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckLaneIndexDot: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, - (128 / (4 * ElementSizeInBits)) - 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheckComplexRot90_270: - if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; }, - diag::err_rotation_argument_to_cadd)) - HasError = true; - break; - case SVETypeFlags::ImmCheckComplexRotAll90: - if (CheckImmediateInSet( - [](int64_t V) { - return V == 0 || V == 90 || V == 180 || V == 270; - }, - diag::err_rotation_argument_to_cmla)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_1: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 1)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_2: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 2)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_3: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 3)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_0: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 0)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_15: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 15)) - HasError = true; - break; - case SVETypeFlags::ImmCheck0_255: - if (BuiltinConstantArgRange(TheCall, ArgNum, 0, 255)) - HasError = true; - break; - case SVETypeFlags::ImmCheck2_4_Mul2: - if (BuiltinConstantArgRange(TheCall, ArgNum, 2, 4) || - BuiltinConstantArgMultiple(TheCall, ArgNum, 2)) - HasError = true; - break; - } - } - - return HasError; -} - -static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) { - if (FD->hasAttr()) - return ArmStreaming; - if (const Type *Ty = FD->getType().getTypePtrOrNull()) { - if (const auto *FPT = Ty->getAs()) { - if (FPT->getAArch64SMEAttributes() & - FunctionType::SME_PStateSMEnabledMask) - return ArmStreaming; - if (FPT->getAArch64SMEAttributes() & - FunctionType::SME_PStateSMCompatibleMask) - return ArmStreamingCompatible; - } - } - return ArmNonStreaming; -} - -static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, - const FunctionDecl *FD, - ArmStreamingType BuiltinType) { - ArmStreamingType FnType = getArmStreamingFnType(FD); - if (BuiltinType == ArmStreamingOrSVE2p1) { - // Check intrinsics that are available in [sve2p1 or sme/sme2]. - llvm::StringMap CallerFeatureMap; - S.Context.getFunctionFeatureMap(CallerFeatureMap, FD); - if (Builtin::evaluateRequiredTargetFeatures("sve2p1", CallerFeatureMap)) - BuiltinType = ArmStreamingCompatible; - else - BuiltinType = ArmStreaming; - } - - if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) { - S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) - << TheCall->getSourceRange() << "streaming"; - } - - if (FnType == ArmStreamingCompatible && - BuiltinType != ArmStreamingCompatible) { - S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) - << TheCall->getSourceRange() << "streaming compatible"; - return; - } - - if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) { - S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin) - << TheCall->getSourceRange() << "non-streaming"; - } -} - -static bool hasArmZAState(const FunctionDecl *FD) { - const auto *T = FD->getType()->getAs(); - return (T && FunctionType::getArmZAState(T->getAArch64SMEAttributes()) != - FunctionType::ARM_None) || - (FD->hasAttr() && FD->getAttr()->isNewZA()); -} - -static bool hasArmZT0State(const FunctionDecl *FD) { - const auto *T = FD->getType()->getAs(); - return (T && FunctionType::getArmZT0State(T->getAArch64SMEAttributes()) != - FunctionType::ARM_None) || - (FD->hasAttr() && FD->getAttr()->isNewZT0()); -} - -static ArmSMEState getSMEState(unsigned BuiltinID) { - switch (BuiltinID) { - default: - return ArmNoState; -#define GET_SME_BUILTIN_GET_STATE -#include "clang/Basic/arm_sme_builtins_za_state.inc" -#undef GET_SME_BUILTIN_GET_STATE - } -} - -bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = getCurFunctionDecl()) { - std::optional BuiltinType; - - switch (BuiltinID) { -#define GET_SME_STREAMING_ATTRS -#include "clang/Basic/arm_sme_streaming_attrs.inc" -#undef GET_SME_STREAMING_ATTRS - } - - if (BuiltinType) - checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType); - - if ((getSMEState(BuiltinID) & ArmZAMask) && !hasArmZAState(FD)) - Diag(TheCall->getBeginLoc(), - diag::warn_attribute_arm_za_builtin_no_za_state) - << TheCall->getSourceRange(); - - if ((getSMEState(BuiltinID) & ArmZT0Mask) && !hasArmZT0State(FD)) - Diag(TheCall->getBeginLoc(), - diag::warn_attribute_arm_zt0_builtin_no_zt0_state) - << TheCall->getSourceRange(); - } - - // Range check SME intrinsics that take immediate values. - SmallVector, 3> ImmChecks; - - switch (BuiltinID) { - default: - return false; -#define GET_SME_IMMEDIATE_CHECK -#include "clang/Basic/arm_sme_sema_rangechecks.inc" -#undef GET_SME_IMMEDIATE_CHECK - } - - return ParseSVEImmChecks(TheCall, ImmChecks); -} - -bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = getCurFunctionDecl()) { - std::optional BuiltinType; - - switch (BuiltinID) { -#define GET_SVE_STREAMING_ATTRS -#include "clang/Basic/arm_sve_streaming_attrs.inc" -#undef GET_SVE_STREAMING_ATTRS - } - if (BuiltinType) - checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType); - } - // Range check SVE intrinsics that take immediate values. - SmallVector, 3> ImmChecks; - - switch (BuiltinID) { - default: - return false; -#define GET_SVE_IMMEDIATE_CHECK -#include "clang/Basic/arm_sve_sema_rangechecks.inc" -#undef GET_SVE_IMMEDIATE_CHECK - } - - return ParseSVEImmChecks(TheCall, ImmChecks); -} - -bool Sema::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = getCurFunctionDecl()) { - - switch (BuiltinID) { - default: - break; -#define GET_NEON_BUILTINS -#define TARGET_BUILTIN(id, ...) case NEON::BI##id: -#define BUILTIN(id, ...) case NEON::BI##id: -#include "clang/Basic/arm_neon.inc" - checkArmStreamingBuiltin(*this, TheCall, FD, ArmNonStreaming); - break; -#undef TARGET_BUILTIN -#undef BUILTIN -#undef GET_NEON_BUILTINS - } - } - - llvm::APSInt Result; - uint64_t mask = 0; - unsigned TV = 0; - int PtrArgNum = -1; - bool HasConstPtr = false; - switch (BuiltinID) { -#define GET_NEON_OVERLOAD_CHECK -#include "clang/Basic/arm_neon.inc" -#include "clang/Basic/arm_fp16.inc" -#undef GET_NEON_OVERLOAD_CHECK - } - - // For NEON intrinsics which are overloaded on vector element type, validate - // the immediate which specifies which variant to emit. - unsigned ImmArg = TheCall->getNumArgs()-1; - if (mask) { - if (BuiltinConstantArg(TheCall, ImmArg, Result)) - return true; - - TV = Result.getLimitedValue(64); - if ((TV > 63) || (mask & (1ULL << TV)) == 0) - return Diag(TheCall->getBeginLoc(), diag::err_invalid_neon_type_code) - << TheCall->getArg(ImmArg)->getSourceRange(); - } - - if (PtrArgNum >= 0) { - // Check that pointer arguments have the specified type. - Expr *Arg = TheCall->getArg(PtrArgNum); - if (ImplicitCastExpr *ICE = dyn_cast(Arg)) - Arg = ICE->getSubExpr(); - ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); - QualType RHSTy = RHS.get()->getType(); - - llvm::Triple::ArchType Arch = TI.getTriple().getArch(); - bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 || - Arch == llvm::Triple::aarch64_32 || - Arch == llvm::Triple::aarch64_be; - bool IsInt64Long = TI.getInt64Type() == TargetInfo::SignedLong; - QualType EltTy = - getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long); - if (HasConstPtr) - EltTy = EltTy.withConst(); - QualType LHSTy = Context.getPointerType(EltTy); - AssignConvertType ConvTy; - ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); - if (RHS.isInvalid()) - return true; - if (DiagnoseAssignmentResult(ConvTy, Arg->getBeginLoc(), LHSTy, RHSTy, - RHS.get(), AA_Assigning)) - return true; - } - - // For NEON intrinsics which take an immediate value as part of the - // instruction, range check them here. - unsigned i = 0, l = 0, u = 0; - switch (BuiltinID) { - default: - return false; - #define GET_NEON_IMMEDIATE_CHECK - #include "clang/Basic/arm_neon.inc" - #include "clang/Basic/arm_fp16.inc" - #undef GET_NEON_IMMEDIATE_CHECK - } - - return BuiltinConstantArgRange(TheCall, i, l, u + l); -} - -bool Sema::CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - switch (BuiltinID) { - default: - return false; - #include "clang/Basic/arm_mve_builtin_sema.inc" - } -} - -bool Sema::CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall) { - bool Err = false; - switch (BuiltinID) { - default: - return false; -#include "clang/Basic/arm_cde_builtin_sema.inc" - } - - if (Err) - return true; - - return CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), /*WantCDE*/ true); -} - -bool Sema::CheckARMCoprocessorImmediate(const TargetInfo &TI, - const Expr *CoprocArg, bool WantCDE) { - if (isConstantEvaluatedContext()) - return false; - - // We can't check the value of a dependent argument. - if (CoprocArg->isTypeDependent() || CoprocArg->isValueDependent()) - return false; - - llvm::APSInt CoprocNoAP = *CoprocArg->getIntegerConstantExpr(Context); - int64_t CoprocNo = CoprocNoAP.getExtValue(); - assert(CoprocNo >= 0 && "Coprocessor immediate must be non-negative"); - - uint32_t CDECoprocMask = TI.getARMCDECoprocMask(); - bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo)); - - if (IsCDECoproc != WantCDE) - return Diag(CoprocArg->getBeginLoc(), diag::err_arm_invalid_coproc) - << (int)CoprocNo << (int)WantCDE << CoprocArg->getSourceRange(); - - return false; -} - -bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, - unsigned MaxWidth) { - assert((BuiltinID == ARM::BI__builtin_arm_ldrex || - BuiltinID == ARM::BI__builtin_arm_ldaex || - BuiltinID == ARM::BI__builtin_arm_strex || - BuiltinID == ARM::BI__builtin_arm_stlex || - BuiltinID == AArch64::BI__builtin_arm_ldrex || - BuiltinID == AArch64::BI__builtin_arm_ldaex || - BuiltinID == AArch64::BI__builtin_arm_strex || - BuiltinID == AArch64::BI__builtin_arm_stlex) && - "unexpected ARM builtin"); - bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || - BuiltinID == ARM::BI__builtin_arm_ldaex || - BuiltinID == AArch64::BI__builtin_arm_ldrex || - BuiltinID == AArch64::BI__builtin_arm_ldaex; - - DeclRefExpr *DRE =cast(TheCall->getCallee()->IgnoreParenCasts()); - - // Ensure that we have the proper number of arguments. - if (checkArgCount(TheCall, IsLdrex ? 1 : 2)) - return true; - - // Inspect the pointer argument of the atomic builtin. This should always be - // a pointer type, whose element is an integral scalar or pointer type. - // Because it is a pointer type, we don't have to worry about any implicit - // casts here. - Expr *PointerArg = TheCall->getArg(IsLdrex ? 0 : 1); - ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg); - if (PointerArgRes.isInvalid()) - return true; - PointerArg = PointerArgRes.get(); - - const PointerType *pointerType = PointerArg->getType()->getAs(); - if (!pointerType) { - Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) - << PointerArg->getType() << 0 << PointerArg->getSourceRange(); - return true; - } - - // ldrex takes a "const volatile T*" and strex takes a "volatile T*". Our next - // task is to insert the appropriate casts into the AST. First work out just - // what the appropriate type is. - QualType ValType = pointerType->getPointeeType(); - QualType AddrType = ValType.getUnqualifiedType().withVolatile(); - if (IsLdrex) - AddrType.addConst(); - - // Issue a warning if the cast is dodgy. - CastKind CastNeeded = CK_NoOp; - if (!AddrType.isAtLeastAsQualifiedAs(ValType)) { - CastNeeded = CK_BitCast; - Diag(DRE->getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers) - << PointerArg->getType() << Context.getPointerType(AddrType) - << AA_Passing << PointerArg->getSourceRange(); - } - - // Finally, do the cast and replace the argument with the corrected version. - AddrType = Context.getPointerType(AddrType); - PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded); - if (PointerArgRes.isInvalid()) - return true; - PointerArg = PointerArgRes.get(); - - TheCall->setArg(IsLdrex ? 0 : 1, PointerArg); - - // In general, we allow ints, floats and pointers to be loaded and stored. - if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && - !ValType->isBlockPointerType() && !ValType->isFloatingType()) { - Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr) - << PointerArg->getType() << 0 << PointerArg->getSourceRange(); - return true; - } - - // But ARM doesn't have instructions to deal with 128-bit versions. - if (Context.getTypeSize(ValType) > MaxWidth) { - assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); - Diag(DRE->getBeginLoc(), diag::err_atomic_exclusive_builtin_pointer_size) - << PointerArg->getType() << PointerArg->getSourceRange(); - return true; - } - - switch (ValType.getObjCLifetime()) { - case Qualifiers::OCL_None: - case Qualifiers::OCL_ExplicitNone: - // okay - break; - - case Qualifiers::OCL_Weak: - case Qualifiers::OCL_Strong: - case Qualifiers::OCL_Autoreleasing: - Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) - << ValType << PointerArg->getSourceRange(); - return true; - } - - if (IsLdrex) { - TheCall->setType(ValType); - return false; - } - - // Initialize the argument to be stored. - ExprResult ValArg = TheCall->getArg(0); - InitializedEntity Entity = InitializedEntity::InitializeParameter( - Context, ValType, /*consume*/ false); - ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); - if (ValArg.isInvalid()) - return true; - TheCall->setArg(0, ValArg.get()); - - // __builtin_arm_strex always returns an int. It's marked as such in the .def, - // but the custom checker bypasses all default analysis. - TheCall->setType(Context.IntTy); - return false; -} - -bool Sema::CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall) { - if (BuiltinID == ARM::BI__builtin_arm_ldrex || - BuiltinID == ARM::BI__builtin_arm_ldaex || - BuiltinID == ARM::BI__builtin_arm_strex || - BuiltinID == ARM::BI__builtin_arm_stlex) { - return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); - } - - if (BuiltinID == ARM::BI__builtin_arm_prefetch) { - return BuiltinConstantArgRange(TheCall, 1, 0, 1) || - BuiltinConstantArgRange(TheCall, 2, 0, 1); - } - - if (BuiltinID == ARM::BI__builtin_arm_rsr64 || - BuiltinID == ARM::BI__builtin_arm_wsr64) - return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 3, false); - - if (BuiltinID == ARM::BI__builtin_arm_rsr || - BuiltinID == ARM::BI__builtin_arm_rsrp || - BuiltinID == ARM::BI__builtin_arm_wsr || - BuiltinID == ARM::BI__builtin_arm_wsrp) - return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); - - if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) - return true; - if (CheckMVEBuiltinFunctionCall(BuiltinID, TheCall)) - return true; - if (CheckCDEBuiltinFunctionCall(TI, BuiltinID, TheCall)) - return true; - - // For intrinsics which take an immediate value as part of the instruction, - // range check them here. - // FIXME: VFP Intrinsics should error if VFP not present. - switch (BuiltinID) { - default: return false; - case ARM::BI__builtin_arm_ssat: - return BuiltinConstantArgRange(TheCall, 1, 1, 32); - case ARM::BI__builtin_arm_usat: - return BuiltinConstantArgRange(TheCall, 1, 0, 31); - case ARM::BI__builtin_arm_ssat16: - return BuiltinConstantArgRange(TheCall, 1, 1, 16); - case ARM::BI__builtin_arm_usat16: - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - case ARM::BI__builtin_arm_vcvtr_f: - case ARM::BI__builtin_arm_vcvtr_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 1); - case ARM::BI__builtin_arm_dmb: - case ARM::BI__builtin_arm_dsb: - case ARM::BI__builtin_arm_isb: - case ARM::BI__builtin_arm_dbg: - return BuiltinConstantArgRange(TheCall, 0, 0, 15); - case ARM::BI__builtin_arm_cdp: - case ARM::BI__builtin_arm_cdp2: - case ARM::BI__builtin_arm_mcr: - case ARM::BI__builtin_arm_mcr2: - case ARM::BI__builtin_arm_mrc: - case ARM::BI__builtin_arm_mrc2: - case ARM::BI__builtin_arm_mcrr: - case ARM::BI__builtin_arm_mcrr2: - case ARM::BI__builtin_arm_mrrc: - case ARM::BI__builtin_arm_mrrc2: - case ARM::BI__builtin_arm_ldc: - case ARM::BI__builtin_arm_ldcl: - case ARM::BI__builtin_arm_ldc2: - case ARM::BI__builtin_arm_ldc2l: - case ARM::BI__builtin_arm_stc: - case ARM::BI__builtin_arm_stcl: - case ARM::BI__builtin_arm_stc2: - case ARM::BI__builtin_arm_stc2l: - return BuiltinConstantArgRange(TheCall, 0, 0, 15) || - CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), - /*WantCDE*/ false); - } -} - -bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall) { - if (BuiltinID == AArch64::BI__builtin_arm_ldrex || - BuiltinID == AArch64::BI__builtin_arm_ldaex || - BuiltinID == AArch64::BI__builtin_arm_strex || - BuiltinID == AArch64::BI__builtin_arm_stlex) { - return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); - } - - if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { - return BuiltinConstantArgRange(TheCall, 1, 0, 1) || - BuiltinConstantArgRange(TheCall, 2, 0, 3) || - BuiltinConstantArgRange(TheCall, 3, 0, 1) || - BuiltinConstantArgRange(TheCall, 4, 0, 1); - } - - if (BuiltinID == AArch64::BI__builtin_arm_rsr64 || - BuiltinID == AArch64::BI__builtin_arm_wsr64 || - BuiltinID == AArch64::BI__builtin_arm_rsr128 || - BuiltinID == AArch64::BI__builtin_arm_wsr128) - return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); - - // Memory Tagging Extensions (MTE) Intrinsics - if (BuiltinID == AArch64::BI__builtin_arm_irg || - BuiltinID == AArch64::BI__builtin_arm_addg || - BuiltinID == AArch64::BI__builtin_arm_gmi || - BuiltinID == AArch64::BI__builtin_arm_ldg || - BuiltinID == AArch64::BI__builtin_arm_stg || - BuiltinID == AArch64::BI__builtin_arm_subp) { - return BuiltinARMMemoryTaggingCall(BuiltinID, TheCall); - } - - if (BuiltinID == AArch64::BI__builtin_arm_rsr || - BuiltinID == AArch64::BI__builtin_arm_rsrp || - BuiltinID == AArch64::BI__builtin_arm_wsr || - BuiltinID == AArch64::BI__builtin_arm_wsrp) - return BuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); - - // Only check the valid encoding range. Any constant in this range would be - // converted to a register of the form S1_2_C3_C4_5. Let the hardware throw - // an exception for incorrect registers. This matches MSVC behavior. - if (BuiltinID == AArch64::BI_ReadStatusReg || - BuiltinID == AArch64::BI_WriteStatusReg) - return BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff); - - if (BuiltinID == AArch64::BI__getReg) - return BuiltinConstantArgRange(TheCall, 0, 0, 31); - - if (BuiltinID == AArch64::BI__break) - return BuiltinConstantArgRange(TheCall, 0, 0, 0xffff); - - if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) - return true; - - if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall)) - return true; - - if (CheckSMEBuiltinFunctionCall(BuiltinID, TheCall)) - return true; - - // For intrinsics which take an immediate value as part of the instruction, - // range check them here. - unsigned i = 0, l = 0, u = 0; - switch (BuiltinID) { - default: return false; - case AArch64::BI__builtin_arm_dmb: - case AArch64::BI__builtin_arm_dsb: - case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break; - case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break; - } - - return BuiltinConstantArgRange(TheCall, i, l, u + l); -} - -static bool isValidBPFPreserveFieldInfoArg(Expr *Arg) { - if (Arg->getType()->getAsPlaceholderType()) - return false; - - // The first argument needs to be a record field access. - // If it is an array element access, we delay decision - // to BPF backend to check whether the access is a - // field access or not. - return (Arg->IgnoreParens()->getObjectKind() == OK_BitField || - isa(Arg->IgnoreParens()) || - isa(Arg->IgnoreParens())); -} - -static bool isValidBPFPreserveTypeInfoArg(Expr *Arg) { - QualType ArgType = Arg->getType(); - if (ArgType->getAsPlaceholderType()) - return false; - - // for TYPE_EXISTENCE/TYPE_MATCH/TYPE_SIZEOF reloc type - // format: - // 1. __builtin_preserve_type_info(*( *)0, flag); - // 2. var; - // __builtin_preserve_type_info(var, flag); - if (!isa(Arg->IgnoreParens()) && - !isa(Arg->IgnoreParens())) - return false; - - // Typedef type. - if (ArgType->getAs()) - return true; - - // Record type or Enum type. - const Type *Ty = ArgType->getUnqualifiedDesugaredType(); - if (const auto *RT = Ty->getAs()) { - if (!RT->getDecl()->getDeclName().isEmpty()) - return true; - } else if (const auto *ET = Ty->getAs()) { - if (!ET->getDecl()->getDeclName().isEmpty()) - return true; - } - - return false; -} - -static bool isValidBPFPreserveEnumValueArg(Expr *Arg) { - QualType ArgType = Arg->getType(); - if (ArgType->getAsPlaceholderType()) - return false; - - // for ENUM_VALUE_EXISTENCE/ENUM_VALUE reloc type - // format: - // __builtin_preserve_enum_value(*( *), - // flag); - const auto *UO = dyn_cast(Arg->IgnoreParens()); - if (!UO) - return false; - - const auto *CE = dyn_cast(UO->getSubExpr()); - if (!CE) - return false; - if (CE->getCastKind() != CK_IntegralToPointer && - CE->getCastKind() != CK_NullToPointer) - return false; - - // The integer must be from an EnumConstantDecl. - const auto *DR = dyn_cast(CE->getSubExpr()); - if (!DR) - return false; - - const EnumConstantDecl *Enumerator = - dyn_cast(DR->getDecl()); - if (!Enumerator) - return false; - - // The type must be EnumType. - const Type *Ty = ArgType->getUnqualifiedDesugaredType(); - const auto *ET = Ty->getAs(); - if (!ET) - return false; - - // The enum value must be supported. - return llvm::is_contained(ET->getDecl()->enumerators(), Enumerator); -} - -bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, - CallExpr *TheCall) { - assert((BuiltinID == BPF::BI__builtin_preserve_field_info || - BuiltinID == BPF::BI__builtin_btf_type_id || - BuiltinID == BPF::BI__builtin_preserve_type_info || - BuiltinID == BPF::BI__builtin_preserve_enum_value) && - "unexpected BPF builtin"); - - if (checkArgCount(TheCall, 2)) - return true; - - // The second argument needs to be a constant int - Expr *Arg = TheCall->getArg(1); - std::optional Value = Arg->getIntegerConstantExpr(Context); - diag::kind kind; - if (!Value) { - if (BuiltinID == BPF::BI__builtin_preserve_field_info) - kind = diag::err_preserve_field_info_not_const; - else if (BuiltinID == BPF::BI__builtin_btf_type_id) - kind = diag::err_btf_type_id_not_const; - else if (BuiltinID == BPF::BI__builtin_preserve_type_info) - kind = diag::err_preserve_type_info_not_const; - else - kind = diag::err_preserve_enum_value_not_const; - Diag(Arg->getBeginLoc(), kind) << 2 << Arg->getSourceRange(); - return true; - } - - // The first argument - Arg = TheCall->getArg(0); - bool InvalidArg = false; - bool ReturnUnsignedInt = true; - if (BuiltinID == BPF::BI__builtin_preserve_field_info) { - if (!isValidBPFPreserveFieldInfoArg(Arg)) { - InvalidArg = true; - kind = diag::err_preserve_field_info_not_field; - } - } else if (BuiltinID == BPF::BI__builtin_preserve_type_info) { - if (!isValidBPFPreserveTypeInfoArg(Arg)) { - InvalidArg = true; - kind = diag::err_preserve_type_info_invalid; - } - } else if (BuiltinID == BPF::BI__builtin_preserve_enum_value) { - if (!isValidBPFPreserveEnumValueArg(Arg)) { - InvalidArg = true; - kind = diag::err_preserve_enum_value_invalid; - } - ReturnUnsignedInt = false; - } else if (BuiltinID == BPF::BI__builtin_btf_type_id) { - ReturnUnsignedInt = false; - } - - if (InvalidArg) { - Diag(Arg->getBeginLoc(), kind) << 1 << Arg->getSourceRange(); - return true; - } - - if (ReturnUnsignedInt) - TheCall->setType(Context.UnsignedIntTy); - else - TheCall->setType(Context.UnsignedLongTy); - return false; -} - -bool Sema::CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { - struct ArgInfo { - uint8_t OpNum; - bool IsSigned; - uint8_t BitWidth; - uint8_t Align; - }; - struct BuiltinInfo { - unsigned BuiltinID; - ArgInfo Infos[2]; - }; - - static BuiltinInfo Infos[] = { - { Hexagon::BI__builtin_circ_ldd, {{ 3, true, 4, 3 }} }, - { Hexagon::BI__builtin_circ_ldw, {{ 3, true, 4, 2 }} }, - { Hexagon::BI__builtin_circ_ldh, {{ 3, true, 4, 1 }} }, - { Hexagon::BI__builtin_circ_lduh, {{ 3, true, 4, 1 }} }, - { Hexagon::BI__builtin_circ_ldb, {{ 3, true, 4, 0 }} }, - { Hexagon::BI__builtin_circ_ldub, {{ 3, true, 4, 0 }} }, - { Hexagon::BI__builtin_circ_std, {{ 3, true, 4, 3 }} }, - { Hexagon::BI__builtin_circ_stw, {{ 3, true, 4, 2 }} }, - { Hexagon::BI__builtin_circ_sth, {{ 3, true, 4, 1 }} }, - { Hexagon::BI__builtin_circ_sthhi, {{ 3, true, 4, 1 }} }, - { Hexagon::BI__builtin_circ_stb, {{ 3, true, 4, 0 }} }, - - { Hexagon::BI__builtin_HEXAGON_L2_loadrub_pci, {{ 1, true, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_L2_loadrb_pci, {{ 1, true, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_L2_loadruh_pci, {{ 1, true, 4, 1 }} }, - { Hexagon::BI__builtin_HEXAGON_L2_loadrh_pci, {{ 1, true, 4, 1 }} }, - { Hexagon::BI__builtin_HEXAGON_L2_loadri_pci, {{ 1, true, 4, 2 }} }, - { Hexagon::BI__builtin_HEXAGON_L2_loadrd_pci, {{ 1, true, 4, 3 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_storerb_pci, {{ 1, true, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_storerh_pci, {{ 1, true, 4, 1 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_storerf_pci, {{ 1, true, 4, 1 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_storeri_pci, {{ 1, true, 4, 2 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_storerd_pci, {{ 1, true, 4, 3 }} }, - - { Hexagon::BI__builtin_HEXAGON_A2_combineii, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A2_tfrih, {{ 1, false, 16, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A2_tfril, {{ 1, false, 16, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A2_tfrpi, {{ 0, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_bitspliti, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_cmpbeqi, {{ 1, false, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_cmpbgti, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_cround_ri, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_round_ri, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_round_ri_sat, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpbeqi, {{ 1, false, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgti, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgtui, {{ 1, false, 7, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpheqi, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmphgti, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmphgtui, {{ 1, false, 7, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpweqi, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgti, {{ 1, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgtui, {{ 1, false, 7, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_C2_bitsclri, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_C2_muxii, {{ 2, true, 8, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_C4_nbitsclri, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_dfclass, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_dfimm_n, {{ 0, false, 10, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_dfimm_p, {{ 0, false, 10, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_sfclass, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_sfimm_n, {{ 0, false, 10, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_F2_sfimm_p, {{ 0, false, 10, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addi, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addr_u2, {{ 1, false, 6, 2 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_addasl_rrri, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_acc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_and, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_nac, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_or, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_xacc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_acc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_and, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_nac, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_or, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_sat, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_xacc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vh, {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vw, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_acc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_and, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_nac, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_or, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, - {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_acc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_and, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_nac, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_or, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, - {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_svw_trun, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vh, {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vw, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_clrbit_i, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_extractu, {{ 1, false, 5, 0 }, - { 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_extractup, {{ 1, false, 6, 0 }, - { 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_insert, {{ 2, false, 5, 0 }, - { 3, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_insertp, {{ 2, false, 6, 0 }, - { 3, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_acc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_and, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_nac, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_or, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_xacc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_acc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_and, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_nac, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_or, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_xacc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vh, {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vw, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_setbit_i, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_tableidxb_goodsyntax, - {{ 2, false, 4, 0 }, - { 3, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_tableidxd_goodsyntax, - {{ 2, false, 4, 0 }, - { 3, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_tableidxh_goodsyntax, - {{ 2, false, 4, 0 }, - { 3, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_tableidxw_goodsyntax, - {{ 2, false, 4, 0 }, - { 3, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_togglebit_i, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_tstbit_i, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_valignib, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S2_vspliceib, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_addi_asl_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_addi_lsr_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_andi_asl_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_andi_lsr_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_clbaddi, {{ 1, true , 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_clbpaddi, {{ 1, true, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_extract, {{ 1, false, 5, 0 }, - { 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_extractp, {{ 1, false, 6, 0 }, - { 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_lsli, {{ 0, true, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_ntstbit_i, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_ori_asl_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_ori_lsr_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_subi_asl_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_subi_lsr_ri, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate_acc, {{ 3, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate, {{ 2, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, - {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S5_asrhub_sat, {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, - {{ 1, false, 4, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, {{ 1, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, {{ 2, false, 6, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, {{ 1, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, {{ 2, false, 5, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignbi, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, {{ 3, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, - {{ 3, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, {{ 3, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, - {{ 3, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, {{ 2, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, {{ 3, false, 1, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, - {{ 3, false, 1, 0 }} }, - - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10, {{ 2, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_128B, - {{ 2, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_vxx, - {{ 3, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_vxx_128B, - {{ 3, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10, {{ 2, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_128B, - {{ 2, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_vxx, - {{ 3, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_vxx_128B, - {{ 3, false, 2, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi_128B, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci, {{ 3, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci_128B, - {{ 3, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi_128B, {{ 2, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci, {{ 3, false, 3, 0 }} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci_128B, - {{ 3, false, 3, 0 }} }, - }; - - // Use a dynamically initialized static to sort the table exactly once on - // first run. - static const bool SortOnce = - (llvm::sort(Infos, - [](const BuiltinInfo &LHS, const BuiltinInfo &RHS) { - return LHS.BuiltinID < RHS.BuiltinID; - }), - true); - (void)SortOnce; - - const BuiltinInfo *F = llvm::partition_point( - Infos, [=](const BuiltinInfo &BI) { return BI.BuiltinID < BuiltinID; }); - if (F == std::end(Infos) || F->BuiltinID != BuiltinID) - return false; - - bool Error = false; - - for (const ArgInfo &A : F->Infos) { - // Ignore empty ArgInfo elements. - if (A.BitWidth == 0) - continue; - - int32_t Min = A.IsSigned ? -(1 << (A.BitWidth - 1)) : 0; - int32_t Max = (1 << (A.IsSigned ? A.BitWidth - 1 : A.BitWidth)) - 1; - if (!A.Align) { - Error |= BuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); - } else { - unsigned M = 1 << A.Align; - Min *= M; - Max *= M; - Error |= BuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); - Error |= BuiltinConstantArgMultiple(TheCall, A.OpNum, M); - } - } - return Error; -} - -bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, - CallExpr *TheCall) { - return CheckHexagonBuiltinArgument(BuiltinID, TheCall); -} - -bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall) { - switch (BuiltinID) { - default: - break; - // Basic intrinsics. - case LoongArch::BI__builtin_loongarch_cacop_d: - case LoongArch::BI__builtin_loongarch_cacop_w: { - BuiltinConstantArgRange(TheCall, 0, 0, llvm::maxUIntN(5)); - BuiltinConstantArgRange(TheCall, 2, llvm::minIntN(12), llvm::maxIntN(12)); - break; - } - case LoongArch::BI__builtin_loongarch_break: - case LoongArch::BI__builtin_loongarch_dbar: - case LoongArch::BI__builtin_loongarch_ibar: - case LoongArch::BI__builtin_loongarch_syscall: - // Check if immediate is in [0, 32767]. - return BuiltinConstantArgRange(TheCall, 0, 0, 32767); - case LoongArch::BI__builtin_loongarch_csrrd_w: - case LoongArch::BI__builtin_loongarch_csrrd_d: - return BuiltinConstantArgRange(TheCall, 0, 0, 16383); - case LoongArch::BI__builtin_loongarch_csrwr_w: - case LoongArch::BI__builtin_loongarch_csrwr_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 16383); - case LoongArch::BI__builtin_loongarch_csrxchg_w: - case LoongArch::BI__builtin_loongarch_csrxchg_d: - return BuiltinConstantArgRange(TheCall, 2, 0, 16383); - case LoongArch::BI__builtin_loongarch_lddir_d: - case LoongArch::BI__builtin_loongarch_ldpte_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 31); - case LoongArch::BI__builtin_loongarch_movfcsr2gr: - case LoongArch::BI__builtin_loongarch_movgr2fcsr: - return BuiltinConstantArgRange(TheCall, 0, 0, llvm::maxUIntN(2)); - - // LSX intrinsics. - case LoongArch::BI__builtin_lsx_vbitclri_b: - case LoongArch::BI__builtin_lsx_vbitrevi_b: - case LoongArch::BI__builtin_lsx_vbitseti_b: - case LoongArch::BI__builtin_lsx_vsat_b: - case LoongArch::BI__builtin_lsx_vsat_bu: - case LoongArch::BI__builtin_lsx_vslli_b: - case LoongArch::BI__builtin_lsx_vsrai_b: - case LoongArch::BI__builtin_lsx_vsrari_b: - case LoongArch::BI__builtin_lsx_vsrli_b: - case LoongArch::BI__builtin_lsx_vsllwil_h_b: - case LoongArch::BI__builtin_lsx_vsllwil_hu_bu: - case LoongArch::BI__builtin_lsx_vrotri_b: - case LoongArch::BI__builtin_lsx_vsrlri_b: - return BuiltinConstantArgRange(TheCall, 1, 0, 7); - case LoongArch::BI__builtin_lsx_vbitclri_h: - case LoongArch::BI__builtin_lsx_vbitrevi_h: - case LoongArch::BI__builtin_lsx_vbitseti_h: - case LoongArch::BI__builtin_lsx_vsat_h: - case LoongArch::BI__builtin_lsx_vsat_hu: - case LoongArch::BI__builtin_lsx_vslli_h: - case LoongArch::BI__builtin_lsx_vsrai_h: - case LoongArch::BI__builtin_lsx_vsrari_h: - case LoongArch::BI__builtin_lsx_vsrli_h: - case LoongArch::BI__builtin_lsx_vsllwil_w_h: - case LoongArch::BI__builtin_lsx_vsllwil_wu_hu: - case LoongArch::BI__builtin_lsx_vrotri_h: - case LoongArch::BI__builtin_lsx_vsrlri_h: - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - case LoongArch::BI__builtin_lsx_vssrarni_b_h: - case LoongArch::BI__builtin_lsx_vssrarni_bu_h: - case LoongArch::BI__builtin_lsx_vssrani_b_h: - case LoongArch::BI__builtin_lsx_vssrani_bu_h: - case LoongArch::BI__builtin_lsx_vsrarni_b_h: - case LoongArch::BI__builtin_lsx_vsrlni_b_h: - case LoongArch::BI__builtin_lsx_vsrlrni_b_h: - case LoongArch::BI__builtin_lsx_vssrlni_b_h: - case LoongArch::BI__builtin_lsx_vssrlni_bu_h: - case LoongArch::BI__builtin_lsx_vssrlrni_b_h: - case LoongArch::BI__builtin_lsx_vssrlrni_bu_h: - case LoongArch::BI__builtin_lsx_vsrani_b_h: - return BuiltinConstantArgRange(TheCall, 2, 0, 15); - case LoongArch::BI__builtin_lsx_vslei_bu: - case LoongArch::BI__builtin_lsx_vslei_hu: - case LoongArch::BI__builtin_lsx_vslei_wu: - case LoongArch::BI__builtin_lsx_vslei_du: - case LoongArch::BI__builtin_lsx_vslti_bu: - case LoongArch::BI__builtin_lsx_vslti_hu: - case LoongArch::BI__builtin_lsx_vslti_wu: - case LoongArch::BI__builtin_lsx_vslti_du: - case LoongArch::BI__builtin_lsx_vmaxi_bu: - case LoongArch::BI__builtin_lsx_vmaxi_hu: - case LoongArch::BI__builtin_lsx_vmaxi_wu: - case LoongArch::BI__builtin_lsx_vmaxi_du: - case LoongArch::BI__builtin_lsx_vmini_bu: - case LoongArch::BI__builtin_lsx_vmini_hu: - case LoongArch::BI__builtin_lsx_vmini_wu: - case LoongArch::BI__builtin_lsx_vmini_du: - case LoongArch::BI__builtin_lsx_vaddi_bu: - case LoongArch::BI__builtin_lsx_vaddi_hu: - case LoongArch::BI__builtin_lsx_vaddi_wu: - case LoongArch::BI__builtin_lsx_vaddi_du: - case LoongArch::BI__builtin_lsx_vbitclri_w: - case LoongArch::BI__builtin_lsx_vbitrevi_w: - case LoongArch::BI__builtin_lsx_vbitseti_w: - case LoongArch::BI__builtin_lsx_vsat_w: - case LoongArch::BI__builtin_lsx_vsat_wu: - case LoongArch::BI__builtin_lsx_vslli_w: - case LoongArch::BI__builtin_lsx_vsrai_w: - case LoongArch::BI__builtin_lsx_vsrari_w: - case LoongArch::BI__builtin_lsx_vsrli_w: - case LoongArch::BI__builtin_lsx_vsllwil_d_w: - case LoongArch::BI__builtin_lsx_vsllwil_du_wu: - case LoongArch::BI__builtin_lsx_vsrlri_w: - case LoongArch::BI__builtin_lsx_vrotri_w: - case LoongArch::BI__builtin_lsx_vsubi_bu: - case LoongArch::BI__builtin_lsx_vsubi_hu: - case LoongArch::BI__builtin_lsx_vbsrl_v: - case LoongArch::BI__builtin_lsx_vbsll_v: - case LoongArch::BI__builtin_lsx_vsubi_wu: - case LoongArch::BI__builtin_lsx_vsubi_du: - return BuiltinConstantArgRange(TheCall, 1, 0, 31); - case LoongArch::BI__builtin_lsx_vssrarni_h_w: - case LoongArch::BI__builtin_lsx_vssrarni_hu_w: - case LoongArch::BI__builtin_lsx_vssrani_h_w: - case LoongArch::BI__builtin_lsx_vssrani_hu_w: - case LoongArch::BI__builtin_lsx_vsrarni_h_w: - case LoongArch::BI__builtin_lsx_vsrani_h_w: - case LoongArch::BI__builtin_lsx_vfrstpi_b: - case LoongArch::BI__builtin_lsx_vfrstpi_h: - case LoongArch::BI__builtin_lsx_vsrlni_h_w: - case LoongArch::BI__builtin_lsx_vsrlrni_h_w: - case LoongArch::BI__builtin_lsx_vssrlni_h_w: - case LoongArch::BI__builtin_lsx_vssrlni_hu_w: - case LoongArch::BI__builtin_lsx_vssrlrni_h_w: - case LoongArch::BI__builtin_lsx_vssrlrni_hu_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 31); - case LoongArch::BI__builtin_lsx_vbitclri_d: - case LoongArch::BI__builtin_lsx_vbitrevi_d: - case LoongArch::BI__builtin_lsx_vbitseti_d: - case LoongArch::BI__builtin_lsx_vsat_d: - case LoongArch::BI__builtin_lsx_vsat_du: - case LoongArch::BI__builtin_lsx_vslli_d: - case LoongArch::BI__builtin_lsx_vsrai_d: - case LoongArch::BI__builtin_lsx_vsrli_d: - case LoongArch::BI__builtin_lsx_vsrari_d: - case LoongArch::BI__builtin_lsx_vrotri_d: - case LoongArch::BI__builtin_lsx_vsrlri_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 63); - case LoongArch::BI__builtin_lsx_vssrarni_w_d: - case LoongArch::BI__builtin_lsx_vssrarni_wu_d: - case LoongArch::BI__builtin_lsx_vssrani_w_d: - case LoongArch::BI__builtin_lsx_vssrani_wu_d: - case LoongArch::BI__builtin_lsx_vsrarni_w_d: - case LoongArch::BI__builtin_lsx_vsrlni_w_d: - case LoongArch::BI__builtin_lsx_vsrlrni_w_d: - case LoongArch::BI__builtin_lsx_vssrlni_w_d: - case LoongArch::BI__builtin_lsx_vssrlni_wu_d: - case LoongArch::BI__builtin_lsx_vssrlrni_w_d: - case LoongArch::BI__builtin_lsx_vssrlrni_wu_d: - case LoongArch::BI__builtin_lsx_vsrani_w_d: - return BuiltinConstantArgRange(TheCall, 2, 0, 63); - case LoongArch::BI__builtin_lsx_vssrarni_d_q: - case LoongArch::BI__builtin_lsx_vssrarni_du_q: - case LoongArch::BI__builtin_lsx_vssrani_d_q: - case LoongArch::BI__builtin_lsx_vssrani_du_q: - case LoongArch::BI__builtin_lsx_vsrarni_d_q: - case LoongArch::BI__builtin_lsx_vssrlni_d_q: - case LoongArch::BI__builtin_lsx_vssrlni_du_q: - case LoongArch::BI__builtin_lsx_vssrlrni_d_q: - case LoongArch::BI__builtin_lsx_vssrlrni_du_q: - case LoongArch::BI__builtin_lsx_vsrani_d_q: - case LoongArch::BI__builtin_lsx_vsrlrni_d_q: - case LoongArch::BI__builtin_lsx_vsrlni_d_q: - return BuiltinConstantArgRange(TheCall, 2, 0, 127); - case LoongArch::BI__builtin_lsx_vseqi_b: - case LoongArch::BI__builtin_lsx_vseqi_h: - case LoongArch::BI__builtin_lsx_vseqi_w: - case LoongArch::BI__builtin_lsx_vseqi_d: - case LoongArch::BI__builtin_lsx_vslti_b: - case LoongArch::BI__builtin_lsx_vslti_h: - case LoongArch::BI__builtin_lsx_vslti_w: - case LoongArch::BI__builtin_lsx_vslti_d: - case LoongArch::BI__builtin_lsx_vslei_b: - case LoongArch::BI__builtin_lsx_vslei_h: - case LoongArch::BI__builtin_lsx_vslei_w: - case LoongArch::BI__builtin_lsx_vslei_d: - case LoongArch::BI__builtin_lsx_vmaxi_b: - case LoongArch::BI__builtin_lsx_vmaxi_h: - case LoongArch::BI__builtin_lsx_vmaxi_w: - case LoongArch::BI__builtin_lsx_vmaxi_d: - case LoongArch::BI__builtin_lsx_vmini_b: - case LoongArch::BI__builtin_lsx_vmini_h: - case LoongArch::BI__builtin_lsx_vmini_w: - case LoongArch::BI__builtin_lsx_vmini_d: - return BuiltinConstantArgRange(TheCall, 1, -16, 15); - case LoongArch::BI__builtin_lsx_vandi_b: - case LoongArch::BI__builtin_lsx_vnori_b: - case LoongArch::BI__builtin_lsx_vori_b: - case LoongArch::BI__builtin_lsx_vshuf4i_b: - case LoongArch::BI__builtin_lsx_vshuf4i_h: - case LoongArch::BI__builtin_lsx_vshuf4i_w: - case LoongArch::BI__builtin_lsx_vxori_b: - return BuiltinConstantArgRange(TheCall, 1, 0, 255); - case LoongArch::BI__builtin_lsx_vbitseli_b: - case LoongArch::BI__builtin_lsx_vshuf4i_d: - case LoongArch::BI__builtin_lsx_vextrins_b: - case LoongArch::BI__builtin_lsx_vextrins_h: - case LoongArch::BI__builtin_lsx_vextrins_w: - case LoongArch::BI__builtin_lsx_vextrins_d: - case LoongArch::BI__builtin_lsx_vpermi_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 255); - case LoongArch::BI__builtin_lsx_vpickve2gr_b: - case LoongArch::BI__builtin_lsx_vpickve2gr_bu: - case LoongArch::BI__builtin_lsx_vreplvei_b: - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - case LoongArch::BI__builtin_lsx_vinsgr2vr_b: - return BuiltinConstantArgRange(TheCall, 2, 0, 15); - case LoongArch::BI__builtin_lsx_vpickve2gr_h: - case LoongArch::BI__builtin_lsx_vpickve2gr_hu: - case LoongArch::BI__builtin_lsx_vreplvei_h: - return BuiltinConstantArgRange(TheCall, 1, 0, 7); - case LoongArch::BI__builtin_lsx_vinsgr2vr_h: - return BuiltinConstantArgRange(TheCall, 2, 0, 7); - case LoongArch::BI__builtin_lsx_vpickve2gr_w: - case LoongArch::BI__builtin_lsx_vpickve2gr_wu: - case LoongArch::BI__builtin_lsx_vreplvei_w: - return BuiltinConstantArgRange(TheCall, 1, 0, 3); - case LoongArch::BI__builtin_lsx_vinsgr2vr_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 3); - case LoongArch::BI__builtin_lsx_vpickve2gr_d: - case LoongArch::BI__builtin_lsx_vpickve2gr_du: - case LoongArch::BI__builtin_lsx_vreplvei_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 1); - case LoongArch::BI__builtin_lsx_vinsgr2vr_d: - return BuiltinConstantArgRange(TheCall, 2, 0, 1); - case LoongArch::BI__builtin_lsx_vstelm_b: - return BuiltinConstantArgRange(TheCall, 2, -128, 127) || - BuiltinConstantArgRange(TheCall, 3, 0, 15); - case LoongArch::BI__builtin_lsx_vstelm_h: - return BuiltinConstantArgRange(TheCall, 2, -256, 254) || - BuiltinConstantArgRange(TheCall, 3, 0, 7); - case LoongArch::BI__builtin_lsx_vstelm_w: - return BuiltinConstantArgRange(TheCall, 2, -512, 508) || - BuiltinConstantArgRange(TheCall, 3, 0, 3); - case LoongArch::BI__builtin_lsx_vstelm_d: - return BuiltinConstantArgRange(TheCall, 2, -1024, 1016) || - BuiltinConstantArgRange(TheCall, 3, 0, 1); - case LoongArch::BI__builtin_lsx_vldrepl_b: - case LoongArch::BI__builtin_lsx_vld: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2047); - case LoongArch::BI__builtin_lsx_vldrepl_h: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2046); - case LoongArch::BI__builtin_lsx_vldrepl_w: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2044); - case LoongArch::BI__builtin_lsx_vldrepl_d: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2040); - case LoongArch::BI__builtin_lsx_vst: - return BuiltinConstantArgRange(TheCall, 2, -2048, 2047); - case LoongArch::BI__builtin_lsx_vldi: - return BuiltinConstantArgRange(TheCall, 0, -4096, 4095); - case LoongArch::BI__builtin_lsx_vrepli_b: - case LoongArch::BI__builtin_lsx_vrepli_h: - case LoongArch::BI__builtin_lsx_vrepli_w: - case LoongArch::BI__builtin_lsx_vrepli_d: - return BuiltinConstantArgRange(TheCall, 0, -512, 511); - - // LASX intrinsics. - case LoongArch::BI__builtin_lasx_xvbitclri_b: - case LoongArch::BI__builtin_lasx_xvbitrevi_b: - case LoongArch::BI__builtin_lasx_xvbitseti_b: - case LoongArch::BI__builtin_lasx_xvsat_b: - case LoongArch::BI__builtin_lasx_xvsat_bu: - case LoongArch::BI__builtin_lasx_xvslli_b: - case LoongArch::BI__builtin_lasx_xvsrai_b: - case LoongArch::BI__builtin_lasx_xvsrari_b: - case LoongArch::BI__builtin_lasx_xvsrli_b: - case LoongArch::BI__builtin_lasx_xvsllwil_h_b: - case LoongArch::BI__builtin_lasx_xvsllwil_hu_bu: - case LoongArch::BI__builtin_lasx_xvrotri_b: - case LoongArch::BI__builtin_lasx_xvsrlri_b: - return BuiltinConstantArgRange(TheCall, 1, 0, 7); - case LoongArch::BI__builtin_lasx_xvbitclri_h: - case LoongArch::BI__builtin_lasx_xvbitrevi_h: - case LoongArch::BI__builtin_lasx_xvbitseti_h: - case LoongArch::BI__builtin_lasx_xvsat_h: - case LoongArch::BI__builtin_lasx_xvsat_hu: - case LoongArch::BI__builtin_lasx_xvslli_h: - case LoongArch::BI__builtin_lasx_xvsrai_h: - case LoongArch::BI__builtin_lasx_xvsrari_h: - case LoongArch::BI__builtin_lasx_xvsrli_h: - case LoongArch::BI__builtin_lasx_xvsllwil_w_h: - case LoongArch::BI__builtin_lasx_xvsllwil_wu_hu: - case LoongArch::BI__builtin_lasx_xvrotri_h: - case LoongArch::BI__builtin_lasx_xvsrlri_h: - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - case LoongArch::BI__builtin_lasx_xvssrarni_b_h: - case LoongArch::BI__builtin_lasx_xvssrarni_bu_h: - case LoongArch::BI__builtin_lasx_xvssrani_b_h: - case LoongArch::BI__builtin_lasx_xvssrani_bu_h: - case LoongArch::BI__builtin_lasx_xvsrarni_b_h: - case LoongArch::BI__builtin_lasx_xvsrlni_b_h: - case LoongArch::BI__builtin_lasx_xvsrlrni_b_h: - case LoongArch::BI__builtin_lasx_xvssrlni_b_h: - case LoongArch::BI__builtin_lasx_xvssrlni_bu_h: - case LoongArch::BI__builtin_lasx_xvssrlrni_b_h: - case LoongArch::BI__builtin_lasx_xvssrlrni_bu_h: - case LoongArch::BI__builtin_lasx_xvsrani_b_h: - return BuiltinConstantArgRange(TheCall, 2, 0, 15); - case LoongArch::BI__builtin_lasx_xvslei_bu: - case LoongArch::BI__builtin_lasx_xvslei_hu: - case LoongArch::BI__builtin_lasx_xvslei_wu: - case LoongArch::BI__builtin_lasx_xvslei_du: - case LoongArch::BI__builtin_lasx_xvslti_bu: - case LoongArch::BI__builtin_lasx_xvslti_hu: - case LoongArch::BI__builtin_lasx_xvslti_wu: - case LoongArch::BI__builtin_lasx_xvslti_du: - case LoongArch::BI__builtin_lasx_xvmaxi_bu: - case LoongArch::BI__builtin_lasx_xvmaxi_hu: - case LoongArch::BI__builtin_lasx_xvmaxi_wu: - case LoongArch::BI__builtin_lasx_xvmaxi_du: - case LoongArch::BI__builtin_lasx_xvmini_bu: - case LoongArch::BI__builtin_lasx_xvmini_hu: - case LoongArch::BI__builtin_lasx_xvmini_wu: - case LoongArch::BI__builtin_lasx_xvmini_du: - case LoongArch::BI__builtin_lasx_xvaddi_bu: - case LoongArch::BI__builtin_lasx_xvaddi_hu: - case LoongArch::BI__builtin_lasx_xvaddi_wu: - case LoongArch::BI__builtin_lasx_xvaddi_du: - case LoongArch::BI__builtin_lasx_xvbitclri_w: - case LoongArch::BI__builtin_lasx_xvbitrevi_w: - case LoongArch::BI__builtin_lasx_xvbitseti_w: - case LoongArch::BI__builtin_lasx_xvsat_w: - case LoongArch::BI__builtin_lasx_xvsat_wu: - case LoongArch::BI__builtin_lasx_xvslli_w: - case LoongArch::BI__builtin_lasx_xvsrai_w: - case LoongArch::BI__builtin_lasx_xvsrari_w: - case LoongArch::BI__builtin_lasx_xvsrli_w: - case LoongArch::BI__builtin_lasx_xvsllwil_d_w: - case LoongArch::BI__builtin_lasx_xvsllwil_du_wu: - case LoongArch::BI__builtin_lasx_xvsrlri_w: - case LoongArch::BI__builtin_lasx_xvrotri_w: - case LoongArch::BI__builtin_lasx_xvsubi_bu: - case LoongArch::BI__builtin_lasx_xvsubi_hu: - case LoongArch::BI__builtin_lasx_xvsubi_wu: - case LoongArch::BI__builtin_lasx_xvsubi_du: - case LoongArch::BI__builtin_lasx_xvbsrl_v: - case LoongArch::BI__builtin_lasx_xvbsll_v: - return BuiltinConstantArgRange(TheCall, 1, 0, 31); - case LoongArch::BI__builtin_lasx_xvssrarni_h_w: - case LoongArch::BI__builtin_lasx_xvssrarni_hu_w: - case LoongArch::BI__builtin_lasx_xvssrani_h_w: - case LoongArch::BI__builtin_lasx_xvssrani_hu_w: - case LoongArch::BI__builtin_lasx_xvsrarni_h_w: - case LoongArch::BI__builtin_lasx_xvsrani_h_w: - case LoongArch::BI__builtin_lasx_xvfrstpi_b: - case LoongArch::BI__builtin_lasx_xvfrstpi_h: - case LoongArch::BI__builtin_lasx_xvsrlni_h_w: - case LoongArch::BI__builtin_lasx_xvsrlrni_h_w: - case LoongArch::BI__builtin_lasx_xvssrlni_h_w: - case LoongArch::BI__builtin_lasx_xvssrlni_hu_w: - case LoongArch::BI__builtin_lasx_xvssrlrni_h_w: - case LoongArch::BI__builtin_lasx_xvssrlrni_hu_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 31); - case LoongArch::BI__builtin_lasx_xvbitclri_d: - case LoongArch::BI__builtin_lasx_xvbitrevi_d: - case LoongArch::BI__builtin_lasx_xvbitseti_d: - case LoongArch::BI__builtin_lasx_xvsat_d: - case LoongArch::BI__builtin_lasx_xvsat_du: - case LoongArch::BI__builtin_lasx_xvslli_d: - case LoongArch::BI__builtin_lasx_xvsrai_d: - case LoongArch::BI__builtin_lasx_xvsrli_d: - case LoongArch::BI__builtin_lasx_xvsrari_d: - case LoongArch::BI__builtin_lasx_xvrotri_d: - case LoongArch::BI__builtin_lasx_xvsrlri_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 63); - case LoongArch::BI__builtin_lasx_xvssrarni_w_d: - case LoongArch::BI__builtin_lasx_xvssrarni_wu_d: - case LoongArch::BI__builtin_lasx_xvssrani_w_d: - case LoongArch::BI__builtin_lasx_xvssrani_wu_d: - case LoongArch::BI__builtin_lasx_xvsrarni_w_d: - case LoongArch::BI__builtin_lasx_xvsrlni_w_d: - case LoongArch::BI__builtin_lasx_xvsrlrni_w_d: - case LoongArch::BI__builtin_lasx_xvssrlni_w_d: - case LoongArch::BI__builtin_lasx_xvssrlni_wu_d: - case LoongArch::BI__builtin_lasx_xvssrlrni_w_d: - case LoongArch::BI__builtin_lasx_xvssrlrni_wu_d: - case LoongArch::BI__builtin_lasx_xvsrani_w_d: - return BuiltinConstantArgRange(TheCall, 2, 0, 63); - case LoongArch::BI__builtin_lasx_xvssrarni_d_q: - case LoongArch::BI__builtin_lasx_xvssrarni_du_q: - case LoongArch::BI__builtin_lasx_xvssrani_d_q: - case LoongArch::BI__builtin_lasx_xvssrani_du_q: - case LoongArch::BI__builtin_lasx_xvsrarni_d_q: - case LoongArch::BI__builtin_lasx_xvssrlni_d_q: - case LoongArch::BI__builtin_lasx_xvssrlni_du_q: - case LoongArch::BI__builtin_lasx_xvssrlrni_d_q: - case LoongArch::BI__builtin_lasx_xvssrlrni_du_q: - case LoongArch::BI__builtin_lasx_xvsrani_d_q: - case LoongArch::BI__builtin_lasx_xvsrlni_d_q: - case LoongArch::BI__builtin_lasx_xvsrlrni_d_q: - return BuiltinConstantArgRange(TheCall, 2, 0, 127); - case LoongArch::BI__builtin_lasx_xvseqi_b: - case LoongArch::BI__builtin_lasx_xvseqi_h: - case LoongArch::BI__builtin_lasx_xvseqi_w: - case LoongArch::BI__builtin_lasx_xvseqi_d: - case LoongArch::BI__builtin_lasx_xvslti_b: - case LoongArch::BI__builtin_lasx_xvslti_h: - case LoongArch::BI__builtin_lasx_xvslti_w: - case LoongArch::BI__builtin_lasx_xvslti_d: - case LoongArch::BI__builtin_lasx_xvslei_b: - case LoongArch::BI__builtin_lasx_xvslei_h: - case LoongArch::BI__builtin_lasx_xvslei_w: - case LoongArch::BI__builtin_lasx_xvslei_d: - case LoongArch::BI__builtin_lasx_xvmaxi_b: - case LoongArch::BI__builtin_lasx_xvmaxi_h: - case LoongArch::BI__builtin_lasx_xvmaxi_w: - case LoongArch::BI__builtin_lasx_xvmaxi_d: - case LoongArch::BI__builtin_lasx_xvmini_b: - case LoongArch::BI__builtin_lasx_xvmini_h: - case LoongArch::BI__builtin_lasx_xvmini_w: - case LoongArch::BI__builtin_lasx_xvmini_d: - return BuiltinConstantArgRange(TheCall, 1, -16, 15); - case LoongArch::BI__builtin_lasx_xvandi_b: - case LoongArch::BI__builtin_lasx_xvnori_b: - case LoongArch::BI__builtin_lasx_xvori_b: - case LoongArch::BI__builtin_lasx_xvshuf4i_b: - case LoongArch::BI__builtin_lasx_xvshuf4i_h: - case LoongArch::BI__builtin_lasx_xvshuf4i_w: - case LoongArch::BI__builtin_lasx_xvxori_b: - case LoongArch::BI__builtin_lasx_xvpermi_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 255); - case LoongArch::BI__builtin_lasx_xvbitseli_b: - case LoongArch::BI__builtin_lasx_xvshuf4i_d: - case LoongArch::BI__builtin_lasx_xvextrins_b: - case LoongArch::BI__builtin_lasx_xvextrins_h: - case LoongArch::BI__builtin_lasx_xvextrins_w: - case LoongArch::BI__builtin_lasx_xvextrins_d: - case LoongArch::BI__builtin_lasx_xvpermi_q: - case LoongArch::BI__builtin_lasx_xvpermi_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 255); - case LoongArch::BI__builtin_lasx_xvrepl128vei_b: - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - case LoongArch::BI__builtin_lasx_xvrepl128vei_h: - case LoongArch::BI__builtin_lasx_xvpickve2gr_w: - case LoongArch::BI__builtin_lasx_xvpickve2gr_wu: - case LoongArch::BI__builtin_lasx_xvpickve_w_f: - case LoongArch::BI__builtin_lasx_xvpickve_w: - return BuiltinConstantArgRange(TheCall, 1, 0, 7); - case LoongArch::BI__builtin_lasx_xvinsgr2vr_w: - case LoongArch::BI__builtin_lasx_xvinsve0_w: - return BuiltinConstantArgRange(TheCall, 2, 0, 7); - case LoongArch::BI__builtin_lasx_xvrepl128vei_w: - case LoongArch::BI__builtin_lasx_xvpickve2gr_d: - case LoongArch::BI__builtin_lasx_xvpickve2gr_du: - case LoongArch::BI__builtin_lasx_xvpickve_d_f: - case LoongArch::BI__builtin_lasx_xvpickve_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 3); - case LoongArch::BI__builtin_lasx_xvinsve0_d: - case LoongArch::BI__builtin_lasx_xvinsgr2vr_d: - return BuiltinConstantArgRange(TheCall, 2, 0, 3); - case LoongArch::BI__builtin_lasx_xvstelm_b: - return BuiltinConstantArgRange(TheCall, 2, -128, 127) || - BuiltinConstantArgRange(TheCall, 3, 0, 31); - case LoongArch::BI__builtin_lasx_xvstelm_h: - return BuiltinConstantArgRange(TheCall, 2, -256, 254) || - BuiltinConstantArgRange(TheCall, 3, 0, 15); - case LoongArch::BI__builtin_lasx_xvstelm_w: - return BuiltinConstantArgRange(TheCall, 2, -512, 508) || - BuiltinConstantArgRange(TheCall, 3, 0, 7); - case LoongArch::BI__builtin_lasx_xvstelm_d: - return BuiltinConstantArgRange(TheCall, 2, -1024, 1016) || - BuiltinConstantArgRange(TheCall, 3, 0, 3); - case LoongArch::BI__builtin_lasx_xvrepl128vei_d: - return BuiltinConstantArgRange(TheCall, 1, 0, 1); - case LoongArch::BI__builtin_lasx_xvldrepl_b: - case LoongArch::BI__builtin_lasx_xvld: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2047); - case LoongArch::BI__builtin_lasx_xvldrepl_h: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2046); - case LoongArch::BI__builtin_lasx_xvldrepl_w: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2044); - case LoongArch::BI__builtin_lasx_xvldrepl_d: - return BuiltinConstantArgRange(TheCall, 1, -2048, 2040); - case LoongArch::BI__builtin_lasx_xvst: - return BuiltinConstantArgRange(TheCall, 2, -2048, 2047); - case LoongArch::BI__builtin_lasx_xvldi: - return BuiltinConstantArgRange(TheCall, 0, -4096, 4095); - case LoongArch::BI__builtin_lasx_xvrepli_b: - case LoongArch::BI__builtin_lasx_xvrepli_h: - case LoongArch::BI__builtin_lasx_xvrepli_w: - case LoongArch::BI__builtin_lasx_xvrepli_d: - return BuiltinConstantArgRange(TheCall, 0, -512, 511); - } - return false; -} - -bool Sema::CheckMipsBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, CallExpr *TheCall) { - return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) || - CheckMipsBuiltinArgument(BuiltinID, TheCall); -} - -bool Sema::CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall) { - - if (Mips::BI__builtin_mips_addu_qb <= BuiltinID && - BuiltinID <= Mips::BI__builtin_mips_lwx) { - if (!TI.hasFeature("dsp")) - return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp); - } - - if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID && - BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) { - if (!TI.hasFeature("dspr2")) - return Diag(TheCall->getBeginLoc(), - diag::err_mips_builtin_requires_dspr2); - } - - if (Mips::BI__builtin_msa_add_a_b <= BuiltinID && - BuiltinID <= Mips::BI__builtin_msa_xori_b) { - if (!TI.hasFeature("msa")) - return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa); - } - - return false; -} - -// CheckMipsBuiltinArgument - Checks the constant value passed to the -// intrinsic is correct. The switch statement is ordered by DSP, MSA. The -// ordering for DSP is unspecified. MSA is ordered by the data format used -// by the underlying instruction i.e., df/m, df/n and then by size. -// -// FIXME: The size tests here should instead be tablegen'd along with the -// definitions from include/clang/Basic/BuiltinsMips.def. -// FIXME: GCC is strict on signedness for some of these intrinsics, we should -// be too. -bool Sema::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { - unsigned i = 0, l = 0, u = 0, m = 0; - switch (BuiltinID) { - default: return false; - case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; - case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; - case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break; - case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break; - case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; - case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; - case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; - // MSA intrinsics. Instructions (which the intrinsics maps to) which use the - // df/m field. - // These intrinsics take an unsigned 3 bit immediate. - case Mips::BI__builtin_msa_bclri_b: - case Mips::BI__builtin_msa_bnegi_b: - case Mips::BI__builtin_msa_bseti_b: - case Mips::BI__builtin_msa_sat_s_b: - case Mips::BI__builtin_msa_sat_u_b: - case Mips::BI__builtin_msa_slli_b: - case Mips::BI__builtin_msa_srai_b: - case Mips::BI__builtin_msa_srari_b: - case Mips::BI__builtin_msa_srli_b: - case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; - case Mips::BI__builtin_msa_binsli_b: - case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; - // These intrinsics take an unsigned 4 bit immediate. - case Mips::BI__builtin_msa_bclri_h: - case Mips::BI__builtin_msa_bnegi_h: - case Mips::BI__builtin_msa_bseti_h: - case Mips::BI__builtin_msa_sat_s_h: - case Mips::BI__builtin_msa_sat_u_h: - case Mips::BI__builtin_msa_slli_h: - case Mips::BI__builtin_msa_srai_h: - case Mips::BI__builtin_msa_srari_h: - case Mips::BI__builtin_msa_srli_h: - case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; - case Mips::BI__builtin_msa_binsli_h: - case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; - // These intrinsics take an unsigned 5 bit immediate. - // The first block of intrinsics actually have an unsigned 5 bit field, - // not a df/n field. - case Mips::BI__builtin_msa_cfcmsa: - case Mips::BI__builtin_msa_ctcmsa: i = 0; l = 0; u = 31; break; - case Mips::BI__builtin_msa_clei_u_b: - case Mips::BI__builtin_msa_clei_u_h: - case Mips::BI__builtin_msa_clei_u_w: - case Mips::BI__builtin_msa_clei_u_d: - case Mips::BI__builtin_msa_clti_u_b: - case Mips::BI__builtin_msa_clti_u_h: - case Mips::BI__builtin_msa_clti_u_w: - case Mips::BI__builtin_msa_clti_u_d: - case Mips::BI__builtin_msa_maxi_u_b: - case Mips::BI__builtin_msa_maxi_u_h: - case Mips::BI__builtin_msa_maxi_u_w: - case Mips::BI__builtin_msa_maxi_u_d: - case Mips::BI__builtin_msa_mini_u_b: - case Mips::BI__builtin_msa_mini_u_h: - case Mips::BI__builtin_msa_mini_u_w: - case Mips::BI__builtin_msa_mini_u_d: - case Mips::BI__builtin_msa_addvi_b: - case Mips::BI__builtin_msa_addvi_h: - case Mips::BI__builtin_msa_addvi_w: - case Mips::BI__builtin_msa_addvi_d: - case Mips::BI__builtin_msa_bclri_w: - case Mips::BI__builtin_msa_bnegi_w: - case Mips::BI__builtin_msa_bseti_w: - case Mips::BI__builtin_msa_sat_s_w: - case Mips::BI__builtin_msa_sat_u_w: - case Mips::BI__builtin_msa_slli_w: - case Mips::BI__builtin_msa_srai_w: - case Mips::BI__builtin_msa_srari_w: - case Mips::BI__builtin_msa_srli_w: - case Mips::BI__builtin_msa_srlri_w: - case Mips::BI__builtin_msa_subvi_b: - case Mips::BI__builtin_msa_subvi_h: - case Mips::BI__builtin_msa_subvi_w: - case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; - case Mips::BI__builtin_msa_binsli_w: - case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; - // These intrinsics take an unsigned 6 bit immediate. - case Mips::BI__builtin_msa_bclri_d: - case Mips::BI__builtin_msa_bnegi_d: - case Mips::BI__builtin_msa_bseti_d: - case Mips::BI__builtin_msa_sat_s_d: - case Mips::BI__builtin_msa_sat_u_d: - case Mips::BI__builtin_msa_slli_d: - case Mips::BI__builtin_msa_srai_d: - case Mips::BI__builtin_msa_srari_d: - case Mips::BI__builtin_msa_srli_d: - case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; - case Mips::BI__builtin_msa_binsli_d: - case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; - // These intrinsics take a signed 5 bit immediate. - case Mips::BI__builtin_msa_ceqi_b: - case Mips::BI__builtin_msa_ceqi_h: - case Mips::BI__builtin_msa_ceqi_w: - case Mips::BI__builtin_msa_ceqi_d: - case Mips::BI__builtin_msa_clti_s_b: - case Mips::BI__builtin_msa_clti_s_h: - case Mips::BI__builtin_msa_clti_s_w: - case Mips::BI__builtin_msa_clti_s_d: - case Mips::BI__builtin_msa_clei_s_b: - case Mips::BI__builtin_msa_clei_s_h: - case Mips::BI__builtin_msa_clei_s_w: - case Mips::BI__builtin_msa_clei_s_d: - case Mips::BI__builtin_msa_maxi_s_b: - case Mips::BI__builtin_msa_maxi_s_h: - case Mips::BI__builtin_msa_maxi_s_w: - case Mips::BI__builtin_msa_maxi_s_d: - case Mips::BI__builtin_msa_mini_s_b: - case Mips::BI__builtin_msa_mini_s_h: - case Mips::BI__builtin_msa_mini_s_w: - case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; - // These intrinsics take an unsigned 8 bit immediate. - case Mips::BI__builtin_msa_andi_b: - case Mips::BI__builtin_msa_nori_b: - case Mips::BI__builtin_msa_ori_b: - case Mips::BI__builtin_msa_shf_b: - case Mips::BI__builtin_msa_shf_h: - case Mips::BI__builtin_msa_shf_w: - case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; - case Mips::BI__builtin_msa_bseli_b: - case Mips::BI__builtin_msa_bmnzi_b: - case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; - // df/n format - // These intrinsics take an unsigned 4 bit immediate. - case Mips::BI__builtin_msa_copy_s_b: - case Mips::BI__builtin_msa_copy_u_b: - case Mips::BI__builtin_msa_insve_b: - case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; - case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; - // These intrinsics take an unsigned 3 bit immediate. - case Mips::BI__builtin_msa_copy_s_h: - case Mips::BI__builtin_msa_copy_u_h: - case Mips::BI__builtin_msa_insve_h: - case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; - case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; - // These intrinsics take an unsigned 2 bit immediate. - case Mips::BI__builtin_msa_copy_s_w: - case Mips::BI__builtin_msa_copy_u_w: - case Mips::BI__builtin_msa_insve_w: - case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; - case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; - // These intrinsics take an unsigned 1 bit immediate. - case Mips::BI__builtin_msa_copy_s_d: - case Mips::BI__builtin_msa_copy_u_d: - case Mips::BI__builtin_msa_insve_d: - case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; - case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; - // Memory offsets and immediate loads. - // These intrinsics take a signed 10 bit immediate. - case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; - case Mips::BI__builtin_msa_ldi_h: - case Mips::BI__builtin_msa_ldi_w: - case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; - case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; - case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; - case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; - case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; - case Mips::BI__builtin_msa_ldr_d: i = 1; l = -4096; u = 4088; m = 8; break; - case Mips::BI__builtin_msa_ldr_w: i = 1; l = -2048; u = 2044; m = 4; break; - case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; - case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; - case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; - case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; - case Mips::BI__builtin_msa_str_d: i = 2; l = -4096; u = 4088; m = 8; break; - case Mips::BI__builtin_msa_str_w: i = 2; l = -2048; u = 2044; m = 4; break; - } - - if (!m) - return BuiltinConstantArgRange(TheCall, i, l, u); - - return BuiltinConstantArgRange(TheCall, i, l, u) || - BuiltinConstantArgMultiple(TheCall, i, m); -} - -/// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str, -/// advancing the pointer over the consumed characters. The decoded type is -/// returned. If the decoded type represents a constant integer with a -/// constraint on its value then Mask is set to that value. The type descriptors -/// used in Str are specific to PPC MMA builtins and are documented in the file -/// defining the PPC builtins. -static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str, - unsigned &Mask) { - bool RequireICE = false; - ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None; - switch (*Str++) { - case 'V': - return Context.getVectorType(Context.UnsignedCharTy, 16, - VectorKind::AltiVecVector); - case 'i': { - char *End; - unsigned size = strtoul(Str, &End, 10); - assert(End != Str && "Missing constant parameter constraint"); - Str = End; - Mask = size; - return Context.IntTy; - } - case 'W': { - char *End; - unsigned size = strtoul(Str, &End, 10); - assert(End != Str && "Missing PowerPC MMA type size"); - Str = End; - QualType Type; - switch (size) { - #define PPC_VECTOR_TYPE(typeName, Id, size) \ - case size: Type = Context.Id##Ty; break; - #include "clang/Basic/PPCTypes.def" - default: llvm_unreachable("Invalid PowerPC MMA vector type"); - } - bool CheckVectorArgs = false; - while (!CheckVectorArgs) { - switch (*Str++) { - case '*': - Type = Context.getPointerType(Type); - break; - case 'C': - Type = Type.withConst(); - break; - default: - CheckVectorArgs = true; - --Str; - break; - } - } - return Type; - } - default: - return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true); - } -} - -static bool isPPC_64Builtin(unsigned BuiltinID) { - // These builtins only work on PPC 64bit targets. - switch (BuiltinID) { - case PPC::BI__builtin_divde: - case PPC::BI__builtin_divdeu: - case PPC::BI__builtin_bpermd: - case PPC::BI__builtin_pdepd: - case PPC::BI__builtin_pextd: - case PPC::BI__builtin_ppc_ldarx: - case PPC::BI__builtin_ppc_stdcx: - case PPC::BI__builtin_ppc_tdw: - case PPC::BI__builtin_ppc_trapd: - case PPC::BI__builtin_ppc_cmpeqb: - case PPC::BI__builtin_ppc_setb: - case PPC::BI__builtin_ppc_mulhd: - case PPC::BI__builtin_ppc_mulhdu: - case PPC::BI__builtin_ppc_maddhd: - case PPC::BI__builtin_ppc_maddhdu: - case PPC::BI__builtin_ppc_maddld: - case PPC::BI__builtin_ppc_load8r: - case PPC::BI__builtin_ppc_store8r: - case PPC::BI__builtin_ppc_insert_exp: - case PPC::BI__builtin_ppc_extract_sig: - case PPC::BI__builtin_ppc_addex: - case PPC::BI__builtin_darn: - case PPC::BI__builtin_darn_raw: - case PPC::BI__builtin_ppc_compare_and_swaplp: - case PPC::BI__builtin_ppc_fetch_and_addlp: - case PPC::BI__builtin_ppc_fetch_and_andlp: - case PPC::BI__builtin_ppc_fetch_and_orlp: - case PPC::BI__builtin_ppc_fetch_and_swaplp: - return true; - } - return false; -} - /// Returns true if the argument consists of one contiguous run of 1s with any /// number of 0s on either side. The 1s are allowed to wrap from LSB to MSB, so /// 0x000FFF0, 0x0000FFFF, 0xFF0000FF, 0x0 are all runs. 0x0F0F0000 is not, @@ -5293,182 +3322,6 @@ bool Sema::ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum) { << ArgNum << Arg->getSourceRange(); } -bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall) { - unsigned i = 0, l = 0, u = 0; - bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; - llvm::APSInt Result; - - if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit) - return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) - << TheCall->getSourceRange(); - - switch (BuiltinID) { - default: return false; - case PPC::BI__builtin_altivec_crypto_vshasigmaw: - case PPC::BI__builtin_altivec_crypto_vshasigmad: - return BuiltinConstantArgRange(TheCall, 1, 0, 1) || - BuiltinConstantArgRange(TheCall, 2, 0, 15); - case PPC::BI__builtin_altivec_dss: - return BuiltinConstantArgRange(TheCall, 0, 0, 3); - case PPC::BI__builtin_tbegin: - case PPC::BI__builtin_tend: - return BuiltinConstantArgRange(TheCall, 0, 0, 1); - case PPC::BI__builtin_tsr: - return BuiltinConstantArgRange(TheCall, 0, 0, 7); - case PPC::BI__builtin_tabortwc: - case PPC::BI__builtin_tabortdc: - return BuiltinConstantArgRange(TheCall, 0, 0, 31); - case PPC::BI__builtin_tabortwci: - case PPC::BI__builtin_tabortdci: - return BuiltinConstantArgRange(TheCall, 0, 0, 31) || - BuiltinConstantArgRange(TheCall, 2, 0, 31); - // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05', - // __builtin_(un)pack_longdouble are available only if long double uses IBM - // extended double representation. - case PPC::BI__builtin_unpack_longdouble: - if (BuiltinConstantArgRange(TheCall, 1, 0, 1)) - return true; - [[fallthrough]]; - case PPC::BI__builtin_pack_longdouble: - if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble()) - return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi) - << "ibmlongdouble"; - return false; - case PPC::BI__builtin_altivec_dst: - case PPC::BI__builtin_altivec_dstt: - case PPC::BI__builtin_altivec_dstst: - case PPC::BI__builtin_altivec_dststt: - return BuiltinConstantArgRange(TheCall, 2, 0, 3); - case PPC::BI__builtin_vsx_xxpermdi: - case PPC::BI__builtin_vsx_xxsldwi: - return BuiltinVSX(TheCall); - case PPC::BI__builtin_unpack_vector_int128: - return BuiltinConstantArgRange(TheCall, 1, 0, 1); - case PPC::BI__builtin_altivec_vgnb: - return BuiltinConstantArgRange(TheCall, 1, 2, 7); - case PPC::BI__builtin_vsx_xxeval: - return BuiltinConstantArgRange(TheCall, 3, 0, 255); - case PPC::BI__builtin_altivec_vsldbi: - return BuiltinConstantArgRange(TheCall, 2, 0, 7); - case PPC::BI__builtin_altivec_vsrdbi: - return BuiltinConstantArgRange(TheCall, 2, 0, 7); - case PPC::BI__builtin_vsx_xxpermx: - return BuiltinConstantArgRange(TheCall, 3, 0, 7); - case PPC::BI__builtin_ppc_tw: - case PPC::BI__builtin_ppc_tdw: - return BuiltinConstantArgRange(TheCall, 2, 1, 31); - case PPC::BI__builtin_ppc_cmprb: - return BuiltinConstantArgRange(TheCall, 0, 0, 1); - // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must - // be a constant that represents a contiguous bit field. - case PPC::BI__builtin_ppc_rlwnm: - return ValueIsRunOfOnes(TheCall, 2); - case PPC::BI__builtin_ppc_rlwimi: - return BuiltinConstantArgRange(TheCall, 2, 0, 31) || - ValueIsRunOfOnes(TheCall, 3); - case PPC::BI__builtin_ppc_rldimi: - return BuiltinConstantArgRange(TheCall, 2, 0, 63) || - ValueIsRunOfOnes(TheCall, 3); - case PPC::BI__builtin_ppc_addex: { - if (BuiltinConstantArgRange(TheCall, 2, 0, 3)) - return true; - // Output warning for reserved values 1 to 3. - int ArgValue = - TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue(); - if (ArgValue != 0) - Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour) - << ArgValue; - return false; - } - case PPC::BI__builtin_ppc_mtfsb0: - case PPC::BI__builtin_ppc_mtfsb1: - return BuiltinConstantArgRange(TheCall, 0, 0, 31); - case PPC::BI__builtin_ppc_mtfsf: - return BuiltinConstantArgRange(TheCall, 0, 0, 255); - case PPC::BI__builtin_ppc_mtfsfi: - return BuiltinConstantArgRange(TheCall, 0, 0, 7) || - BuiltinConstantArgRange(TheCall, 1, 0, 15); - case PPC::BI__builtin_ppc_alignx: - return BuiltinConstantArgPower2(TheCall, 0); - case PPC::BI__builtin_ppc_rdlam: - return ValueIsRunOfOnes(TheCall, 2); - case PPC::BI__builtin_vsx_ldrmb: - case PPC::BI__builtin_vsx_strmb: - return BuiltinConstantArgRange(TheCall, 1, 1, 16); - case PPC::BI__builtin_altivec_vcntmbb: - case PPC::BI__builtin_altivec_vcntmbh: - case PPC::BI__builtin_altivec_vcntmbw: - case PPC::BI__builtin_altivec_vcntmbd: - return BuiltinConstantArgRange(TheCall, 1, 0, 1); - case PPC::BI__builtin_vsx_xxgenpcvbm: - case PPC::BI__builtin_vsx_xxgenpcvhm: - case PPC::BI__builtin_vsx_xxgenpcvwm: - case PPC::BI__builtin_vsx_xxgenpcvdm: - return BuiltinConstantArgRange(TheCall, 1, 0, 3); - case PPC::BI__builtin_ppc_test_data_class: { - // Check if the first argument of the __builtin_ppc_test_data_class call is - // valid. The argument must be 'float' or 'double' or '__float128'. - QualType ArgType = TheCall->getArg(0)->getType(); - if (ArgType != QualType(Context.FloatTy) && - ArgType != QualType(Context.DoubleTy) && - ArgType != QualType(Context.Float128Ty)) - return Diag(TheCall->getBeginLoc(), - diag::err_ppc_invalid_test_data_class_type); - return BuiltinConstantArgRange(TheCall, 1, 0, 127); - } - case PPC::BI__builtin_ppc_maxfe: - case PPC::BI__builtin_ppc_minfe: - case PPC::BI__builtin_ppc_maxfl: - case PPC::BI__builtin_ppc_minfl: - case PPC::BI__builtin_ppc_maxfs: - case PPC::BI__builtin_ppc_minfs: { - if (Context.getTargetInfo().getTriple().isOSAIX() && - (BuiltinID == PPC::BI__builtin_ppc_maxfe || - BuiltinID == PPC::BI__builtin_ppc_minfe)) - return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type) - << "builtin" << true << 128 << QualType(Context.LongDoubleTy) - << false << Context.getTargetInfo().getTriple().str(); - // Argument type should be exact. - QualType ArgType = QualType(Context.LongDoubleTy); - if (BuiltinID == PPC::BI__builtin_ppc_maxfl || - BuiltinID == PPC::BI__builtin_ppc_minfl) - ArgType = QualType(Context.DoubleTy); - else if (BuiltinID == PPC::BI__builtin_ppc_maxfs || - BuiltinID == PPC::BI__builtin_ppc_minfs) - ArgType = QualType(Context.FloatTy); - for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I) - if (TheCall->getArg(I)->getType() != ArgType) - return Diag(TheCall->getBeginLoc(), - diag::err_typecheck_convert_incompatible) - << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0; - return false; - } -#define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \ - case PPC::BI__builtin_##Name: \ - return BuiltinPPCMMACall(TheCall, BuiltinID, Types); -#include "clang/Basic/BuiltinsPPC.def" - } - return BuiltinConstantArgRange(TheCall, i, l, u); -} - -// Check if the given type is a non-pointer PPC MMA type. This function is used -// in Sema to prevent invalid uses of restricted PPC MMA types. -bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { - if (Type->isPointerType() || Type->isArrayType()) - return false; - - QualType CoreType = Type.getCanonicalType().getUnqualifiedType(); -#define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty - if (false -#include "clang/Basic/PPCTypes.def" - ) { - Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type); - return true; - } - return false; -} - // Helper function for CheckHLSLBuiltinFunctionCall bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { assert(TheCall->getNumArgs() > 1); @@ -5664,225 +3517,30 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } // Note these are llvm builtins that we want to catch invalid intrinsic // generation. Normal handling of these builitns will occur elsewhere. - case Builtin::BI__builtin_elementwise_bitreverse: { - if (CheckUnsignedIntRepresentation(this, TheCall)) - return true; - break; - } - case Builtin::BI__builtin_elementwise_ceil: - case Builtin::BI__builtin_elementwise_cos: - case Builtin::BI__builtin_elementwise_exp: - case Builtin::BI__builtin_elementwise_exp2: - case Builtin::BI__builtin_elementwise_floor: - case Builtin::BI__builtin_elementwise_log: - case Builtin::BI__builtin_elementwise_log2: - case Builtin::BI__builtin_elementwise_log10: - case Builtin::BI__builtin_elementwise_pow: - case Builtin::BI__builtin_elementwise_roundeven: - case Builtin::BI__builtin_elementwise_sin: - case Builtin::BI__builtin_elementwise_sqrt: - case Builtin::BI__builtin_elementwise_tan: - case Builtin::BI__builtin_elementwise_trunc: { - if (CheckFloatOrHalfRepresentations(this, TheCall)) - return true; - break; - } - } - return false; -} - -bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, - CallExpr *TheCall) { - // position of memory order and scope arguments in the builtin - unsigned OrderIndex, ScopeIndex; - switch (BuiltinID) { - case AMDGPU::BI__builtin_amdgcn_global_load_lds: { - constexpr const int SizeIdx = 2; - llvm::APSInt Size; - Expr *ArgExpr = TheCall->getArg(SizeIdx); - ExprResult R = VerifyIntegerConstantExpression(ArgExpr, &Size); - if (R.isInvalid()) - return true; - switch (Size.getSExtValue()) { - case 1: - case 2: - case 4: - return false; - default: - Diag(ArgExpr->getExprLoc(), - diag::err_amdgcn_global_load_lds_size_invalid_value) - << ArgExpr->getSourceRange(); - Diag(ArgExpr->getExprLoc(), - diag::note_amdgcn_global_load_lds_size_valid_value) - << ArgExpr->getSourceRange(); - return true; - } - } - case AMDGPU::BI__builtin_amdgcn_get_fpenv: - case AMDGPU::BI__builtin_amdgcn_set_fpenv: - return false; - case AMDGPU::BI__builtin_amdgcn_atomic_inc32: - case AMDGPU::BI__builtin_amdgcn_atomic_inc64: - case AMDGPU::BI__builtin_amdgcn_atomic_dec32: - case AMDGPU::BI__builtin_amdgcn_atomic_dec64: - OrderIndex = 2; - ScopeIndex = 3; - break; - case AMDGPU::BI__builtin_amdgcn_fence: - OrderIndex = 0; - ScopeIndex = 1; - break; - default: - return false; - } - - ExprResult Arg = TheCall->getArg(OrderIndex); - auto ArgExpr = Arg.get(); - Expr::EvalResult ArgResult; - - if (!ArgExpr->EvaluateAsInt(ArgResult, Context)) - return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int) - << ArgExpr->getType(); - auto Ord = ArgResult.Val.getInt().getZExtValue(); - - // Check validity of memory ordering as per C11 / C++11's memody model. - // Only fence needs check. Atomic dec/inc allow all memory orders. - if (!llvm::isValidAtomicOrderingCABI(Ord)) - return Diag(ArgExpr->getBeginLoc(), - diag::warn_atomic_op_has_invalid_memory_order) - << 0 << ArgExpr->getSourceRange(); - switch (static_cast(Ord)) { - case llvm::AtomicOrderingCABI::relaxed: - case llvm::AtomicOrderingCABI::consume: - if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence) - return Diag(ArgExpr->getBeginLoc(), - diag::warn_atomic_op_has_invalid_memory_order) - << 0 << ArgExpr->getSourceRange(); - break; - case llvm::AtomicOrderingCABI::acquire: - case llvm::AtomicOrderingCABI::release: - case llvm::AtomicOrderingCABI::acq_rel: - case llvm::AtomicOrderingCABI::seq_cst: + case Builtin::BI__builtin_elementwise_bitreverse: { + if (CheckUnsignedIntRepresentation(this, TheCall)) + return true; break; } - - Arg = TheCall->getArg(ScopeIndex); - ArgExpr = Arg.get(); - Expr::EvalResult ArgResult1; - // Check that sync scope is a constant literal - if (!ArgExpr->EvaluateAsConstantExpr(ArgResult1, Context)) - return Diag(ArgExpr->getExprLoc(), diag::err_expr_not_string_literal) - << ArgExpr->getType(); - - return false; -} - -bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, - CallExpr *TheCall) { - if (BuiltinID == SystemZ::BI__builtin_tabort) { - Expr *Arg = TheCall->getArg(0); - if (std::optional AbortCode = - Arg->getIntegerConstantExpr(Context)) - if (AbortCode->getSExtValue() >= 0 && AbortCode->getSExtValue() < 256) - return Diag(Arg->getBeginLoc(), diag::err_systemz_invalid_tabort_code) - << Arg->getSourceRange(); - } - - // For intrinsics which take an immediate value as part of the instruction, - // range check them here. - unsigned i = 0, l = 0, u = 0; - switch (BuiltinID) { - default: return false; - case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_verimb: - case SystemZ::BI__builtin_s390_verimh: - case SystemZ::BI__builtin_s390_verimf: - case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break; - case SystemZ::BI__builtin_s390_vfaeb: - case SystemZ::BI__builtin_s390_vfaeh: - case SystemZ::BI__builtin_s390_vfaef: - case SystemZ::BI__builtin_s390_vfaebs: - case SystemZ::BI__builtin_s390_vfaehs: - case SystemZ::BI__builtin_s390_vfaefs: - case SystemZ::BI__builtin_s390_vfaezb: - case SystemZ::BI__builtin_s390_vfaezh: - case SystemZ::BI__builtin_s390_vfaezf: - case SystemZ::BI__builtin_s390_vfaezbs: - case SystemZ::BI__builtin_s390_vfaezhs: - case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vfisb: - case SystemZ::BI__builtin_s390_vfidb: - return BuiltinConstantArgRange(TheCall, 1, 0, 15) || - BuiltinConstantArgRange(TheCall, 2, 0, 15); - case SystemZ::BI__builtin_s390_vftcisb: - case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break; - case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vstrcb: - case SystemZ::BI__builtin_s390_vstrch: - case SystemZ::BI__builtin_s390_vstrcf: - case SystemZ::BI__builtin_s390_vstrczb: - case SystemZ::BI__builtin_s390_vstrczh: - case SystemZ::BI__builtin_s390_vstrczf: - case SystemZ::BI__builtin_s390_vstrcbs: - case SystemZ::BI__builtin_s390_vstrchs: - case SystemZ::BI__builtin_s390_vstrcfs: - case SystemZ::BI__builtin_s390_vstrczbs: - case SystemZ::BI__builtin_s390_vstrczhs: - case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vfminsb: - case SystemZ::BI__builtin_s390_vfmaxsb: - case SystemZ::BI__builtin_s390_vfmindb: - case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vsld: i = 2; l = 0; u = 7; break; - case SystemZ::BI__builtin_s390_vsrd: i = 2; l = 0; u = 7; break; - case SystemZ::BI__builtin_s390_vclfnhs: - case SystemZ::BI__builtin_s390_vclfnls: - case SystemZ::BI__builtin_s390_vcfn: - case SystemZ::BI__builtin_s390_vcnf: i = 1; l = 0; u = 15; break; - case SystemZ::BI__builtin_s390_vcrnfs: i = 2; l = 0; u = 15; break; - } - return BuiltinConstantArgRange(TheCall, i, l, u); -} - -bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall) { - switch (BuiltinID) { - case WebAssembly::BI__builtin_wasm_ref_null_extern: - return BuiltinWasmRefNullExtern(TheCall); - case WebAssembly::BI__builtin_wasm_ref_null_func: - return BuiltinWasmRefNullFunc(TheCall); - case WebAssembly::BI__builtin_wasm_table_get: - return BuiltinWasmTableGet(TheCall); - case WebAssembly::BI__builtin_wasm_table_set: - return BuiltinWasmTableSet(TheCall); - case WebAssembly::BI__builtin_wasm_table_size: - return BuiltinWasmTableSize(TheCall); - case WebAssembly::BI__builtin_wasm_table_grow: - return BuiltinWasmTableGrow(TheCall); - case WebAssembly::BI__builtin_wasm_table_fill: - return BuiltinWasmTableFill(TheCall); - case WebAssembly::BI__builtin_wasm_table_copy: - return BuiltinWasmTableCopy(TheCall); + case Builtin::BI__builtin_elementwise_ceil: + case Builtin::BI__builtin_elementwise_cos: + case Builtin::BI__builtin_elementwise_exp: + case Builtin::BI__builtin_elementwise_exp2: + case Builtin::BI__builtin_elementwise_floor: + case Builtin::BI__builtin_elementwise_log: + case Builtin::BI__builtin_elementwise_log2: + case Builtin::BI__builtin_elementwise_log10: + case Builtin::BI__builtin_elementwise_pow: + case Builtin::BI__builtin_elementwise_roundeven: + case Builtin::BI__builtin_elementwise_sin: + case Builtin::BI__builtin_elementwise_sqrt: + case Builtin::BI__builtin_elementwise_tan: + case Builtin::BI__builtin_elementwise_trunc: { + if (CheckFloatOrHalfRepresentations(this, TheCall)) + return true; + break; } - - return false; -} - -bool Sema::CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall) { - switch (BuiltinID) { - case NVPTX::BI__nvvm_cp_async_ca_shared_global_4: - case NVPTX::BI__nvvm_cp_async_ca_shared_global_8: - case NVPTX::BI__nvvm_cp_async_ca_shared_global_16: - case NVPTX::BI__nvvm_cp_async_cg_shared_global_16: - return checkArgCountAtMost(TheCall, 3); } - return false; } @@ -6113,40 +3771,6 @@ static void CheckNonNullArguments(Sema &S, } } -// 16 byte ByVal alignment not due to a vector member is not honoured by XL -// on AIX. Emit a warning here that users are generating binary incompatible -// code to be safe. -// Here we try to get information about the alignment of the struct member -// from the struct passed to the caller function. We only warn when the struct -// is passed byval, hence the series of checks and early returns if we are a not -// passing a struct byval. -void Sema::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) { - const auto *ICE = dyn_cast(Arg->IgnoreParens()); - if (!ICE) - return; - - const auto *DR = dyn_cast(ICE->getSubExpr()); - if (!DR) - return; - - const auto *PD = dyn_cast(DR->getDecl()); - if (!PD || !PD->getType()->isRecordType()) - return; - - QualType ArgType = Arg->getType(); - for (const FieldDecl *FD : - ArgType->castAs()->getDecl()->fields()) { - if (const auto *AA = FD->getAttr()) { - CharUnits Alignment = - Context.toCharUnitsFromBits(AA->getAlignment(Context)); - if (Alignment.getQuantity() == 16) { - Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD; - Diag(Loc, diag::note_misaligned_member_used_here) << PD; - } - } - } -} - /// Warn if a pointer or reference argument passed to a function points to an /// object that is less aligned than the parameter. This can happen when /// creating a typedef with a lower alignment than the original type and then @@ -6263,7 +3887,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, FDecl->hasLinkage() && FDecl->getFormalLinkage() != Linkage::Internal && CallType == VariadicDoesNotApply) - checkAIXMemberAlignment((Arg->getExprLoc()), Arg); + PPC().checkAIXMemberAlignment((Arg->getExprLoc()), Arg); QualType ParamTy = Proto->getParamType(ArgIdx); if (ParamTy->isSizelessVectorType()) @@ -6299,10 +3923,10 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, bool IsCalleeStreamingCompatible = ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMCompatibleMask; - ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD); + SemaARM::ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD); if (!IsCalleeStreamingCompatible && - (CallerFnType == ArmStreamingCompatible || - ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming))) { + (CallerFnType == SemaARM::ArmStreamingCompatible || + ((CallerFnType == SemaARM::ArmStreaming) ^ IsCalleeStreaming))) { if (IsScalableArg) Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) << /*IsArg=*/true; @@ -7165,35 +4789,6 @@ static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) { return false; } -bool Sema::BuiltinWasmRefNullExtern(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) - return true; - - TheCall->setType(Context.getWebAssemblyExternrefType()); - - return false; -} - -bool Sema::BuiltinWasmRefNullFunc(CallExpr *TheCall) { - if (TheCall->getNumArgs() != 0) { - Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args) - << 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs() - << /*is non object*/ 0; - return true; - } - - // This custom type checking code ensures that the nodes are as expected - // in order to later on generate the necessary builtin. - QualType Pointee = Context.getFunctionType(Context.VoidTy, {}, {}); - QualType Type = Context.getPointerType(Pointee); - Pointee = Context.getAddrSpaceQualType(Pointee, LangAS::wasm_funcref); - Type = Context.getAttributedType(attr::WebAssemblyFuncref, Type, - Context.getPointerType(Pointee)); - TheCall->setType(Type); - - return false; -} - /// We have a call to a function like __sync_fetch_and_add, which is an /// overloaded function based on the pointer type of its first argument. /// The main BuildCallExpr routines have already promoted the types of @@ -8069,55 +5664,6 @@ bool Sema::BuiltinComplex(CallExpr *TheCall) { return false; } -// Customized Sema Checking for VSX builtins that have the following signature: -// vector [...] builtinName(vector [...], vector [...], const int); -// Which takes the same type of vectors (any legal vector type) for the first -// two arguments and takes compile time constant for the third argument. -// Example builtins are : -// vector double vec_xxpermdi(vector double, vector double, int); -// vector short vec_xxsldwi(vector short, vector short, int); -bool Sema::BuiltinVSX(CallExpr *TheCall) { - unsigned ExpectedNumArgs = 3; - if (checkArgCount(TheCall, ExpectedNumArgs)) - return true; - - // Check the third argument is a compile time constant - if (!TheCall->getArg(2)->isIntegerConstantExpr(Context)) - return Diag(TheCall->getBeginLoc(), - diag::err_vsx_builtin_nonconstant_argument) - << 3 /* argument index */ << TheCall->getDirectCallee() - << SourceRange(TheCall->getArg(2)->getBeginLoc(), - TheCall->getArg(2)->getEndLoc()); - - QualType Arg1Ty = TheCall->getArg(0)->getType(); - QualType Arg2Ty = TheCall->getArg(1)->getType(); - - // Check the type of argument 1 and argument 2 are vectors. - SourceLocation BuiltinLoc = TheCall->getBeginLoc(); - if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) || - (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) { - return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector) - << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false - << SourceRange(TheCall->getArg(0)->getBeginLoc(), - TheCall->getArg(1)->getEndLoc()); - } - - // Check the first two arguments are the same type. - if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) { - return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector) - << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false - << SourceRange(TheCall->getArg(0)->getBeginLoc(), - TheCall->getArg(1)->getEndLoc()); - } - - // When default clang type checking is turned off and the customized type - // checking is used, the returning type of the function must be explicitly - // set. Otherwise it is _Bool by default. - TheCall->setType(Arg1Ty); - - return false; -} - /// BuiltinShuffleVector - Handle __builtin_shufflevector. // This is declared to take (...), so we have to check everything. ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) { @@ -8635,360 +6181,6 @@ bool Sema::BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, << Arg->getSourceRange(); } -/// BuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions -bool Sema::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) { - if (BuiltinID == AArch64::BI__builtin_arm_irg) { - if (checkArgCount(TheCall, 2)) - return true; - Expr *Arg0 = TheCall->getArg(0); - Expr *Arg1 = TheCall->getArg(1); - - ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0); - if (FirstArg.isInvalid()) - return true; - QualType FirstArgType = FirstArg.get()->getType(); - if (!FirstArgType->isAnyPointerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) - << "first" << FirstArgType << Arg0->getSourceRange(); - TheCall->setArg(0, FirstArg.get()); - - ExprResult SecArg = DefaultLvalueConversion(Arg1); - if (SecArg.isInvalid()) - return true; - QualType SecArgType = SecArg.get()->getType(); - if (!SecArgType->isIntegerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) - << "second" << SecArgType << Arg1->getSourceRange(); - - // Derive the return type from the pointer argument. - TheCall->setType(FirstArgType); - return false; - } - - if (BuiltinID == AArch64::BI__builtin_arm_addg) { - if (checkArgCount(TheCall, 2)) - return true; - - Expr *Arg0 = TheCall->getArg(0); - ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0); - if (FirstArg.isInvalid()) - return true; - QualType FirstArgType = FirstArg.get()->getType(); - if (!FirstArgType->isAnyPointerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) - << "first" << FirstArgType << Arg0->getSourceRange(); - TheCall->setArg(0, FirstArg.get()); - - // Derive the return type from the pointer argument. - TheCall->setType(FirstArgType); - - // Second arg must be an constant in range [0,15] - return BuiltinConstantArgRange(TheCall, 1, 0, 15); - } - - if (BuiltinID == AArch64::BI__builtin_arm_gmi) { - if (checkArgCount(TheCall, 2)) - return true; - Expr *Arg0 = TheCall->getArg(0); - Expr *Arg1 = TheCall->getArg(1); - - ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0); - if (FirstArg.isInvalid()) - return true; - QualType FirstArgType = FirstArg.get()->getType(); - if (!FirstArgType->isAnyPointerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) - << "first" << FirstArgType << Arg0->getSourceRange(); - - QualType SecArgType = Arg1->getType(); - if (!SecArgType->isIntegerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) - << "second" << SecArgType << Arg1->getSourceRange(); - TheCall->setType(Context.IntTy); - return false; - } - - if (BuiltinID == AArch64::BI__builtin_arm_ldg || - BuiltinID == AArch64::BI__builtin_arm_stg) { - if (checkArgCount(TheCall, 1)) - return true; - Expr *Arg0 = TheCall->getArg(0); - ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0); - if (FirstArg.isInvalid()) - return true; - - QualType FirstArgType = FirstArg.get()->getType(); - if (!FirstArgType->isAnyPointerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer) - << "first" << FirstArgType << Arg0->getSourceRange(); - TheCall->setArg(0, FirstArg.get()); - - // Derive the return type from the pointer argument. - if (BuiltinID == AArch64::BI__builtin_arm_ldg) - TheCall->setType(FirstArgType); - return false; - } - - if (BuiltinID == AArch64::BI__builtin_arm_subp) { - Expr *ArgA = TheCall->getArg(0); - Expr *ArgB = TheCall->getArg(1); - - ExprResult ArgExprA = DefaultFunctionArrayLvalueConversion(ArgA); - ExprResult ArgExprB = DefaultFunctionArrayLvalueConversion(ArgB); - - if (ArgExprA.isInvalid() || ArgExprB.isInvalid()) - return true; - - QualType ArgTypeA = ArgExprA.get()->getType(); - QualType ArgTypeB = ArgExprB.get()->getType(); - - auto isNull = [&] (Expr *E) -> bool { - return E->isNullPointerConstant( - Context, Expr::NPC_ValueDependentIsNotNull); }; - - // argument should be either a pointer or null - if (!ArgTypeA->isAnyPointerType() && !isNull(ArgA)) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer) - << "first" << ArgTypeA << ArgA->getSourceRange(); - - if (!ArgTypeB->isAnyPointerType() && !isNull(ArgB)) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer) - << "second" << ArgTypeB << ArgB->getSourceRange(); - - // Ensure Pointee types are compatible - if (ArgTypeA->isAnyPointerType() && !isNull(ArgA) && - ArgTypeB->isAnyPointerType() && !isNull(ArgB)) { - QualType pointeeA = ArgTypeA->getPointeeType(); - QualType pointeeB = ArgTypeB->getPointeeType(); - if (!Context.typesAreCompatible( - Context.getCanonicalType(pointeeA).getUnqualifiedType(), - Context.getCanonicalType(pointeeB).getUnqualifiedType())) { - return Diag(TheCall->getBeginLoc(), diag::err_typecheck_sub_ptr_compatible) - << ArgTypeA << ArgTypeB << ArgA->getSourceRange() - << ArgB->getSourceRange(); - } - } - - // at least one argument should be pointer type - if (!ArgTypeA->isAnyPointerType() && !ArgTypeB->isAnyPointerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_any2arg_pointer) - << ArgTypeA << ArgTypeB << ArgA->getSourceRange(); - - if (isNull(ArgA)) // adopt type of the other pointer - ArgExprA = ImpCastExprToType(ArgExprA.get(), ArgTypeB, CK_NullToPointer); - - if (isNull(ArgB)) - ArgExprB = ImpCastExprToType(ArgExprB.get(), ArgTypeA, CK_NullToPointer); - - TheCall->setArg(0, ArgExprA.get()); - TheCall->setArg(1, ArgExprB.get()); - TheCall->setType(Context.LongLongTy); - return false; - } - assert(false && "Unhandled ARM MTE intrinsic"); - return true; -} - -/// BuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr -/// TheCall is an ARM/AArch64 special register string literal. -bool Sema::BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, - int ArgNum, unsigned ExpectedFieldNum, - bool AllowName) { - bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 || - BuiltinID == ARM::BI__builtin_arm_wsr64 || - BuiltinID == ARM::BI__builtin_arm_rsr || - BuiltinID == ARM::BI__builtin_arm_rsrp || - BuiltinID == ARM::BI__builtin_arm_wsr || - BuiltinID == ARM::BI__builtin_arm_wsrp; - bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 || - BuiltinID == AArch64::BI__builtin_arm_wsr64 || - BuiltinID == AArch64::BI__builtin_arm_rsr128 || - BuiltinID == AArch64::BI__builtin_arm_wsr128 || - BuiltinID == AArch64::BI__builtin_arm_rsr || - BuiltinID == AArch64::BI__builtin_arm_rsrp || - BuiltinID == AArch64::BI__builtin_arm_wsr || - BuiltinID == AArch64::BI__builtin_arm_wsrp; - assert((IsARMBuiltin || IsAArch64Builtin) && "Unexpected ARM builtin."); - - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check if the argument is a string literal. - if (!isa(Arg->IgnoreParenImpCasts())) - return Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) - << Arg->getSourceRange(); - - // Check the type of special register given. - StringRef Reg = cast(Arg->IgnoreParenImpCasts())->getString(); - SmallVector Fields; - Reg.split(Fields, ":"); - - if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1)) - return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) - << Arg->getSourceRange(); - - // If the string is the name of a register then we cannot check that it is - // valid here but if the string is of one the forms described in ACLE then we - // can check that the supplied fields are integers and within the valid - // ranges. - if (Fields.size() > 1) { - bool FiveFields = Fields.size() == 5; - - bool ValidString = true; - if (IsARMBuiltin) { - ValidString &= Fields[0].starts_with_insensitive("cp") || - Fields[0].starts_with_insensitive("p"); - if (ValidString) - Fields[0] = Fields[0].drop_front( - Fields[0].starts_with_insensitive("cp") ? 2 : 1); - - ValidString &= Fields[2].starts_with_insensitive("c"); - if (ValidString) - Fields[2] = Fields[2].drop_front(1); - - if (FiveFields) { - ValidString &= Fields[3].starts_with_insensitive("c"); - if (ValidString) - Fields[3] = Fields[3].drop_front(1); - } - } - - SmallVector Ranges; - if (FiveFields) - Ranges.append({IsAArch64Builtin ? 1 : 15, 7, 15, 15, 7}); - else - Ranges.append({15, 7, 15}); - - for (unsigned i=0; i= 0 && IntField <= Ranges[i]); - } - - if (!ValidString) - return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) - << Arg->getSourceRange(); - } else if (IsAArch64Builtin && Fields.size() == 1) { - // This code validates writes to PSTATE registers. - - // Not a write. - if (TheCall->getNumArgs() != 2) - return false; - - // The 128-bit system register accesses do not touch PSTATE. - if (BuiltinID == AArch64::BI__builtin_arm_rsr128 || - BuiltinID == AArch64::BI__builtin_arm_wsr128) - return false; - - // These are the named PSTATE accesses using "MSR (immediate)" instructions, - // along with the upper limit on the immediates allowed. - auto MaxLimit = llvm::StringSwitch>(Reg) - .CaseLower("spsel", 15) - .CaseLower("daifclr", 15) - .CaseLower("daifset", 15) - .CaseLower("pan", 15) - .CaseLower("uao", 15) - .CaseLower("dit", 15) - .CaseLower("ssbs", 15) - .CaseLower("tco", 15) - .CaseLower("allint", 1) - .CaseLower("pm", 1) - .Default(std::nullopt); - - // If this is not a named PSTATE, just continue without validating, as this - // will be lowered to an "MSR (register)" instruction directly - if (!MaxLimit) - return false; - - // Here we only allow constants in the range for that pstate, as required by - // the ACLE. - // - // While clang also accepts the names of system registers in its ACLE - // intrinsics, we prevent this with the PSTATE names used in MSR (immediate) - // as the value written via a register is different to the value used as an - // immediate to have the same effect. e.g., for the instruction `msr tco, - // x0`, it is bit 25 of register x0 that is written into PSTATE.TCO, but - // with `msr tco, #imm`, it is bit 0 of xN that is written into PSTATE.TCO. - // - // If a programmer wants to codegen the MSR (register) form of `msr tco, - // xN`, they can still do so by specifying the register using five - // colon-separated numbers in a string. - return BuiltinConstantArgRange(TheCall, 1, 0, *MaxLimit); - } - - return false; -} - -/// BuiltinPPCMMACall - Check the call to a PPC MMA builtin for validity. -/// Emit an error and return true on failure; return false on success. -/// TypeStr is a string containing the type descriptor of the value returned by -/// the builtin and the descriptors of the expected type of the arguments. -bool Sema::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, - const char *TypeStr) { - - assert((TypeStr[0] != '\0') && - "Invalid types in PPC MMA builtin declaration"); - - unsigned Mask = 0; - unsigned ArgNum = 0; - - // The first type in TypeStr is the type of the value returned by the - // builtin. So we first read that type and change the type of TheCall. - QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); - TheCall->setType(type); - - while (*TypeStr != '\0') { - Mask = 0; - QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); - if (ArgNum >= TheCall->getNumArgs()) { - ArgNum++; - break; - } - - Expr *Arg = TheCall->getArg(ArgNum); - QualType PassedType = Arg->getType(); - QualType StrippedRVType = PassedType.getCanonicalType(); - - // Strip Restrict/Volatile qualifiers. - if (StrippedRVType.isRestrictQualified() || - StrippedRVType.isVolatileQualified()) - StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType(); - - // The only case where the argument type and expected type are allowed to - // mismatch is if the argument type is a non-void pointer (or array) and - // expected type is a void pointer. - if (StrippedRVType != ExpectedType) - if (!(ExpectedType->isVoidPointerType() && - (StrippedRVType->isPointerType() || StrippedRVType->isArrayType()))) - return Diag(Arg->getBeginLoc(), - diag::err_typecheck_convert_incompatible) - << PassedType << ExpectedType << 1 << 0 << 0; - - // If the value of the Mask is not 0, we have a constraint in the size of - // the integer argument so here we ensure the argument is a constant that - // is in the valid range. - if (Mask != 0 && BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true)) - return true; - - ArgNum++; - } - - // In case we exited early from the previous loop, there are other types to - // read from TypeStr. So we need to read them all to ensure we have the right - // number of arguments in TheCall and if it is not the case, to display a - // better error message. - while (*TypeStr != '\0') { - (void) DecodePPCMMATypeFromStr(Context, TypeStr, Mask); - ArgNum++; - } - if (checkArgCount(TheCall, ArgNum)) - return true; - - return false; -} - /// BuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val). /// This checks that the target supports __builtin_longjmp and /// that val is a constant 1. @@ -12718,7 +9910,7 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, // PPC MMA non-pointer types are not allowed as return type. Checking the type // here prevent the user from using a PPC MMA type as trailing return type. if (Context.getTargetInfo().getTriple().isPPC64()) - CheckPPCMMAType(RetValExp->getType(), ReturnLoc); + PPC().CheckPPCMMAType(RetValExp->getType(), ReturnLoc); } /// Check for comparisons of floating-point values using == and !=. Issue a @@ -18396,168 +15588,6 @@ ExprResult Sema::BuiltinMatrixColumnMajorStore(CallExpr *TheCall, return CallResult; } -/// Checks the argument at the given index is a WebAssembly table and if it -/// is, sets ElTy to the element type. -static bool CheckWasmBuiltinArgIsTable(Sema &S, CallExpr *E, unsigned ArgIndex, - QualType &ElTy) { - Expr *ArgExpr = E->getArg(ArgIndex); - const auto *ATy = dyn_cast(ArgExpr->getType()); - if (!ATy || !ATy->getElementType().isWebAssemblyReferenceType()) { - return S.Diag(ArgExpr->getBeginLoc(), - diag::err_wasm_builtin_arg_must_be_table_type) - << ArgIndex + 1 << ArgExpr->getSourceRange(); - } - ElTy = ATy->getElementType(); - return false; -} - -/// Checks the argument at the given index is an integer. -static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, - unsigned ArgIndex) { - Expr *ArgExpr = E->getArg(ArgIndex); - if (!ArgExpr->getType()->isIntegerType()) { - return S.Diag(ArgExpr->getBeginLoc(), - diag::err_wasm_builtin_arg_must_be_integer_type) - << ArgIndex + 1 << ArgExpr->getSourceRange(); - } - return false; -} - -/// Check that the first argument is a WebAssembly table, and the second -/// is an index to use as index into the table. -bool Sema::BuiltinWasmTableGet(CallExpr *TheCall) { - if (checkArgCount(TheCall, 2)) - return true; - - QualType ElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, ElTy)) - return true; - - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, 1)) - return true; - - // If all is well, we set the type of TheCall to be the type of the - // element of the table. - // i.e. a table.get on an externref table has type externref, - // or whatever the type of the table element is. - TheCall->setType(ElTy); - - return false; -} - -/// Check that the first argumnet is a WebAssembly table, the second is -/// an index to use as index into the table and the third is the reference -/// type to set into the table. -bool Sema::BuiltinWasmTableSet(CallExpr *TheCall) { - if (checkArgCount(TheCall, 3)) - return true; - - QualType ElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, ElTy)) - return true; - - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, 1)) - return true; - - if (!Context.hasSameType(ElTy, TheCall->getArg(2)->getType())) - return true; - - return false; -} - -/// Check that the argument is a WebAssembly table. -bool Sema::BuiltinWasmTableSize(CallExpr *TheCall) { - if (checkArgCount(TheCall, 1)) - return true; - - QualType ElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, ElTy)) - return true; - - return false; -} - -/// Check that the first argument is a WebAssembly table, the second is the -/// value to use for new elements (of a type matching the table type), the -/// third value is an integer. -bool Sema::BuiltinWasmTableGrow(CallExpr *TheCall) { - if (checkArgCount(TheCall, 3)) - return true; - - QualType ElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, ElTy)) - return true; - - Expr *NewElemArg = TheCall->getArg(1); - if (!Context.hasSameType(ElTy, NewElemArg->getType())) { - return Diag(NewElemArg->getBeginLoc(), - diag::err_wasm_builtin_arg_must_match_table_element_type) - << 2 << 1 << NewElemArg->getSourceRange(); - } - - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, 2)) - return true; - - return false; -} - -/// Check that the first argument is a WebAssembly table, the second is an -/// integer, the third is the value to use to fill the table (of a type -/// matching the table type), and the fourth is an integer. -bool Sema::BuiltinWasmTableFill(CallExpr *TheCall) { - if (checkArgCount(TheCall, 4)) - return true; - - QualType ElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, ElTy)) - return true; - - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, 1)) - return true; - - Expr *NewElemArg = TheCall->getArg(2); - if (!Context.hasSameType(ElTy, NewElemArg->getType())) { - return Diag(NewElemArg->getBeginLoc(), - diag::err_wasm_builtin_arg_must_match_table_element_type) - << 3 << 1 << NewElemArg->getSourceRange(); - } - - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, 3)) - return true; - - return false; -} - -/// Check that the first argument is a WebAssembly table, the second is also a -/// WebAssembly table (of the same element type), and the third to fifth -/// arguments are integers. -bool Sema::BuiltinWasmTableCopy(CallExpr *TheCall) { - if (checkArgCount(TheCall, 5)) - return true; - - QualType XElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 0, XElTy)) - return true; - - QualType YElTy; - if (CheckWasmBuiltinArgIsTable(*this, TheCall, 1, YElTy)) - return true; - - Expr *TableYArg = TheCall->getArg(1); - if (!Context.hasSameType(XElTy, YElTy)) { - return Diag(TableYArg->getBeginLoc(), - diag::err_wasm_builtin_arg_must_match_table_element_type) - << 2 << 1 << TableYArg->getSourceRange(); - } - - for (int I = 2; I <= 4; I++) { - if (CheckWasmBuiltinArgIsInteger(*this, TheCall, I)) - return true; - } - - return false; -} - /// \brief Enforce the bounds of a TCB /// CheckTCBEnforcement - Enforces that every function in a named TCB only /// directly calls other functions in the same TCB as marked by the enforce_tcb diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e29ddd81a3f8..34e46e12859b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -50,7 +50,9 @@ #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaPPC.h" #include "clang/Sema/SemaRISCV.h" +#include "clang/Sema/SemaWasm.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" @@ -2929,9 +2931,9 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, else if (const auto *UA = dyn_cast(Attr)) NewAttr = S.mergeUuidAttr(D, *UA, UA->getGuid(), UA->getGuidDecl()); else if (const auto *IMA = dyn_cast(Attr)) - NewAttr = S.mergeImportModuleAttr(D, *IMA); + NewAttr = S.Wasm().mergeImportModuleAttr(D, *IMA); else if (const auto *INA = dyn_cast(Attr)) - NewAttr = S.mergeImportNameAttr(D, *INA); + NewAttr = S.Wasm().mergeImportNameAttr(D, *INA); else if (const auto *TCBA = dyn_cast(Attr)) NewAttr = S.mergeEnforceTCBAttr(D, *TCBA); else if (const auto *TCBLA = dyn_cast(Attr)) @@ -8895,7 +8897,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { // PPC MMA non-pointer types are not allowed as non-local variable types. if (Context.getTargetInfo().getTriple().isPPC64() && !NewVD->isLocalVarDecl() && - CheckPPCMMAType(T, NewVD->getLocation())) { + PPC().CheckPPCMMAType(T, NewVD->getLocation())) { NewVD->setInvalidDecl(); return; } @@ -12056,7 +12058,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // PPC MMA non-pointer types are not allowed as function return types. if (Context.getTargetInfo().getTriple().isPPC64() && - CheckPPCMMAType(NewFD->getReturnType(), NewFD->getLocation())) { + PPC().CheckPPCMMAType(NewFD->getReturnType(), NewFD->getLocation())) { NewFD->setInvalidDecl(); } @@ -15348,7 +15350,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, // PPC MMA non-pointer types are not allowed as function argument types. if (Context.getTargetInfo().getTriple().isPPC64() && - CheckPPCMMAType(New->getOriginalType(), New->getLocation())) { + PPC().CheckPPCMMAType(New->getOriginalType(), New->getLocation())) { New->setInvalidDecl(); } @@ -18763,7 +18765,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // PPC MMA non-pointer types are not allowed as field types. if (Context.getTargetInfo().getTriple().isPPC64() && - CheckPPCMMAType(T, NewFD->getLocation())) + PPC().CheckPPCMMAType(T, NewFD->getLocation())) NewFD->setInvalidDecl(); NewFD->setAccess(AS); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5041fd65286f..7c1fb23b9072 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -33,6 +33,7 @@ #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Attr.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Initialization.h" @@ -40,10 +41,12 @@ #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaAMDGPU.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" +#include "clang/Sema/SemaWasm.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/StringExtras.h" @@ -71,19 +74,6 @@ namespace AttributeLangSupport { // Helper functions //===----------------------------------------------------------------------===// -/// isFunctionOrMethod - Return true if the given decl has function -/// type (function or function-typed variable) or an Objective-C -/// method. -static bool isFunctionOrMethod(const Decl *D) { - return (D->getFunctionType() != nullptr) || isa(D); -} - -/// Return true if the given decl has function type (function or -/// function-typed variable) or an Objective-C method or a block. -static bool isFunctionOrMethodOrBlock(const Decl *D) { - return isFunctionOrMethod(D) || isa(D); -} - /// Return true if the given decl has a declarator that should have /// been processed by Sema::GetTypeForDeclarator. static bool hasDeclarator(const Decl *D) { @@ -94,7 +84,7 @@ static bool hasDeclarator(const Decl *D) { /// hasFunctionProto - Return true if the given decl has a argument /// information. This decl should have already passed -/// isFunctionOrMethod or isFunctionOrMethodOrBlock. +/// isFuncOrMethodForAttrSubject or isFunctionOrMethodOrBlockForAttrSubject. static bool hasFunctionProto(const Decl *D) { if (const FunctionType *FnTy = D->getFunctionType()) return isa(FnTy); @@ -207,52 +197,7 @@ static unsigned getNumAttributeArgs(const ParsedAttr &AL) { return AL.getNumArgs() + AL.hasParsedType(); } -/// A helper function to provide Attribute Location for the Attr types -/// AND the ParsedAttr. -template -static std::enable_if_t, SourceLocation> -getAttrLoc(const AttrInfo &AL) { - return AL.getLocation(); -} -static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); } - -/// If Expr is a valid integer constant, get the value of the integer -/// expression and return success or failure. May output an error. -/// -/// Negative argument is implicitly converted to unsigned, unless -/// \p StrictlyUnsigned is true. -template -static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr, - uint32_t &Val, unsigned Idx = UINT_MAX, - bool StrictlyUnsigned = false) { - std::optional I = llvm::APSInt(32); - if (Expr->isTypeDependent() || - !(I = Expr->getIntegerConstantExpr(S.Context))) { - if (Idx != UINT_MAX) - S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) - << &AI << Idx << AANT_ArgumentIntegerConstant - << Expr->getSourceRange(); - else - S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type) - << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange(); - return false; - } - - if (!I->isIntN(32)) { - S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) - << toString(*I, 10, false) << 32 << /* Unsigned */ 1; - return false; - } - - if (StrictlyUnsigned && I->isSigned() && I->isNegative()) { - S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer) - << &AI << /*non-negative*/ 1; - return false; - } - - Val = (uint32_t)I->getZExtValue(); - return true; -} +SourceLocation Sema::getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); } /// Wrapper around checkUInt32Argument, with an extra check to be sure /// that the result will fit into a regular (signed) int. All args have the same @@ -261,7 +206,7 @@ template static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr, int &Val, unsigned Idx = UINT_MAX) { uint32_t UVal; - if (!checkUInt32Argument(S, AI, Expr, UVal, Idx)) + if (!S.checkUInt32Argument(AI, Expr, UVal, Idx)) return false; if (UVal > (uint32_t)std::numeric_limits::max()) { @@ -310,7 +255,7 @@ template static bool checkFunctionOrMethodParameterIndex( Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) { - assert(isFunctionOrMethodOrBlock(D)); + assert(isFunctionOrMethodOrBlockForAttrSubject(D)); // In C++ the implicit 'this' function parameter also counts. // Parameters are counted from one. @@ -323,7 +268,7 @@ static bool checkFunctionOrMethodParameterIndex( std::optional IdxInt; if (IdxExpr->isTypeDependent() || !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) { - S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) + S.Diag(S.getAttrLoc(AI), diag::err_attribute_argument_n_type) << &AI << AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange(); return false; @@ -331,13 +276,14 @@ static bool checkFunctionOrMethodParameterIndex( unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX); if (IdxSource < 1 || (!IV && IdxSource > NumParams)) { - S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) + S.Diag(S.getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) << &AI << AttrArgNum << IdxExpr->getSourceRange(); return false; } if (HasImplicitThisParam && !CanIndexImplicitThis) { if (IdxSource == 1) { - S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument) + S.Diag(S.getAttrLoc(AI), + diag::err_attribute_invalid_implicit_this_argument) << &AI << IdxExpr->getSourceRange(); return false; } @@ -845,7 +791,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) return; - assert(isFunctionOrMethod(D) && hasFunctionProto(D)); + assert(isFuncOrMethodForAttrSubject(D) && hasFunctionProto(D)); QualType RetTy = getFunctionOrMethodResultType(D); if (!RetTy->isPointerType()) { @@ -1100,7 +1046,7 @@ static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D, const Expr *IndexExpr = AL.getArgAsExpr(I); uint32_t Index; - if (!checkUInt32Argument(S, AL, IndexExpr, Index, I + 1, false)) + if (!S.checkUInt32Argument(AL, IndexExpr, Index, I + 1, false)) return; if (Index > DeclFD->getNumParams()) { @@ -1210,7 +1156,7 @@ static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *E = AL.getArgAsExpr(0); uint32_t Type; - if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1)) + if (!S.checkUInt32Argument(AL, E, Type, /*Idx=*/1)) return; // pass_object_size's argument is passed in as the second argument of @@ -2295,7 +2241,7 @@ static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // The checking path for 'noreturn' and 'analyzer_noreturn' are different // because 'analyzer_noreturn' does not impact the type. - if (!isFunctionOrMethodOrBlock(D)) { + if (!isFunctionOrMethodOrBlockForAttrSubject(D)) { ValueDecl *VD = dyn_cast(D); if (!VD || (!VD->getType()->isBlockPointerType() && !VD->getType()->isFunctionPointerType())) { @@ -2399,7 +2345,7 @@ static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } if (AL.getNumArgs() && - !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)) + !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) return; D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority)); @@ -2408,7 +2354,7 @@ static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { uint32_t priority = DestructorAttr::DefaultPriority; if (AL.getNumArgs() && - !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority)) + !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) return; D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority)); @@ -3297,8 +3243,8 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { uint32_t WGSize[3]; for (unsigned i = 0; i < 3; ++i) { const Expr *E = AL.getArgAsExpr(i); - if (!checkUInt32Argument(S, AL, E, WGSize[i], i, - /*StrictlyUnsigned=*/true)) + if (!S.checkUInt32Argument(AL, E, WGSize[i], i, + /*StrictlyUnsigned=*/true)) return; if (WGSize[i] == 0) { S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero) @@ -3321,7 +3267,7 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) { uint32_t SGSize; const Expr *E = AL.getArgAsExpr(0); - if (!checkUInt32Argument(S, AL, E, SGSize)) + if (!S.checkUInt32Argument(AL, E, SGSize)) return; if (SGSize == 0) { S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero) @@ -3790,7 +3736,7 @@ static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *E = AL.getArgAsExpr(0); uint32_t VecWidth; - if (!checkUInt32Argument(S, AL, E, VecWidth)) { + if (!S.checkUInt32Argument(AL, E, VecWidth)) { AL.setInvalid(); return; } @@ -4003,7 +3949,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *E = AL.getArgAsExpr(0); uint32_t prioritynum; - if (!checkUInt32Argument(S, AL, E, prioritynum)) { + if (!S.checkUInt32Argument(AL, E, prioritynum)) { AL.setInvalid(); return; } @@ -4102,7 +4048,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // checks for the 2nd argument Expr *IdxExpr = AL.getArgAsExpr(1); uint32_t Idx; - if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2)) + if (!S.checkUInt32Argument(AL, IdxExpr, Idx, 2)) return; if (Idx < 1 || Idx > NumArgs) { @@ -4139,7 +4085,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // check the 3rd argument Expr *FirstArgExpr = AL.getArgAsExpr(2); uint32_t FirstArg; - if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3)) + if (!S.checkUInt32Argument(AL, FirstArgExpr, FirstArg, 3)) return; // FirstArg == 0 is is always valid. @@ -4227,8 +4173,8 @@ static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) { Expr *IdxExpr = AL.getArgAsExpr(I); // If the expression is not parseable as an int32_t we have a problem. - if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1, - false)) { + if (!S.checkUInt32Argument(AL, IdxExpr, (uint32_t &)ArgIdx, I + 1, + false)) { S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) << AL << (I + 1) << IdxExpr->getSourceRange(); return; @@ -5727,7 +5673,7 @@ bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) { uint32_t NP; Expr *NumParamsExpr = AL.getArgAsExpr(0); - if (!checkUInt32Argument(*this, AL, NumParamsExpr, NP)) { + if (!checkUInt32Argument(AL, NumParamsExpr, NP)) { AL.setInvalid(); return true; } @@ -5923,14 +5869,14 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) { uint32_t Count = 0, Offset = 0; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true)) return; if (AL.getNumArgs() == 2) { Expr *Arg = AL.getArgAsExpr(1); - if (!checkUInt32Argument(S, AL, Arg, Offset, 1, true)) + if (!S.checkUInt32Argument(AL, Arg, Offset, 1, true)) return; if (Count < Offset) { - S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range) + S.Diag(S.getAttrLoc(AL), diag::err_attribute_argument_out_of_range) << &AL << 0 << Count << Arg->getBeginLoc(); return; } @@ -6776,7 +6722,7 @@ static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) { return; Expr *IdxExpr = AL.getArgAsExpr(1); - if (!checkUInt32Argument(S, AL, IdxExpr, ParamIdx)) + if (!S.checkUInt32Argument(AL, IdxExpr, ParamIdx)) return; break; } @@ -7278,7 +7224,7 @@ static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } uint32_t X; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), X)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), X)) return; if (X > 1024) { S.Diag(AL.getArgAsExpr(0)->getExprLoc(), @@ -7286,7 +7232,7 @@ static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } uint32_t Y; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(1), Y)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(1), Y)) return; if (Y > 1024) { S.Diag(AL.getArgAsExpr(1)->getExprLoc(), @@ -7294,7 +7240,7 @@ static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } uint32_t Z; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(2), Z)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(2), Z)) return; if (Z > ZMax) { S.Diag(AL.getArgAsExpr(2)->getExprLoc(), @@ -7348,10 +7294,10 @@ static void handleHLSLPackOffsetAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } uint32_t SubComponent; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), SubComponent)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), SubComponent)) return; uint32_t Component; - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(1), Component)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(1), Component)) return; QualType T = cast(D)->getType().getCanonicalType(); @@ -7602,7 +7548,7 @@ static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // MSP430 'interrupt' attribute is applied to // a function with no parameters and void return type. - if (!isFunctionOrMethod(D)) { + if (!isFuncOrMethodForAttrSubject(D)) { S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; return; @@ -7675,7 +7621,7 @@ static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // e) The attribute itself must either have no argument or one of the // valid interrupt types, see [MipsInterruptDocs]. - if (!isFunctionOrMethod(D)) { + if (!isFuncOrMethodForAttrSubject(D)) { S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; return; @@ -7748,7 +7694,8 @@ static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // c) Must take 1 or 2 arguments. // d) The 1st argument must be a pointer. // e) The 2nd argument (if any) must be an unsigned integer. - if (!isFunctionOrMethod(D) || !hasFunctionProto(D) || isInstanceMethod(D) || + if (!isFuncOrMethodForAttrSubject(D) || !hasFunctionProto(D) || + isInstanceMethod(D) || CXXMethodDecl::isStaticOverloadedOperator( cast(D)->getDeclName().getCXXOverloadedOperator())) { S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -7807,7 +7754,7 @@ static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!isFunctionOrMethod(D)) { + if (!isFuncOrMethodForAttrSubject(D)) { S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; return; @@ -7820,7 +7767,7 @@ static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!isFunctionOrMethod(D)) { + if (!isFuncOrMethodForAttrSubject(D)) { S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; return; @@ -7875,102 +7822,6 @@ BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) { return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag()); } -static void handleWebAssemblyExportNameAttr(Sema &S, Decl *D, - const ParsedAttr &AL) { - if (!isFunctionOrMethod(D)) { - S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) - << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; - return; - } - - auto *FD = cast(D); - if (FD->isThisDeclarationADefinition()) { - S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0; - return; - } - - StringRef Str; - SourceLocation ArgLoc; - if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) - return; - - D->addAttr(::new (S.Context) WebAssemblyExportNameAttr(S.Context, AL, Str)); - D->addAttr(UsedAttr::CreateImplicit(S.Context)); -} - -WebAssemblyImportModuleAttr * -Sema::mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL) { - auto *FD = cast(D); - - if (const auto *ExistingAttr = FD->getAttr()) { - if (ExistingAttr->getImportModule() == AL.getImportModule()) - return nullptr; - Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 0 - << ExistingAttr->getImportModule() << AL.getImportModule(); - Diag(AL.getLoc(), diag::note_previous_attribute); - return nullptr; - } - if (FD->hasBody()) { - Diag(AL.getLoc(), diag::warn_import_on_definition) << 0; - return nullptr; - } - return ::new (Context) WebAssemblyImportModuleAttr(Context, AL, - AL.getImportModule()); -} - -WebAssemblyImportNameAttr * -Sema::mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL) { - auto *FD = cast(D); - - if (const auto *ExistingAttr = FD->getAttr()) { - if (ExistingAttr->getImportName() == AL.getImportName()) - return nullptr; - Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) << 1 - << ExistingAttr->getImportName() << AL.getImportName(); - Diag(AL.getLoc(), diag::note_previous_attribute); - return nullptr; - } - if (FD->hasBody()) { - Diag(AL.getLoc(), diag::warn_import_on_definition) << 1; - return nullptr; - } - return ::new (Context) WebAssemblyImportNameAttr(Context, AL, - AL.getImportName()); -} - -static void -handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - auto *FD = cast(D); - - StringRef Str; - SourceLocation ArgLoc; - if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) - return; - if (FD->hasBody()) { - S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 0; - return; - } - - FD->addAttr(::new (S.Context) - WebAssemblyImportModuleAttr(S.Context, AL, Str)); -} - -static void -handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - auto *FD = cast(D); - - StringRef Str; - SourceLocation ArgLoc; - if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) - return; - if (FD->hasBody()) { - S.Diag(AL.getLoc(), diag::warn_import_on_definition) << 1; - return; - } - - FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(S.Context, AL, Str)); -} - static void handleRISCVInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // Warn about repeated attributes. @@ -8059,200 +7910,6 @@ static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } -static bool -checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, - const AMDGPUFlatWorkGroupSizeAttr &Attr) { - // Accept template arguments for now as they depend on something else. - // We'll get to check them when they eventually get instantiated. - if (MinExpr->isValueDependent() || MaxExpr->isValueDependent()) - return false; - - uint32_t Min = 0; - if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0)) - return true; - - uint32_t Max = 0; - if (!checkUInt32Argument(S, Attr, MaxExpr, Max, 1)) - return true; - - if (Min == 0 && Max != 0) { - S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) - << &Attr << 0; - return true; - } - if (Min > Max) { - S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) - << &Attr << 1; - return true; - } - - return false; -} - -AMDGPUFlatWorkGroupSizeAttr * -Sema::CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, - Expr *MinExpr, Expr *MaxExpr) { - AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr); - - if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr, MaxExpr, TmpAttr)) - return nullptr; - return ::new (Context) - AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr); -} - -void Sema::addAMDGPUFlatWorkGroupSizeAttr(Decl *D, - const AttributeCommonInfo &CI, - Expr *MinExpr, Expr *MaxExpr) { - if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr)) - D->addAttr(Attr); -} - -static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D, - const ParsedAttr &AL) { - Expr *MinExpr = AL.getArgAsExpr(0); - Expr *MaxExpr = AL.getArgAsExpr(1); - - S.addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr); -} - -static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr, - Expr *MaxExpr, - const AMDGPUWavesPerEUAttr &Attr) { - if (S.DiagnoseUnexpandedParameterPack(MinExpr) || - (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr))) - return true; - - // Accept template arguments for now as they depend on something else. - // We'll get to check them when they eventually get instantiated. - if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent())) - return false; - - uint32_t Min = 0; - if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0)) - return true; - - uint32_t Max = 0; - if (MaxExpr && !checkUInt32Argument(S, Attr, MaxExpr, Max, 1)) - return true; - - if (Min == 0 && Max != 0) { - S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) - << &Attr << 0; - return true; - } - if (Max != 0 && Min > Max) { - S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) - << &Attr << 1; - return true; - } - - return false; -} - -AMDGPUWavesPerEUAttr * -Sema::CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *MinExpr, - Expr *MaxExpr) { - AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr); - - if (checkAMDGPUWavesPerEUArguments(*this, MinExpr, MaxExpr, TmpAttr)) - return nullptr; - - return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr); -} - -void Sema::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *MinExpr, Expr *MaxExpr) { - if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr)) - D->addAttr(Attr); -} - -static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) - return; - - Expr *MinExpr = AL.getArgAsExpr(0); - Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; - - S.addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr); -} - -static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - uint32_t NumSGPR = 0; - Expr *NumSGPRExpr = AL.getArgAsExpr(0); - if (!checkUInt32Argument(S, AL, NumSGPRExpr, NumSGPR)) - return; - - D->addAttr(::new (S.Context) AMDGPUNumSGPRAttr(S.Context, AL, NumSGPR)); -} - -static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - uint32_t NumVGPR = 0; - Expr *NumVGPRExpr = AL.getArgAsExpr(0); - if (!checkUInt32Argument(S, AL, NumVGPRExpr, NumVGPR)) - return; - - D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR)); -} - -static bool -checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, - Expr *ZExpr, - const AMDGPUMaxNumWorkGroupsAttr &Attr) { - if (S.DiagnoseUnexpandedParameterPack(XExpr) || - (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) || - (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr))) - return true; - - // Accept template arguments for now as they depend on something else. - // We'll get to check them when they eventually get instantiated. - if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) || - (ZExpr && ZExpr->isValueDependent())) - return false; - - uint32_t NumWG = 0; - Expr *Exprs[3] = {XExpr, YExpr, ZExpr}; - for (int i = 0; i < 3; i++) { - if (Exprs[i]) { - if (!checkUInt32Argument(S, Attr, Exprs[i], NumWG, i, - /*StrictlyUnsigned=*/true)) - return true; - if (NumWG == 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) - << &Attr << Exprs[i]->getSourceRange(); - return true; - } - } - } - - return false; -} - -AMDGPUMaxNumWorkGroupsAttr * -Sema::CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, - Expr *XExpr, Expr *YExpr, Expr *ZExpr) { - AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr); - - if (checkAMDGPUMaxNumWorkGroupsArguments(*this, XExpr, YExpr, ZExpr, TmpAttr)) - return nullptr; - - return ::new (Context) - AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr); -} - -void Sema::addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, - Expr *XExpr, Expr *YExpr, - Expr *ZExpr) { - if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr)) - D->addAttr(Attr); -} - -static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D, - const ParsedAttr &AL) { - Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; - Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr; - S.addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr); -} - static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // If we try to apply it to a function pointer, don't warn, but don't @@ -8279,7 +7936,7 @@ static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) { uint32_t Version; Expr *VersionExpr = static_cast(AL.getArgAsExpr(0)); - if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version)) + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Version)) return; // TODO: Investigate what happens with the next major version of MSVC. @@ -9392,19 +9049,19 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleDLLAttr(S, D, AL); break; case ParsedAttr::AT_AMDGPUFlatWorkGroupSize: - handleAMDGPUFlatWorkGroupSizeAttr(S, D, AL); + S.AMDGPU().handleAMDGPUFlatWorkGroupSizeAttr(D, AL); break; case ParsedAttr::AT_AMDGPUWavesPerEU: - handleAMDGPUWavesPerEUAttr(S, D, AL); + S.AMDGPU().handleAMDGPUWavesPerEUAttr(D, AL); break; case ParsedAttr::AT_AMDGPUNumSGPR: - handleAMDGPUNumSGPRAttr(S, D, AL); + S.AMDGPU().handleAMDGPUNumSGPRAttr(D, AL); break; case ParsedAttr::AT_AMDGPUNumVGPR: - handleAMDGPUNumVGPRAttr(S, D, AL); + S.AMDGPU().handleAMDGPUNumVGPRAttr(D, AL); break; case ParsedAttr::AT_AMDGPUMaxNumWorkGroups: - handleAMDGPUMaxNumWorkGroupsAttr(S, D, AL); + S.AMDGPU().handleAMDGPUMaxNumWorkGroupsAttr(D, AL); break; case ParsedAttr::AT_AVRSignal: handleAVRSignalAttr(S, D, AL); @@ -9419,13 +9076,13 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, handleBTFDeclTagAttr(S, D, AL); break; case ParsedAttr::AT_WebAssemblyExportName: - handleWebAssemblyExportNameAttr(S, D, AL); + S.Wasm().handleWebAssemblyExportNameAttr(D, AL); break; case ParsedAttr::AT_WebAssemblyImportModule: - handleWebAssemblyImportModuleAttr(S, D, AL); + S.Wasm().handleWebAssemblyImportModuleAttr(D, AL); break; case ParsedAttr::AT_WebAssemblyImportName: - handleWebAssemblyImportNameAttr(S, D, AL); + S.Wasm().handleWebAssemblyImportNameAttr(D, AL); break; case ParsedAttr::AT_IBOutlet: handleIBOutlet(S, D, AL); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6d4379283f19..807453400abd 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -567,9 +567,8 @@ void SemaObjC::ActOnSuperClassOfClassInterface( if (TypoCorrection Corrected = SemaRef.CorrectTypo( DeclarationNameInfo(SuperName, SuperLoc), Sema::LookupOrdinaryName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::err_undef_superclass_suggest) - << SuperName << ClassName); + SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) + << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs(); } } @@ -1322,9 +1321,9 @@ void SemaObjC::FindProtocolDeclaration(bool WarnOnDeclarations, Sema::LookupObjCProtocolName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery); if ((PDecl = Corrected.getCorrectionDeclAs())) - SemaRef.diagnoseTypo( - Corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) - << Pair.first); + SemaRef.diagnoseTypo(Corrected, + PDiag(diag::err_undeclared_protocol_suggest) + << Pair.first); } if (!PDecl) { @@ -1703,9 +1702,9 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( if (corrected) { // Did we find a protocol? if (auto proto = corrected.getCorrectionDeclAs()) { - SemaRef.diagnoseTypo( - corrected, SemaRef.PDiag(diag::err_undeclared_protocol_suggest) - << identifiers[i]); + SemaRef.diagnoseTypo(corrected, + PDiag(diag::err_undeclared_protocol_suggest) + << identifiers[i]); lookupKind = Sema::LookupObjCProtocolName; protocols[i] = proto; ++numProtocolsResolved; @@ -1715,7 +1714,7 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find a type? if (auto typeDecl = corrected.getCorrectionDeclAs()) { SemaRef.diagnoseTypo(corrected, - SemaRef.PDiag(diag::err_unknown_typename_suggest) + PDiag(diag::err_unknown_typename_suggest) << identifiers[i]); lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = typeDecl; @@ -1725,10 +1724,9 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( // Did we find an Objective-C class? if (auto objcClass = corrected.getCorrectionDeclAs()) { - SemaRef.diagnoseTypo( - corrected, - SemaRef.PDiag(diag::err_unknown_type_or_class_name_suggest) - << identifiers[i] << true); + SemaRef.diagnoseTypo(corrected, + PDiag(diag::err_unknown_type_or_class_name_suggest) + << identifiers[i] << true); lookupKind = Sema::LookupOrdinaryName; typeDecls[i] = objcClass; ++numTypeDeclsResolved; @@ -2009,10 +2007,9 @@ ObjCImplementationDecl *SemaObjC::ActOnStartClassImplementation( // Suggest the (potentially) correct interface name. Don't provide a // code-modification hint or use the typo name for recovery, because // this is just a warning. The program may actually be correct. - SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::warn_undef_interface_suggest) - << ClassName, - /*ErrorRecovery*/ false); + SemaRef.diagnoseTypo( + Corrected, PDiag(diag::warn_undef_interface_suggest) << ClassName, + /*ErrorRecovery*/ false); } else { Diag(ClassLoc, diag::warn_undef_interface) << ClassName; } @@ -5439,8 +5436,7 @@ ObjCInterfaceDecl *SemaObjC::getObjCInterfaceDecl(const IdentifierInfo *&Id, if (TypoCorrection C = SemaRef.CorrectTypo( DeclarationNameInfo(Id, IdLoc), Sema::LookupOrdinaryName, SemaRef.TUScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo(C, SemaRef.PDiag(diag::err_undef_interface_suggest) - << Id); + SemaRef.diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs(); Id = IDecl->getIdentifier(); } @@ -5544,7 +5540,7 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor); SemaRef.CheckDestructorAccess( Field->getLocation(), Destructor, - SemaRef.PDiag(diag::err_access_dtor_ivar) + PDiag(diag::err_access_dtor_ivar) << Context.getBaseElementType(Field->getType())); } } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 6595abbcdda5..4487c618862c 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -42,6 +42,7 @@ #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" #include "clang/Sema/SemaObjC.h" +#include "clang/Sema/SemaPPC.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/APInt.h" @@ -931,7 +932,7 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, // PPC MMA non-pointer types are not allowed as throw expr types. if (Ex && Context.getTargetInfo().getTriple().isPPC64()) - CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc()); + PPC().CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc()); return new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope); diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 462ab2c952b6..9c423529c80e 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -2134,7 +2134,7 @@ ExprResult SemaObjC::HandleExprPropertyRefExpr( } } else { SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::err_property_not_found_suggest) + PDiag(diag::err_property_not_found_suggest) << MemberName << QualType(OPT, 0)); return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, TypoResult, MemberLoc, @@ -2369,15 +2369,15 @@ SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name, if (Corrected.isKeyword()) { // If we've found the keyword "super" (the only keyword that would be // returned by CorrectTypo), this is a send to super. - SemaRef.diagnoseTypo( - Corrected, SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest) + << Name); return ObjCSuperMessage; } else if (ObjCInterfaceDecl *Class = Corrected.getCorrectionDeclAs()) { // If we found a declaration, correct when it refers to an Objective-C // class. - SemaRef.diagnoseTypo( - Corrected, SemaRef.PDiag(diag::err_unknown_receiver_suggest) << Name); + SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest) + << Name); QualType T = Context.getObjCInterfaceType(Class); TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc); ReceiverType = SemaRef.CreateParsedType(T, TSInfo); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 6a12c417e2f3..9e614ae99f37 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -9,6 +9,9 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaHLSL.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/TargetInfo.h" @@ -16,6 +19,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TargetParser/Triple.h" #include @@ -290,3 +294,296 @@ void SemaHLSL::DiagnoseAttrStageMismatch( << A << HLSLShaderAttr::ConvertShaderTypeToStr(Stage) << (AllowedStages.size() != 1) << join(StageStrings, ", "); } + +namespace { + +/// This class implements HLSL availability diagnostics for default +/// and relaxed mode +/// +/// The goal of this diagnostic is to emit an error or warning when an +/// unavailable API is found in code that is reachable from the shader +/// entry function or from an exported function (when compiling a shader +/// library). +/// +/// This is done by traversing the AST of all shader entry point functions +/// and of all exported functions, and any functions that are refrenced +/// from this AST. In other words, any functions that are reachable from +/// the entry points. +class DiagnoseHLSLAvailability + : public RecursiveASTVisitor { + + Sema &SemaRef; + + // Stack of functions to be scaned + llvm::SmallVector DeclsToScan; + + // Tracks which environments functions have been scanned in. + // + // Maps FunctionDecl to an unsigned number that represents the set of shader + // environments the function has been scanned for. + // Since HLSLShaderAttr::ShaderType enum is generated from Attr.td and is + // defined without any assigned values, it is guaranteed to be numbered + // sequentially from 0 up and we can use it to 'index' individual bits + // in the set. + // The N'th bit in the set will be set if the function has been scanned + // in shader environment whose ShaderType integer value equals N. + // For example, if a function has been scanned in compute and pixel stage + // environment, the value will be 0x21 (100001 binary) because + // (int)HLSLShaderAttr::ShaderType::Pixel == 1 and + // (int)HLSLShaderAttr::ShaderType::Compute == 5. + // A FunctionDecl is mapped to 0 (or not included in the map) if it has not + // been scanned in any environment. + llvm::DenseMap ScannedDecls; + + // Do not access these directly, use the get/set methods below to make + // sure the values are in sync + llvm::Triple::EnvironmentType CurrentShaderEnvironment; + unsigned CurrentShaderStageBit; + + // True if scanning a function that was already scanned in a different + // shader stage context, and therefore we should not report issues that + // depend only on shader model version because they would be duplicate. + bool ReportOnlyShaderStageIssues; + + // Helper methods for dealing with current stage context / environment + void SetShaderStageContext(HLSLShaderAttr::ShaderType ShaderType) { + static_assert(sizeof(unsigned) >= 4); + assert((unsigned)ShaderType < 31); // 31 is reserved for "unknown" + + CurrentShaderEnvironment = HLSLShaderAttr::getTypeAsEnvironment(ShaderType); + CurrentShaderStageBit = (1 << ShaderType); + } + + void SetUnknownShaderStageContext() { + CurrentShaderEnvironment = llvm::Triple::UnknownEnvironment; + CurrentShaderStageBit = (1 << 31); + } + + llvm::Triple::EnvironmentType GetCurrentShaderEnvironment() const { + return CurrentShaderEnvironment; + } + + bool InUnknownShaderStageContext() const { + return CurrentShaderEnvironment == llvm::Triple::UnknownEnvironment; + } + + // Helper methods for dealing with shader stage bitmap + void AddToScannedFunctions(const FunctionDecl *FD) { + unsigned &ScannedStages = ScannedDecls.getOrInsertDefault(FD); + ScannedStages |= CurrentShaderStageBit; + } + + unsigned GetScannedStages(const FunctionDecl *FD) { + return ScannedDecls.getOrInsertDefault(FD); + } + + bool WasAlreadyScannedInCurrentStage(const FunctionDecl *FD) { + return WasAlreadyScannedInCurrentStage(GetScannedStages(FD)); + } + + bool WasAlreadyScannedInCurrentStage(unsigned ScannerStages) { + return ScannerStages & CurrentShaderStageBit; + } + + static bool NeverBeenScanned(unsigned ScannedStages) { + return ScannedStages == 0; + } + + // Scanning methods + void HandleFunctionOrMethodRef(FunctionDecl *FD, Expr *RefExpr); + void CheckDeclAvailability(NamedDecl *D, const AvailabilityAttr *AA, + SourceRange Range); + const AvailabilityAttr *FindAvailabilityAttr(const Decl *D); + bool HasMatchingEnvironmentOrNone(const AvailabilityAttr *AA); + +public: + DiagnoseHLSLAvailability(Sema &SemaRef) : SemaRef(SemaRef) {} + + // AST traversal methods + void RunOnTranslationUnit(const TranslationUnitDecl *TU); + void RunOnFunction(const FunctionDecl *FD); + + bool VisitDeclRefExpr(DeclRefExpr *DRE) { + FunctionDecl *FD = llvm::dyn_cast(DRE->getDecl()); + if (FD) + HandleFunctionOrMethodRef(FD, DRE); + return true; + } + + bool VisitMemberExpr(MemberExpr *ME) { + FunctionDecl *FD = llvm::dyn_cast(ME->getMemberDecl()); + if (FD) + HandleFunctionOrMethodRef(FD, ME); + return true; + } +}; + +void DiagnoseHLSLAvailability::HandleFunctionOrMethodRef(FunctionDecl *FD, + Expr *RefExpr) { + assert((isa(RefExpr) || isa(RefExpr)) && + "expected DeclRefExpr or MemberExpr"); + + // has a definition -> add to stack to be scanned + const FunctionDecl *FDWithBody = nullptr; + if (FD->hasBody(FDWithBody)) { + if (!WasAlreadyScannedInCurrentStage(FDWithBody)) + DeclsToScan.push_back(FDWithBody); + return; + } + + // no body -> diagnose availability + const AvailabilityAttr *AA = FindAvailabilityAttr(FD); + if (AA) + CheckDeclAvailability( + FD, AA, SourceRange(RefExpr->getBeginLoc(), RefExpr->getEndLoc())); +} + +void DiagnoseHLSLAvailability::RunOnTranslationUnit( + const TranslationUnitDecl *TU) { + // Iterate over all shader entry functions and library exports, and for those + // that have a body (definiton), run diag scan on each, setting appropriate + // shader environment context based on whether it is a shader entry function + // or an exported function. + for (auto &D : TU->decls()) { + const FunctionDecl *FD = llvm::dyn_cast(D); + if (!FD || !FD->isThisDeclarationADefinition()) + continue; + + // shader entry point + auto ShaderAttr = FD->getAttr(); + if (ShaderAttr) { + SetShaderStageContext(ShaderAttr->getType()); + RunOnFunction(FD); + continue; + } + // exported library function with definition + // FIXME: tracking issue #92073 +#if 0 + if (FD->getFormalLinkage() == Linkage::External) { + SetUnknownShaderStageContext(); + RunOnFunction(FD); + } +#endif + } +} + +void DiagnoseHLSLAvailability::RunOnFunction(const FunctionDecl *FD) { + assert(DeclsToScan.empty() && "DeclsToScan should be empty"); + DeclsToScan.push_back(FD); + + while (!DeclsToScan.empty()) { + // Take one decl from the stack and check it by traversing its AST. + // For any CallExpr found during the traversal add it's callee to the top of + // the stack to be processed next. Functions already processed are stored in + // ScannedDecls. + const FunctionDecl *FD = DeclsToScan.back(); + DeclsToScan.pop_back(); + + // Decl was already scanned + const unsigned ScannedStages = GetScannedStages(FD); + if (WasAlreadyScannedInCurrentStage(ScannedStages)) + continue; + + ReportOnlyShaderStageIssues = !NeverBeenScanned(ScannedStages); + + AddToScannedFunctions(FD); + TraverseStmt(FD->getBody()); + } +} + +bool DiagnoseHLSLAvailability::HasMatchingEnvironmentOrNone( + const AvailabilityAttr *AA) { + IdentifierInfo *IIEnvironment = AA->getEnvironment(); + if (!IIEnvironment) + return true; + + llvm::Triple::EnvironmentType CurrentEnv = GetCurrentShaderEnvironment(); + if (CurrentEnv == llvm::Triple::UnknownEnvironment) + return false; + + llvm::Triple::EnvironmentType AttrEnv = + AvailabilityAttr::getEnvironmentType(IIEnvironment->getName()); + + return CurrentEnv == AttrEnv; +} + +const AvailabilityAttr * +DiagnoseHLSLAvailability::FindAvailabilityAttr(const Decl *D) { + AvailabilityAttr const *PartialMatch = nullptr; + // Check each AvailabilityAttr to find the one for this platform. + // For multiple attributes with the same platform try to find one for this + // environment. + for (const auto *A : D->attrs()) { + if (const auto *Avail = dyn_cast(A)) { + StringRef AttrPlatform = Avail->getPlatform()->getName(); + StringRef TargetPlatform = + SemaRef.getASTContext().getTargetInfo().getPlatformName(); + + // Match the platform name. + if (AttrPlatform == TargetPlatform) { + // Find the best matching attribute for this environment + if (HasMatchingEnvironmentOrNone(Avail)) + return Avail; + PartialMatch = Avail; + } + } + } + return PartialMatch; +} + +// Check availability against target shader model version and current shader +// stage and emit diagnostic +void DiagnoseHLSLAvailability::CheckDeclAvailability(NamedDecl *D, + const AvailabilityAttr *AA, + SourceRange Range) { + if (ReportOnlyShaderStageIssues && !AA->getEnvironment()) + return; + + bool EnvironmentMatches = HasMatchingEnvironmentOrNone(AA); + VersionTuple Introduced = AA->getIntroduced(); + VersionTuple TargetVersion = + SemaRef.Context.getTargetInfo().getPlatformMinVersion(); + + if (TargetVersion >= Introduced && EnvironmentMatches) + return; + + // Do not diagnose shade-stage-specific availability when the shader stage + // context is unknown + if (InUnknownShaderStageContext() && AA->getEnvironment() != nullptr) + return; + + // Emit diagnostic message + const TargetInfo &TI = SemaRef.getASTContext().getTargetInfo(); + llvm::StringRef PlatformName( + AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName())); + + llvm::StringRef CurrentEnvStr = + AvailabilityAttr::getPrettyEnviromentName(GetCurrentShaderEnvironment()); + + llvm::StringRef AttrEnvStr = AA->getEnvironment() + ? AvailabilityAttr::getPrettyEnviromentName( + AvailabilityAttr::getEnvironmentType( + AA->getEnvironment()->getName())) + : ""; + bool UseEnvironment = !AttrEnvStr.empty(); + + if (EnvironmentMatches) { + SemaRef.Diag(Range.getBegin(), diag::warn_hlsl_availability) + << Range << D << PlatformName << Introduced.getAsString() + << UseEnvironment << CurrentEnvStr; + } else { + SemaRef.Diag(Range.getBegin(), diag::warn_hlsl_availability_unavailable) + << Range << D; + } + + SemaRef.Diag(D->getLocation(), diag::note_partial_availability_specified_here) + << D << PlatformName << Introduced.getAsString() + << SemaRef.Context.getTargetInfo().getPlatformMinVersion().getAsString() + << UseEnvironment << AttrEnvStr << CurrentEnvStr; +} + +} // namespace + +void SemaHLSL::DiagnoseAvailabilityViolations(TranslationUnitDecl *TU) { + DiagnoseHLSLAvailability(SemaRef).RunOnTranslationUnit(TU); +} diff --git a/clang/lib/Sema/SemaHexagon.cpp b/clang/lib/Sema/SemaHexagon.cpp new file mode 100644 index 000000000000..5c921c0bc9e3 --- /dev/null +++ b/clang/lib/Sema/SemaHexagon.cpp @@ -0,0 +1,290 @@ +//===------ SemaHexagon.cpp ------ Hexagon target-specific routines -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to Hexagon. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaHexagon.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/STLExtras.h" +#include +#include + +namespace clang { + +SemaHexagon::SemaHexagon(Sema &S) : SemaBase(S) {} + +bool SemaHexagon::CheckHexagonBuiltinArgument(unsigned BuiltinID, + CallExpr *TheCall) { + struct ArgInfo { + uint8_t OpNum; + bool IsSigned; + uint8_t BitWidth; + uint8_t Align; + }; + struct BuiltinInfo { + unsigned BuiltinID; + ArgInfo Infos[2]; + }; + + static BuiltinInfo Infos[] = { + { Hexagon::BI__builtin_circ_ldd, {{ 3, true, 4, 3 }} }, + { Hexagon::BI__builtin_circ_ldw, {{ 3, true, 4, 2 }} }, + { Hexagon::BI__builtin_circ_ldh, {{ 3, true, 4, 1 }} }, + { Hexagon::BI__builtin_circ_lduh, {{ 3, true, 4, 1 }} }, + { Hexagon::BI__builtin_circ_ldb, {{ 3, true, 4, 0 }} }, + { Hexagon::BI__builtin_circ_ldub, {{ 3, true, 4, 0 }} }, + { Hexagon::BI__builtin_circ_std, {{ 3, true, 4, 3 }} }, + { Hexagon::BI__builtin_circ_stw, {{ 3, true, 4, 2 }} }, + { Hexagon::BI__builtin_circ_sth, {{ 3, true, 4, 1 }} }, + { Hexagon::BI__builtin_circ_sthhi, {{ 3, true, 4, 1 }} }, + { Hexagon::BI__builtin_circ_stb, {{ 3, true, 4, 0 }} }, + + { Hexagon::BI__builtin_HEXAGON_L2_loadrub_pci, {{ 1, true, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_L2_loadrb_pci, {{ 1, true, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_L2_loadruh_pci, {{ 1, true, 4, 1 }} }, + { Hexagon::BI__builtin_HEXAGON_L2_loadrh_pci, {{ 1, true, 4, 1 }} }, + { Hexagon::BI__builtin_HEXAGON_L2_loadri_pci, {{ 1, true, 4, 2 }} }, + { Hexagon::BI__builtin_HEXAGON_L2_loadrd_pci, {{ 1, true, 4, 3 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_storerb_pci, {{ 1, true, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_storerh_pci, {{ 1, true, 4, 1 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_storerf_pci, {{ 1, true, 4, 1 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_storeri_pci, {{ 1, true, 4, 2 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_storerd_pci, {{ 1, true, 4, 3 }} }, + + { Hexagon::BI__builtin_HEXAGON_A2_combineii, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A2_tfrih, {{ 1, false, 16, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A2_tfril, {{ 1, false, 16, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A2_tfrpi, {{ 0, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_bitspliti, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_cmpbeqi, {{ 1, false, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_cmpbgti, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_cround_ri, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_round_ri, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_round_ri_sat, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpbeqi, {{ 1, false, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgti, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgtui, {{ 1, false, 7, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpheqi, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmphgti, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmphgtui, {{ 1, false, 7, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpweqi, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgti, {{ 1, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgtui, {{ 1, false, 7, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_C2_bitsclri, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_C2_muxii, {{ 2, true, 8, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_C4_nbitsclri, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_dfclass, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_dfimm_n, {{ 0, false, 10, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_dfimm_p, {{ 0, false, 10, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_sfclass, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_sfimm_n, {{ 0, false, 10, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_F2_sfimm_p, {{ 0, false, 10, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addi, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addr_u2, {{ 1, false, 6, 2 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_addasl_rrri, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_acc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_and, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_nac, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_or, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_xacc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_acc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_and, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_nac, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_or, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_sat, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_xacc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vh, {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vw, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_acc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_and, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_nac, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_or, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, + {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_acc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_and, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_nac, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_or, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, + {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_svw_trun, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vh, {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vw, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_clrbit_i, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_extractu, {{ 1, false, 5, 0 }, + { 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_extractup, {{ 1, false, 6, 0 }, + { 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_insert, {{ 2, false, 5, 0 }, + { 3, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_insertp, {{ 2, false, 6, 0 }, + { 3, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_acc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_and, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_nac, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_or, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_xacc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_acc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_and, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_nac, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_or, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_xacc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vh, {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vw, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_setbit_i, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_tableidxb_goodsyntax, + {{ 2, false, 4, 0 }, + { 3, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_tableidxd_goodsyntax, + {{ 2, false, 4, 0 }, + { 3, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_tableidxh_goodsyntax, + {{ 2, false, 4, 0 }, + { 3, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_tableidxw_goodsyntax, + {{ 2, false, 4, 0 }, + { 3, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_togglebit_i, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_tstbit_i, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_valignib, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S2_vspliceib, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_addi_asl_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_addi_lsr_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_andi_asl_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_andi_lsr_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_clbaddi, {{ 1, true , 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_clbpaddi, {{ 1, true, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_extract, {{ 1, false, 5, 0 }, + { 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_extractp, {{ 1, false, 6, 0 }, + { 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_lsli, {{ 0, true, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_ntstbit_i, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_ori_asl_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_ori_lsr_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_subi_asl_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_subi_lsr_ri, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate_acc, {{ 3, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate, {{ 2, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, + {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S5_asrhub_sat, {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, + {{ 1, false, 4, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, {{ 1, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, {{ 2, false, 6, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, {{ 1, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, {{ 2, false, 5, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_valignbi, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, {{ 3, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, + {{ 3, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, {{ 3, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, + {{ 3, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, {{ 2, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, {{ 3, false, 1, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, + {{ 3, false, 1, 0 }} }, + + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10, {{ 2, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_128B, + {{ 2, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_vxx, + {{ 3, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyhubs10_vxx_128B, + {{ 3, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10, {{ 2, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_128B, + {{ 2, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_vxx, + {{ 3, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_v6mpyvubs10_vxx_128B, + {{ 3, false, 2, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi_128B, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci, {{ 3, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci_128B, + {{ 3, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi_128B, {{ 2, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci, {{ 3, false, 3, 0 }} }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci_128B, + {{ 3, false, 3, 0 }} }, + }; + + // Use a dynamically initialized static to sort the table exactly once on + // first run. + static const bool SortOnce = + (llvm::sort(Infos, + [](const BuiltinInfo &LHS, const BuiltinInfo &RHS) { + return LHS.BuiltinID < RHS.BuiltinID; + }), + true); + (void)SortOnce; + + const BuiltinInfo *F = llvm::partition_point( + Infos, [=](const BuiltinInfo &BI) { return BI.BuiltinID < BuiltinID; }); + if (F == std::end(Infos) || F->BuiltinID != BuiltinID) + return false; + + bool Error = false; + + for (const ArgInfo &A : F->Infos) { + // Ignore empty ArgInfo elements. + if (A.BitWidth == 0) + continue; + + int32_t Min = A.IsSigned ? -(1 << (A.BitWidth - 1)) : 0; + int32_t Max = (1 << (A.IsSigned ? A.BitWidth - 1 : A.BitWidth)) - 1; + if (!A.Align) { + Error |= SemaRef.BuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); + } else { + unsigned M = 1 << A.Align; + Min *= M; + Max *= M; + Error |= SemaRef.BuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); + Error |= SemaRef.BuiltinConstantArgMultiple(TheCall, A.OpNum, M); + } + } + return Error; +} + +bool SemaHexagon::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + return CheckHexagonBuiltinArgument(BuiltinID, TheCall); +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaLoongArch.cpp b/clang/lib/Sema/SemaLoongArch.cpp new file mode 100644 index 000000000000..0a67bf2c7738 --- /dev/null +++ b/clang/lib/Sema/SemaLoongArch.cpp @@ -0,0 +1,515 @@ +//===------ SemaLoongArch.cpp ---- LoongArch target-specific routines -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to LoongArch. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaLoongArch.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/Support/MathExtras.h" + +namespace clang { + +SemaLoongArch::SemaLoongArch(Sema &S) : SemaBase(S) {} + +bool SemaLoongArch::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + switch (BuiltinID) { + default: + break; + // Basic intrinsics. + case LoongArch::BI__builtin_loongarch_cacop_d: + case LoongArch::BI__builtin_loongarch_cacop_w: { + SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, llvm::maxUIntN(5)); + SemaRef.BuiltinConstantArgRange(TheCall, 2, llvm::minIntN(12), + llvm::maxIntN(12)); + break; + } + case LoongArch::BI__builtin_loongarch_break: + case LoongArch::BI__builtin_loongarch_dbar: + case LoongArch::BI__builtin_loongarch_ibar: + case LoongArch::BI__builtin_loongarch_syscall: + // Check if immediate is in [0, 32767]. + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 32767); + case LoongArch::BI__builtin_loongarch_csrrd_w: + case LoongArch::BI__builtin_loongarch_csrrd_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 16383); + case LoongArch::BI__builtin_loongarch_csrwr_w: + case LoongArch::BI__builtin_loongarch_csrwr_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 16383); + case LoongArch::BI__builtin_loongarch_csrxchg_w: + case LoongArch::BI__builtin_loongarch_csrxchg_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 16383); + case LoongArch::BI__builtin_loongarch_lddir_d: + case LoongArch::BI__builtin_loongarch_ldpte_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case LoongArch::BI__builtin_loongarch_movfcsr2gr: + case LoongArch::BI__builtin_loongarch_movgr2fcsr: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, llvm::maxUIntN(2)); + + // LSX intrinsics. + case LoongArch::BI__builtin_lsx_vbitclri_b: + case LoongArch::BI__builtin_lsx_vbitrevi_b: + case LoongArch::BI__builtin_lsx_vbitseti_b: + case LoongArch::BI__builtin_lsx_vsat_b: + case LoongArch::BI__builtin_lsx_vsat_bu: + case LoongArch::BI__builtin_lsx_vslli_b: + case LoongArch::BI__builtin_lsx_vsrai_b: + case LoongArch::BI__builtin_lsx_vsrari_b: + case LoongArch::BI__builtin_lsx_vsrli_b: + case LoongArch::BI__builtin_lsx_vsllwil_h_b: + case LoongArch::BI__builtin_lsx_vsllwil_hu_bu: + case LoongArch::BI__builtin_lsx_vrotri_b: + case LoongArch::BI__builtin_lsx_vsrlri_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 7); + case LoongArch::BI__builtin_lsx_vbitclri_h: + case LoongArch::BI__builtin_lsx_vbitrevi_h: + case LoongArch::BI__builtin_lsx_vbitseti_h: + case LoongArch::BI__builtin_lsx_vsat_h: + case LoongArch::BI__builtin_lsx_vsat_hu: + case LoongArch::BI__builtin_lsx_vslli_h: + case LoongArch::BI__builtin_lsx_vsrai_h: + case LoongArch::BI__builtin_lsx_vsrari_h: + case LoongArch::BI__builtin_lsx_vsrli_h: + case LoongArch::BI__builtin_lsx_vsllwil_w_h: + case LoongArch::BI__builtin_lsx_vsllwil_wu_hu: + case LoongArch::BI__builtin_lsx_vrotri_h: + case LoongArch::BI__builtin_lsx_vsrlri_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case LoongArch::BI__builtin_lsx_vssrarni_b_h: + case LoongArch::BI__builtin_lsx_vssrarni_bu_h: + case LoongArch::BI__builtin_lsx_vssrani_b_h: + case LoongArch::BI__builtin_lsx_vssrani_bu_h: + case LoongArch::BI__builtin_lsx_vsrarni_b_h: + case LoongArch::BI__builtin_lsx_vsrlni_b_h: + case LoongArch::BI__builtin_lsx_vsrlrni_b_h: + case LoongArch::BI__builtin_lsx_vssrlni_b_h: + case LoongArch::BI__builtin_lsx_vssrlni_bu_h: + case LoongArch::BI__builtin_lsx_vssrlrni_b_h: + case LoongArch::BI__builtin_lsx_vssrlrni_bu_h: + case LoongArch::BI__builtin_lsx_vsrani_b_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); + case LoongArch::BI__builtin_lsx_vslei_bu: + case LoongArch::BI__builtin_lsx_vslei_hu: + case LoongArch::BI__builtin_lsx_vslei_wu: + case LoongArch::BI__builtin_lsx_vslei_du: + case LoongArch::BI__builtin_lsx_vslti_bu: + case LoongArch::BI__builtin_lsx_vslti_hu: + case LoongArch::BI__builtin_lsx_vslti_wu: + case LoongArch::BI__builtin_lsx_vslti_du: + case LoongArch::BI__builtin_lsx_vmaxi_bu: + case LoongArch::BI__builtin_lsx_vmaxi_hu: + case LoongArch::BI__builtin_lsx_vmaxi_wu: + case LoongArch::BI__builtin_lsx_vmaxi_du: + case LoongArch::BI__builtin_lsx_vmini_bu: + case LoongArch::BI__builtin_lsx_vmini_hu: + case LoongArch::BI__builtin_lsx_vmini_wu: + case LoongArch::BI__builtin_lsx_vmini_du: + case LoongArch::BI__builtin_lsx_vaddi_bu: + case LoongArch::BI__builtin_lsx_vaddi_hu: + case LoongArch::BI__builtin_lsx_vaddi_wu: + case LoongArch::BI__builtin_lsx_vaddi_du: + case LoongArch::BI__builtin_lsx_vbitclri_w: + case LoongArch::BI__builtin_lsx_vbitrevi_w: + case LoongArch::BI__builtin_lsx_vbitseti_w: + case LoongArch::BI__builtin_lsx_vsat_w: + case LoongArch::BI__builtin_lsx_vsat_wu: + case LoongArch::BI__builtin_lsx_vslli_w: + case LoongArch::BI__builtin_lsx_vsrai_w: + case LoongArch::BI__builtin_lsx_vsrari_w: + case LoongArch::BI__builtin_lsx_vsrli_w: + case LoongArch::BI__builtin_lsx_vsllwil_d_w: + case LoongArch::BI__builtin_lsx_vsllwil_du_wu: + case LoongArch::BI__builtin_lsx_vsrlri_w: + case LoongArch::BI__builtin_lsx_vrotri_w: + case LoongArch::BI__builtin_lsx_vsubi_bu: + case LoongArch::BI__builtin_lsx_vsubi_hu: + case LoongArch::BI__builtin_lsx_vbsrl_v: + case LoongArch::BI__builtin_lsx_vbsll_v: + case LoongArch::BI__builtin_lsx_vsubi_wu: + case LoongArch::BI__builtin_lsx_vsubi_du: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case LoongArch::BI__builtin_lsx_vssrarni_h_w: + case LoongArch::BI__builtin_lsx_vssrarni_hu_w: + case LoongArch::BI__builtin_lsx_vssrani_h_w: + case LoongArch::BI__builtin_lsx_vssrani_hu_w: + case LoongArch::BI__builtin_lsx_vsrarni_h_w: + case LoongArch::BI__builtin_lsx_vsrani_h_w: + case LoongArch::BI__builtin_lsx_vfrstpi_b: + case LoongArch::BI__builtin_lsx_vfrstpi_h: + case LoongArch::BI__builtin_lsx_vsrlni_h_w: + case LoongArch::BI__builtin_lsx_vsrlrni_h_w: + case LoongArch::BI__builtin_lsx_vssrlni_h_w: + case LoongArch::BI__builtin_lsx_vssrlni_hu_w: + case LoongArch::BI__builtin_lsx_vssrlrni_h_w: + case LoongArch::BI__builtin_lsx_vssrlrni_hu_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); + case LoongArch::BI__builtin_lsx_vbitclri_d: + case LoongArch::BI__builtin_lsx_vbitrevi_d: + case LoongArch::BI__builtin_lsx_vbitseti_d: + case LoongArch::BI__builtin_lsx_vsat_d: + case LoongArch::BI__builtin_lsx_vsat_du: + case LoongArch::BI__builtin_lsx_vslli_d: + case LoongArch::BI__builtin_lsx_vsrai_d: + case LoongArch::BI__builtin_lsx_vsrli_d: + case LoongArch::BI__builtin_lsx_vsrari_d: + case LoongArch::BI__builtin_lsx_vrotri_d: + case LoongArch::BI__builtin_lsx_vsrlri_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 63); + case LoongArch::BI__builtin_lsx_vssrarni_w_d: + case LoongArch::BI__builtin_lsx_vssrarni_wu_d: + case LoongArch::BI__builtin_lsx_vssrani_w_d: + case LoongArch::BI__builtin_lsx_vssrani_wu_d: + case LoongArch::BI__builtin_lsx_vsrarni_w_d: + case LoongArch::BI__builtin_lsx_vsrlni_w_d: + case LoongArch::BI__builtin_lsx_vsrlrni_w_d: + case LoongArch::BI__builtin_lsx_vssrlni_w_d: + case LoongArch::BI__builtin_lsx_vssrlni_wu_d: + case LoongArch::BI__builtin_lsx_vssrlrni_w_d: + case LoongArch::BI__builtin_lsx_vssrlrni_wu_d: + case LoongArch::BI__builtin_lsx_vsrani_w_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63); + case LoongArch::BI__builtin_lsx_vssrarni_d_q: + case LoongArch::BI__builtin_lsx_vssrarni_du_q: + case LoongArch::BI__builtin_lsx_vssrani_d_q: + case LoongArch::BI__builtin_lsx_vssrani_du_q: + case LoongArch::BI__builtin_lsx_vsrarni_d_q: + case LoongArch::BI__builtin_lsx_vssrlni_d_q: + case LoongArch::BI__builtin_lsx_vssrlni_du_q: + case LoongArch::BI__builtin_lsx_vssrlrni_d_q: + case LoongArch::BI__builtin_lsx_vssrlrni_du_q: + case LoongArch::BI__builtin_lsx_vsrani_d_q: + case LoongArch::BI__builtin_lsx_vsrlrni_d_q: + case LoongArch::BI__builtin_lsx_vsrlni_d_q: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 127); + case LoongArch::BI__builtin_lsx_vseqi_b: + case LoongArch::BI__builtin_lsx_vseqi_h: + case LoongArch::BI__builtin_lsx_vseqi_w: + case LoongArch::BI__builtin_lsx_vseqi_d: + case LoongArch::BI__builtin_lsx_vslti_b: + case LoongArch::BI__builtin_lsx_vslti_h: + case LoongArch::BI__builtin_lsx_vslti_w: + case LoongArch::BI__builtin_lsx_vslti_d: + case LoongArch::BI__builtin_lsx_vslei_b: + case LoongArch::BI__builtin_lsx_vslei_h: + case LoongArch::BI__builtin_lsx_vslei_w: + case LoongArch::BI__builtin_lsx_vslei_d: + case LoongArch::BI__builtin_lsx_vmaxi_b: + case LoongArch::BI__builtin_lsx_vmaxi_h: + case LoongArch::BI__builtin_lsx_vmaxi_w: + case LoongArch::BI__builtin_lsx_vmaxi_d: + case LoongArch::BI__builtin_lsx_vmini_b: + case LoongArch::BI__builtin_lsx_vmini_h: + case LoongArch::BI__builtin_lsx_vmini_w: + case LoongArch::BI__builtin_lsx_vmini_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -16, 15); + case LoongArch::BI__builtin_lsx_vandi_b: + case LoongArch::BI__builtin_lsx_vnori_b: + case LoongArch::BI__builtin_lsx_vori_b: + case LoongArch::BI__builtin_lsx_vshuf4i_b: + case LoongArch::BI__builtin_lsx_vshuf4i_h: + case LoongArch::BI__builtin_lsx_vshuf4i_w: + case LoongArch::BI__builtin_lsx_vxori_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 255); + case LoongArch::BI__builtin_lsx_vbitseli_b: + case LoongArch::BI__builtin_lsx_vshuf4i_d: + case LoongArch::BI__builtin_lsx_vextrins_b: + case LoongArch::BI__builtin_lsx_vextrins_h: + case LoongArch::BI__builtin_lsx_vextrins_w: + case LoongArch::BI__builtin_lsx_vextrins_d: + case LoongArch::BI__builtin_lsx_vpermi_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 255); + case LoongArch::BI__builtin_lsx_vpickve2gr_b: + case LoongArch::BI__builtin_lsx_vpickve2gr_bu: + case LoongArch::BI__builtin_lsx_vreplvei_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case LoongArch::BI__builtin_lsx_vinsgr2vr_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); + case LoongArch::BI__builtin_lsx_vpickve2gr_h: + case LoongArch::BI__builtin_lsx_vpickve2gr_hu: + case LoongArch::BI__builtin_lsx_vreplvei_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 7); + case LoongArch::BI__builtin_lsx_vinsgr2vr_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); + case LoongArch::BI__builtin_lsx_vpickve2gr_w: + case LoongArch::BI__builtin_lsx_vpickve2gr_wu: + case LoongArch::BI__builtin_lsx_vreplvei_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3); + case LoongArch::BI__builtin_lsx_vinsgr2vr_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); + case LoongArch::BI__builtin_lsx_vpickve2gr_d: + case LoongArch::BI__builtin_lsx_vpickve2gr_du: + case LoongArch::BI__builtin_lsx_vreplvei_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); + case LoongArch::BI__builtin_lsx_vinsgr2vr_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1); + case LoongArch::BI__builtin_lsx_vstelm_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -128, 127) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 15); + case LoongArch::BI__builtin_lsx_vstelm_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -256, 254) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7); + case LoongArch::BI__builtin_lsx_vstelm_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -512, 508) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 3); + case LoongArch::BI__builtin_lsx_vstelm_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -1024, 1016) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 1); + case LoongArch::BI__builtin_lsx_vldrepl_b: + case LoongArch::BI__builtin_lsx_vld: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2047); + case LoongArch::BI__builtin_lsx_vldrepl_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2046); + case LoongArch::BI__builtin_lsx_vldrepl_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2044); + case LoongArch::BI__builtin_lsx_vldrepl_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2040); + case LoongArch::BI__builtin_lsx_vst: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -2048, 2047); + case LoongArch::BI__builtin_lsx_vldi: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, -4096, 4095); + case LoongArch::BI__builtin_lsx_vrepli_b: + case LoongArch::BI__builtin_lsx_vrepli_h: + case LoongArch::BI__builtin_lsx_vrepli_w: + case LoongArch::BI__builtin_lsx_vrepli_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, -512, 511); + + // LASX intrinsics. + case LoongArch::BI__builtin_lasx_xvbitclri_b: + case LoongArch::BI__builtin_lasx_xvbitrevi_b: + case LoongArch::BI__builtin_lasx_xvbitseti_b: + case LoongArch::BI__builtin_lasx_xvsat_b: + case LoongArch::BI__builtin_lasx_xvsat_bu: + case LoongArch::BI__builtin_lasx_xvslli_b: + case LoongArch::BI__builtin_lasx_xvsrai_b: + case LoongArch::BI__builtin_lasx_xvsrari_b: + case LoongArch::BI__builtin_lasx_xvsrli_b: + case LoongArch::BI__builtin_lasx_xvsllwil_h_b: + case LoongArch::BI__builtin_lasx_xvsllwil_hu_bu: + case LoongArch::BI__builtin_lasx_xvrotri_b: + case LoongArch::BI__builtin_lasx_xvsrlri_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 7); + case LoongArch::BI__builtin_lasx_xvbitclri_h: + case LoongArch::BI__builtin_lasx_xvbitrevi_h: + case LoongArch::BI__builtin_lasx_xvbitseti_h: + case LoongArch::BI__builtin_lasx_xvsat_h: + case LoongArch::BI__builtin_lasx_xvsat_hu: + case LoongArch::BI__builtin_lasx_xvslli_h: + case LoongArch::BI__builtin_lasx_xvsrai_h: + case LoongArch::BI__builtin_lasx_xvsrari_h: + case LoongArch::BI__builtin_lasx_xvsrli_h: + case LoongArch::BI__builtin_lasx_xvsllwil_w_h: + case LoongArch::BI__builtin_lasx_xvsllwil_wu_hu: + case LoongArch::BI__builtin_lasx_xvrotri_h: + case LoongArch::BI__builtin_lasx_xvsrlri_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case LoongArch::BI__builtin_lasx_xvssrarni_b_h: + case LoongArch::BI__builtin_lasx_xvssrarni_bu_h: + case LoongArch::BI__builtin_lasx_xvssrani_b_h: + case LoongArch::BI__builtin_lasx_xvssrani_bu_h: + case LoongArch::BI__builtin_lasx_xvsrarni_b_h: + case LoongArch::BI__builtin_lasx_xvsrlni_b_h: + case LoongArch::BI__builtin_lasx_xvsrlrni_b_h: + case LoongArch::BI__builtin_lasx_xvssrlni_b_h: + case LoongArch::BI__builtin_lasx_xvssrlni_bu_h: + case LoongArch::BI__builtin_lasx_xvssrlrni_b_h: + case LoongArch::BI__builtin_lasx_xvssrlrni_bu_h: + case LoongArch::BI__builtin_lasx_xvsrani_b_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); + case LoongArch::BI__builtin_lasx_xvslei_bu: + case LoongArch::BI__builtin_lasx_xvslei_hu: + case LoongArch::BI__builtin_lasx_xvslei_wu: + case LoongArch::BI__builtin_lasx_xvslei_du: + case LoongArch::BI__builtin_lasx_xvslti_bu: + case LoongArch::BI__builtin_lasx_xvslti_hu: + case LoongArch::BI__builtin_lasx_xvslti_wu: + case LoongArch::BI__builtin_lasx_xvslti_du: + case LoongArch::BI__builtin_lasx_xvmaxi_bu: + case LoongArch::BI__builtin_lasx_xvmaxi_hu: + case LoongArch::BI__builtin_lasx_xvmaxi_wu: + case LoongArch::BI__builtin_lasx_xvmaxi_du: + case LoongArch::BI__builtin_lasx_xvmini_bu: + case LoongArch::BI__builtin_lasx_xvmini_hu: + case LoongArch::BI__builtin_lasx_xvmini_wu: + case LoongArch::BI__builtin_lasx_xvmini_du: + case LoongArch::BI__builtin_lasx_xvaddi_bu: + case LoongArch::BI__builtin_lasx_xvaddi_hu: + case LoongArch::BI__builtin_lasx_xvaddi_wu: + case LoongArch::BI__builtin_lasx_xvaddi_du: + case LoongArch::BI__builtin_lasx_xvbitclri_w: + case LoongArch::BI__builtin_lasx_xvbitrevi_w: + case LoongArch::BI__builtin_lasx_xvbitseti_w: + case LoongArch::BI__builtin_lasx_xvsat_w: + case LoongArch::BI__builtin_lasx_xvsat_wu: + case LoongArch::BI__builtin_lasx_xvslli_w: + case LoongArch::BI__builtin_lasx_xvsrai_w: + case LoongArch::BI__builtin_lasx_xvsrari_w: + case LoongArch::BI__builtin_lasx_xvsrli_w: + case LoongArch::BI__builtin_lasx_xvsllwil_d_w: + case LoongArch::BI__builtin_lasx_xvsllwil_du_wu: + case LoongArch::BI__builtin_lasx_xvsrlri_w: + case LoongArch::BI__builtin_lasx_xvrotri_w: + case LoongArch::BI__builtin_lasx_xvsubi_bu: + case LoongArch::BI__builtin_lasx_xvsubi_hu: + case LoongArch::BI__builtin_lasx_xvsubi_wu: + case LoongArch::BI__builtin_lasx_xvsubi_du: + case LoongArch::BI__builtin_lasx_xvbsrl_v: + case LoongArch::BI__builtin_lasx_xvbsll_v: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case LoongArch::BI__builtin_lasx_xvssrarni_h_w: + case LoongArch::BI__builtin_lasx_xvssrarni_hu_w: + case LoongArch::BI__builtin_lasx_xvssrani_h_w: + case LoongArch::BI__builtin_lasx_xvssrani_hu_w: + case LoongArch::BI__builtin_lasx_xvsrarni_h_w: + case LoongArch::BI__builtin_lasx_xvsrani_h_w: + case LoongArch::BI__builtin_lasx_xvfrstpi_b: + case LoongArch::BI__builtin_lasx_xvfrstpi_h: + case LoongArch::BI__builtin_lasx_xvsrlni_h_w: + case LoongArch::BI__builtin_lasx_xvsrlrni_h_w: + case LoongArch::BI__builtin_lasx_xvssrlni_h_w: + case LoongArch::BI__builtin_lasx_xvssrlni_hu_w: + case LoongArch::BI__builtin_lasx_xvssrlrni_h_w: + case LoongArch::BI__builtin_lasx_xvssrlrni_hu_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); + case LoongArch::BI__builtin_lasx_xvbitclri_d: + case LoongArch::BI__builtin_lasx_xvbitrevi_d: + case LoongArch::BI__builtin_lasx_xvbitseti_d: + case LoongArch::BI__builtin_lasx_xvsat_d: + case LoongArch::BI__builtin_lasx_xvsat_du: + case LoongArch::BI__builtin_lasx_xvslli_d: + case LoongArch::BI__builtin_lasx_xvsrai_d: + case LoongArch::BI__builtin_lasx_xvsrli_d: + case LoongArch::BI__builtin_lasx_xvsrari_d: + case LoongArch::BI__builtin_lasx_xvrotri_d: + case LoongArch::BI__builtin_lasx_xvsrlri_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 63); + case LoongArch::BI__builtin_lasx_xvssrarni_w_d: + case LoongArch::BI__builtin_lasx_xvssrarni_wu_d: + case LoongArch::BI__builtin_lasx_xvssrani_w_d: + case LoongArch::BI__builtin_lasx_xvssrani_wu_d: + case LoongArch::BI__builtin_lasx_xvsrarni_w_d: + case LoongArch::BI__builtin_lasx_xvsrlni_w_d: + case LoongArch::BI__builtin_lasx_xvsrlrni_w_d: + case LoongArch::BI__builtin_lasx_xvssrlni_w_d: + case LoongArch::BI__builtin_lasx_xvssrlni_wu_d: + case LoongArch::BI__builtin_lasx_xvssrlrni_w_d: + case LoongArch::BI__builtin_lasx_xvssrlrni_wu_d: + case LoongArch::BI__builtin_lasx_xvsrani_w_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63); + case LoongArch::BI__builtin_lasx_xvssrarni_d_q: + case LoongArch::BI__builtin_lasx_xvssrarni_du_q: + case LoongArch::BI__builtin_lasx_xvssrani_d_q: + case LoongArch::BI__builtin_lasx_xvssrani_du_q: + case LoongArch::BI__builtin_lasx_xvsrarni_d_q: + case LoongArch::BI__builtin_lasx_xvssrlni_d_q: + case LoongArch::BI__builtin_lasx_xvssrlni_du_q: + case LoongArch::BI__builtin_lasx_xvssrlrni_d_q: + case LoongArch::BI__builtin_lasx_xvssrlrni_du_q: + case LoongArch::BI__builtin_lasx_xvsrani_d_q: + case LoongArch::BI__builtin_lasx_xvsrlni_d_q: + case LoongArch::BI__builtin_lasx_xvsrlrni_d_q: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 127); + case LoongArch::BI__builtin_lasx_xvseqi_b: + case LoongArch::BI__builtin_lasx_xvseqi_h: + case LoongArch::BI__builtin_lasx_xvseqi_w: + case LoongArch::BI__builtin_lasx_xvseqi_d: + case LoongArch::BI__builtin_lasx_xvslti_b: + case LoongArch::BI__builtin_lasx_xvslti_h: + case LoongArch::BI__builtin_lasx_xvslti_w: + case LoongArch::BI__builtin_lasx_xvslti_d: + case LoongArch::BI__builtin_lasx_xvslei_b: + case LoongArch::BI__builtin_lasx_xvslei_h: + case LoongArch::BI__builtin_lasx_xvslei_w: + case LoongArch::BI__builtin_lasx_xvslei_d: + case LoongArch::BI__builtin_lasx_xvmaxi_b: + case LoongArch::BI__builtin_lasx_xvmaxi_h: + case LoongArch::BI__builtin_lasx_xvmaxi_w: + case LoongArch::BI__builtin_lasx_xvmaxi_d: + case LoongArch::BI__builtin_lasx_xvmini_b: + case LoongArch::BI__builtin_lasx_xvmini_h: + case LoongArch::BI__builtin_lasx_xvmini_w: + case LoongArch::BI__builtin_lasx_xvmini_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -16, 15); + case LoongArch::BI__builtin_lasx_xvandi_b: + case LoongArch::BI__builtin_lasx_xvnori_b: + case LoongArch::BI__builtin_lasx_xvori_b: + case LoongArch::BI__builtin_lasx_xvshuf4i_b: + case LoongArch::BI__builtin_lasx_xvshuf4i_h: + case LoongArch::BI__builtin_lasx_xvshuf4i_w: + case LoongArch::BI__builtin_lasx_xvxori_b: + case LoongArch::BI__builtin_lasx_xvpermi_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 255); + case LoongArch::BI__builtin_lasx_xvbitseli_b: + case LoongArch::BI__builtin_lasx_xvshuf4i_d: + case LoongArch::BI__builtin_lasx_xvextrins_b: + case LoongArch::BI__builtin_lasx_xvextrins_h: + case LoongArch::BI__builtin_lasx_xvextrins_w: + case LoongArch::BI__builtin_lasx_xvextrins_d: + case LoongArch::BI__builtin_lasx_xvpermi_q: + case LoongArch::BI__builtin_lasx_xvpermi_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 255); + case LoongArch::BI__builtin_lasx_xvrepl128vei_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case LoongArch::BI__builtin_lasx_xvrepl128vei_h: + case LoongArch::BI__builtin_lasx_xvpickve2gr_w: + case LoongArch::BI__builtin_lasx_xvpickve2gr_wu: + case LoongArch::BI__builtin_lasx_xvpickve_w_f: + case LoongArch::BI__builtin_lasx_xvpickve_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 7); + case LoongArch::BI__builtin_lasx_xvinsgr2vr_w: + case LoongArch::BI__builtin_lasx_xvinsve0_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); + case LoongArch::BI__builtin_lasx_xvrepl128vei_w: + case LoongArch::BI__builtin_lasx_xvpickve2gr_d: + case LoongArch::BI__builtin_lasx_xvpickve2gr_du: + case LoongArch::BI__builtin_lasx_xvpickve_d_f: + case LoongArch::BI__builtin_lasx_xvpickve_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3); + case LoongArch::BI__builtin_lasx_xvinsve0_d: + case LoongArch::BI__builtin_lasx_xvinsgr2vr_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); + case LoongArch::BI__builtin_lasx_xvstelm_b: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -128, 127) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 31); + case LoongArch::BI__builtin_lasx_xvstelm_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -256, 254) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 15); + case LoongArch::BI__builtin_lasx_xvstelm_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -512, 508) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7); + case LoongArch::BI__builtin_lasx_xvstelm_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -1024, 1016) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 3); + case LoongArch::BI__builtin_lasx_xvrepl128vei_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); + case LoongArch::BI__builtin_lasx_xvldrepl_b: + case LoongArch::BI__builtin_lasx_xvld: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2047); + case LoongArch::BI__builtin_lasx_xvldrepl_h: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2046); + case LoongArch::BI__builtin_lasx_xvldrepl_w: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2044); + case LoongArch::BI__builtin_lasx_xvldrepl_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, -2048, 2040); + case LoongArch::BI__builtin_lasx_xvst: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, -2048, 2047); + case LoongArch::BI__builtin_lasx_xvldi: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, -4096, 4095); + case LoongArch::BI__builtin_lasx_xvrepli_b: + case LoongArch::BI__builtin_lasx_xvrepli_h: + case LoongArch::BI__builtin_lasx_xvrepli_w: + case LoongArch::BI__builtin_lasx_xvrepli_d: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, -512, 511); + } + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaMIPS.cpp b/clang/lib/Sema/SemaMIPS.cpp new file mode 100644 index 000000000000..df5328fbf664 --- /dev/null +++ b/clang/lib/Sema/SemaMIPS.cpp @@ -0,0 +1,240 @@ +//===------ SemaMIPS.cpp -------- MIPS target-specific routines -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to MIPS. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaMIPS.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" + +namespace clang { + +SemaMIPS::SemaMIPS(Sema &S) : SemaBase(S) {} + +bool SemaMIPS::CheckMipsBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) || + CheckMipsBuiltinArgument(BuiltinID, TheCall); +} + +bool SemaMIPS::CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall) { + + if (Mips::BI__builtin_mips_addu_qb <= BuiltinID && + BuiltinID <= Mips::BI__builtin_mips_lwx) { + if (!TI.hasFeature("dsp")) + return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp); + } + + if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID && + BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) { + if (!TI.hasFeature("dspr2")) + return Diag(TheCall->getBeginLoc(), + diag::err_mips_builtin_requires_dspr2); + } + + if (Mips::BI__builtin_msa_add_a_b <= BuiltinID && + BuiltinID <= Mips::BI__builtin_msa_xori_b) { + if (!TI.hasFeature("msa")) + return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa); + } + + return false; +} + +// CheckMipsBuiltinArgument - Checks the constant value passed to the +// intrinsic is correct. The switch statement is ordered by DSP, MSA. The +// ordering for DSP is unspecified. MSA is ordered by the data format used +// by the underlying instruction i.e., df/m, df/n and then by size. +// +// FIXME: The size tests here should instead be tablegen'd along with the +// definitions from include/clang/Basic/BuiltinsMips.def. +// FIXME: GCC is strict on signedness for some of these intrinsics, we should +// be too. +bool SemaMIPS::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { + unsigned i = 0, l = 0, u = 0, m = 0; + switch (BuiltinID) { + default: return false; + case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; + case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; + case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break; + case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break; + case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; + case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; + case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; + // MSA intrinsics. Instructions (which the intrinsics maps to) which use the + // df/m field. + // These intrinsics take an unsigned 3 bit immediate. + case Mips::BI__builtin_msa_bclri_b: + case Mips::BI__builtin_msa_bnegi_b: + case Mips::BI__builtin_msa_bseti_b: + case Mips::BI__builtin_msa_sat_s_b: + case Mips::BI__builtin_msa_sat_u_b: + case Mips::BI__builtin_msa_slli_b: + case Mips::BI__builtin_msa_srai_b: + case Mips::BI__builtin_msa_srari_b: + case Mips::BI__builtin_msa_srli_b: + case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; + case Mips::BI__builtin_msa_binsli_b: + case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; + // These intrinsics take an unsigned 4 bit immediate. + case Mips::BI__builtin_msa_bclri_h: + case Mips::BI__builtin_msa_bnegi_h: + case Mips::BI__builtin_msa_bseti_h: + case Mips::BI__builtin_msa_sat_s_h: + case Mips::BI__builtin_msa_sat_u_h: + case Mips::BI__builtin_msa_slli_h: + case Mips::BI__builtin_msa_srai_h: + case Mips::BI__builtin_msa_srari_h: + case Mips::BI__builtin_msa_srli_h: + case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; + case Mips::BI__builtin_msa_binsli_h: + case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; + // These intrinsics take an unsigned 5 bit immediate. + // The first block of intrinsics actually have an unsigned 5 bit field, + // not a df/n field. + case Mips::BI__builtin_msa_cfcmsa: + case Mips::BI__builtin_msa_ctcmsa: i = 0; l = 0; u = 31; break; + case Mips::BI__builtin_msa_clei_u_b: + case Mips::BI__builtin_msa_clei_u_h: + case Mips::BI__builtin_msa_clei_u_w: + case Mips::BI__builtin_msa_clei_u_d: + case Mips::BI__builtin_msa_clti_u_b: + case Mips::BI__builtin_msa_clti_u_h: + case Mips::BI__builtin_msa_clti_u_w: + case Mips::BI__builtin_msa_clti_u_d: + case Mips::BI__builtin_msa_maxi_u_b: + case Mips::BI__builtin_msa_maxi_u_h: + case Mips::BI__builtin_msa_maxi_u_w: + case Mips::BI__builtin_msa_maxi_u_d: + case Mips::BI__builtin_msa_mini_u_b: + case Mips::BI__builtin_msa_mini_u_h: + case Mips::BI__builtin_msa_mini_u_w: + case Mips::BI__builtin_msa_mini_u_d: + case Mips::BI__builtin_msa_addvi_b: + case Mips::BI__builtin_msa_addvi_h: + case Mips::BI__builtin_msa_addvi_w: + case Mips::BI__builtin_msa_addvi_d: + case Mips::BI__builtin_msa_bclri_w: + case Mips::BI__builtin_msa_bnegi_w: + case Mips::BI__builtin_msa_bseti_w: + case Mips::BI__builtin_msa_sat_s_w: + case Mips::BI__builtin_msa_sat_u_w: + case Mips::BI__builtin_msa_slli_w: + case Mips::BI__builtin_msa_srai_w: + case Mips::BI__builtin_msa_srari_w: + case Mips::BI__builtin_msa_srli_w: + case Mips::BI__builtin_msa_srlri_w: + case Mips::BI__builtin_msa_subvi_b: + case Mips::BI__builtin_msa_subvi_h: + case Mips::BI__builtin_msa_subvi_w: + case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; + case Mips::BI__builtin_msa_binsli_w: + case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; + // These intrinsics take an unsigned 6 bit immediate. + case Mips::BI__builtin_msa_bclri_d: + case Mips::BI__builtin_msa_bnegi_d: + case Mips::BI__builtin_msa_bseti_d: + case Mips::BI__builtin_msa_sat_s_d: + case Mips::BI__builtin_msa_sat_u_d: + case Mips::BI__builtin_msa_slli_d: + case Mips::BI__builtin_msa_srai_d: + case Mips::BI__builtin_msa_srari_d: + case Mips::BI__builtin_msa_srli_d: + case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; + case Mips::BI__builtin_msa_binsli_d: + case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; + // These intrinsics take a signed 5 bit immediate. + case Mips::BI__builtin_msa_ceqi_b: + case Mips::BI__builtin_msa_ceqi_h: + case Mips::BI__builtin_msa_ceqi_w: + case Mips::BI__builtin_msa_ceqi_d: + case Mips::BI__builtin_msa_clti_s_b: + case Mips::BI__builtin_msa_clti_s_h: + case Mips::BI__builtin_msa_clti_s_w: + case Mips::BI__builtin_msa_clti_s_d: + case Mips::BI__builtin_msa_clei_s_b: + case Mips::BI__builtin_msa_clei_s_h: + case Mips::BI__builtin_msa_clei_s_w: + case Mips::BI__builtin_msa_clei_s_d: + case Mips::BI__builtin_msa_maxi_s_b: + case Mips::BI__builtin_msa_maxi_s_h: + case Mips::BI__builtin_msa_maxi_s_w: + case Mips::BI__builtin_msa_maxi_s_d: + case Mips::BI__builtin_msa_mini_s_b: + case Mips::BI__builtin_msa_mini_s_h: + case Mips::BI__builtin_msa_mini_s_w: + case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; + // These intrinsics take an unsigned 8 bit immediate. + case Mips::BI__builtin_msa_andi_b: + case Mips::BI__builtin_msa_nori_b: + case Mips::BI__builtin_msa_ori_b: + case Mips::BI__builtin_msa_shf_b: + case Mips::BI__builtin_msa_shf_h: + case Mips::BI__builtin_msa_shf_w: + case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; + case Mips::BI__builtin_msa_bseli_b: + case Mips::BI__builtin_msa_bmnzi_b: + case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; + // df/n format + // These intrinsics take an unsigned 4 bit immediate. + case Mips::BI__builtin_msa_copy_s_b: + case Mips::BI__builtin_msa_copy_u_b: + case Mips::BI__builtin_msa_insve_b: + case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; + case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; + // These intrinsics take an unsigned 3 bit immediate. + case Mips::BI__builtin_msa_copy_s_h: + case Mips::BI__builtin_msa_copy_u_h: + case Mips::BI__builtin_msa_insve_h: + case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; + case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; + // These intrinsics take an unsigned 2 bit immediate. + case Mips::BI__builtin_msa_copy_s_w: + case Mips::BI__builtin_msa_copy_u_w: + case Mips::BI__builtin_msa_insve_w: + case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; + case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; + // These intrinsics take an unsigned 1 bit immediate. + case Mips::BI__builtin_msa_copy_s_d: + case Mips::BI__builtin_msa_copy_u_d: + case Mips::BI__builtin_msa_insve_d: + case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; + case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; + // Memory offsets and immediate loads. + // These intrinsics take a signed 10 bit immediate. + case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; + case Mips::BI__builtin_msa_ldi_h: + case Mips::BI__builtin_msa_ldi_w: + case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; + case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; + case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; + case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; + case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; + case Mips::BI__builtin_msa_ldr_d: i = 1; l = -4096; u = 4088; m = 8; break; + case Mips::BI__builtin_msa_ldr_w: i = 1; l = -2048; u = 2044; m = 4; break; + case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; + case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; + case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; + case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; + case Mips::BI__builtin_msa_str_d: i = 2; l = -4096; u = 4088; m = 8; break; + case Mips::BI__builtin_msa_str_w: i = 2; l = -2048; u = 2044; m = 4; break; + } + + if (!m) + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u); + + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u) || + SemaRef.BuiltinConstantArgMultiple(TheCall, i, m); +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaNVPTX.cpp b/clang/lib/Sema/SemaNVPTX.cpp new file mode 100644 index 000000000000..cc8941071463 --- /dev/null +++ b/clang/lib/Sema/SemaNVPTX.cpp @@ -0,0 +1,35 @@ +//===------ SemaNVPTX.cpp ------- NVPTX target-specific routines ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to NVPTX. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaNVPTX.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" + +namespace clang { + +SemaNVPTX::SemaNVPTX(Sema &S) : SemaBase(S) {} + +bool SemaNVPTX::CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + switch (BuiltinID) { + case NVPTX::BI__nvvm_cp_async_ca_shared_global_4: + case NVPTX::BI__nvvm_cp_async_ca_shared_global_8: + case NVPTX::BI__nvvm_cp_async_ca_shared_global_16: + case NVPTX::BI__nvvm_cp_async_cg_shared_global_16: + return SemaRef.checkArgCountAtMost(TheCall, 3); + } + + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 15239f4f35c3..5b4d01860c0b 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -170,6 +170,57 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, default: return false; } + case OpenACCClauseKind::CopyIn: + case OpenACCClauseKind::PCopyIn: + case OpenACCClauseKind::PresentOrCopyIn: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::Declare: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + case OpenACCClauseKind::CopyOut: + case OpenACCClauseKind::PCopyOut: + case OpenACCClauseKind::PresentOrCopyOut: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::ExitData: + case OpenACCDirectiveKind::Declare: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + case OpenACCClauseKind::Create: + case OpenACCClauseKind::PCreate: + case OpenACCClauseKind::PresentOrCreate: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + case OpenACCClauseKind::Attach: switch (DirectiveKind) { case OpenACCDirectiveKind::Parallel: @@ -246,6 +297,27 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, return false; } + case OpenACCClauseKind::DeviceType: + case OpenACCClauseKind::DType: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::Init: + case OpenACCDirectiveKind::Shutdown: + case OpenACCDirectiveKind::Set: + case OpenACCDirectiveKind::Update: + case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::Routine: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + default: // Do nothing so we can go to the 'unimplemented' diagnostic instead. return true; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index bab61e8fd54e..99528c2a4f1f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3074,11 +3074,11 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (TypoCorrection Corrected = SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { - SemaRef.diagnoseTypo( - Corrected, - SemaRef.PDiag(Lookup.empty() ? diag::err_undeclared_var_use_suggest - : diag::err_omp_expected_var_arg_suggest) - << Id.getName()); + SemaRef.diagnoseTypo(Corrected, + PDiag(Lookup.empty() + ? diag::err_undeclared_var_use_suggest + : diag::err_omp_expected_var_arg_suggest) + << Id.getName()); VD = Corrected.getCorrectionDeclAs(); } else { Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use @@ -7402,7 +7402,7 @@ void SemaOpenMP::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( // Template specialization is an extension, check if we do it. bool IsTemplated = !TemplateParamLists.empty(); - if (IsTemplated & + if (IsTemplated && !DVScope.TI->isExtensionActive( llvm::omp::TraitProperty::implementation_extension_allow_templates)) return; @@ -7915,9 +7915,9 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG, PartialDiagnostic::NullDiagnostic()), PartialDiagnosticAt( VariantRef->getExprLoc(), - SemaRef.PDiag(diag::err_omp_declare_variant_doesnt_support)), + PDiag(diag::err_omp_declare_variant_doesnt_support)), PartialDiagnosticAt(VariantRef->getExprLoc(), - SemaRef.PDiag(diag::err_omp_declare_variant_diff) + PDiag(diag::err_omp_declare_variant_diff) << FD->getLocation()), /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, /*CLinkageMayDiffer=*/true)) @@ -23695,7 +23695,7 @@ NamedDecl *SemaOpenMP::lookupOpenMPDeclareTargetName( SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr, CCC, Sema::CTK_ErrorRecovery)) { SemaRef.diagnoseTypo(Corrected, - SemaRef.PDiag(diag::err_undeclared_var_use_suggest) + PDiag(diag::err_undeclared_var_use_suggest) << Id.getName()); checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); return nullptr; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6c5e8afbcfb6..6c4ce1022ae2 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10367,7 +10367,7 @@ static bool sameFunctionParameterTypeLists(Sema &S, FunctionDecl *Fn1 = Cand1.Function; FunctionDecl *Fn2 = Cand2.Function; - if (Fn1->isVariadic() != Fn1->isVariadic()) + if (Fn1->isVariadic() != Fn2->isVariadic()) return false; if (!S.FunctionNonObjectParamTypesAreEqual( diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp new file mode 100644 index 000000000000..99f46b12e696 --- /dev/null +++ b/clang/lib/Sema/SemaPPC.cpp @@ -0,0 +1,439 @@ +//===------ SemaPPC.cpp ------ PowerPC target-specific routines -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to PowerPC. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaPPC.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/APSInt.h" + +namespace clang { + +SemaPPC::SemaPPC(Sema &S) : SemaBase(S) {} + +void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) { + const auto *ICE = dyn_cast(Arg->IgnoreParens()); + if (!ICE) + return; + + const auto *DR = dyn_cast(ICE->getSubExpr()); + if (!DR) + return; + + const auto *PD = dyn_cast(DR->getDecl()); + if (!PD || !PD->getType()->isRecordType()) + return; + + QualType ArgType = Arg->getType(); + for (const FieldDecl *FD : + ArgType->castAs()->getDecl()->fields()) { + if (const auto *AA = FD->getAttr()) { + CharUnits Alignment = getASTContext().toCharUnitsFromBits( + AA->getAlignment(getASTContext())); + if (Alignment.getQuantity() == 16) { + Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD; + Diag(Loc, diag::note_misaligned_member_used_here) << PD; + } + } + } +} + +static bool isPPC_64Builtin(unsigned BuiltinID) { + // These builtins only work on PPC 64bit targets. + switch (BuiltinID) { + case PPC::BI__builtin_divde: + case PPC::BI__builtin_divdeu: + case PPC::BI__builtin_bpermd: + case PPC::BI__builtin_pdepd: + case PPC::BI__builtin_pextd: + case PPC::BI__builtin_ppc_ldarx: + case PPC::BI__builtin_ppc_stdcx: + case PPC::BI__builtin_ppc_tdw: + case PPC::BI__builtin_ppc_trapd: + case PPC::BI__builtin_ppc_cmpeqb: + case PPC::BI__builtin_ppc_setb: + case PPC::BI__builtin_ppc_mulhd: + case PPC::BI__builtin_ppc_mulhdu: + case PPC::BI__builtin_ppc_maddhd: + case PPC::BI__builtin_ppc_maddhdu: + case PPC::BI__builtin_ppc_maddld: + case PPC::BI__builtin_ppc_load8r: + case PPC::BI__builtin_ppc_store8r: + case PPC::BI__builtin_ppc_insert_exp: + case PPC::BI__builtin_ppc_extract_sig: + case PPC::BI__builtin_ppc_addex: + case PPC::BI__builtin_darn: + case PPC::BI__builtin_darn_raw: + case PPC::BI__builtin_ppc_compare_and_swaplp: + case PPC::BI__builtin_ppc_fetch_and_addlp: + case PPC::BI__builtin_ppc_fetch_and_andlp: + case PPC::BI__builtin_ppc_fetch_and_orlp: + case PPC::BI__builtin_ppc_fetch_and_swaplp: + return true; + } + return false; +} + +bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + ASTContext &Context = getASTContext(); + unsigned i = 0, l = 0, u = 0; + bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; + llvm::APSInt Result; + + if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit) + return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) + << TheCall->getSourceRange(); + + switch (BuiltinID) { + default: + return false; + case PPC::BI__builtin_altivec_crypto_vshasigmaw: + case PPC::BI__builtin_altivec_crypto_vshasigmad: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); + case PPC::BI__builtin_altivec_dss: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3); + case PPC::BI__builtin_tbegin: + case PPC::BI__builtin_tend: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1); + case PPC::BI__builtin_tsr: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7); + case PPC::BI__builtin_tabortwc: + case PPC::BI__builtin_tabortdc: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31); + case PPC::BI__builtin_tabortwci: + case PPC::BI__builtin_tabortdci: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); + // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05', + // __builtin_(un)pack_longdouble are available only if long double uses IBM + // extended double representation. + case PPC::BI__builtin_unpack_longdouble: + if (SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1)) + return true; + [[fallthrough]]; + case PPC::BI__builtin_pack_longdouble: + if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble()) + return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi) + << "ibmlongdouble"; + return false; + case PPC::BI__builtin_altivec_dst: + case PPC::BI__builtin_altivec_dstt: + case PPC::BI__builtin_altivec_dstst: + case PPC::BI__builtin_altivec_dststt: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); + case PPC::BI__builtin_vsx_xxpermdi: + case PPC::BI__builtin_vsx_xxsldwi: + return BuiltinVSX(TheCall); + case PPC::BI__builtin_unpack_vector_int128: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); + case PPC::BI__builtin_altivec_vgnb: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 2, 7); + case PPC::BI__builtin_vsx_xxeval: + return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 255); + case PPC::BI__builtin_altivec_vsldbi: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); + case PPC::BI__builtin_altivec_vsrdbi: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); + case PPC::BI__builtin_vsx_xxpermx: + return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7); + case PPC::BI__builtin_ppc_tw: + case PPC::BI__builtin_ppc_tdw: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 31); + case PPC::BI__builtin_ppc_cmprb: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1); + // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must + // be a constant that represents a contiguous bit field. + case PPC::BI__builtin_ppc_rlwnm: + return SemaRef.ValueIsRunOfOnes(TheCall, 2); + case PPC::BI__builtin_ppc_rlwimi: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) || + SemaRef.ValueIsRunOfOnes(TheCall, 3); + case PPC::BI__builtin_ppc_rldimi: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63) || + SemaRef.ValueIsRunOfOnes(TheCall, 3); + case PPC::BI__builtin_ppc_addex: { + if (SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3)) + return true; + // Output warning for reserved values 1 to 3. + int ArgValue = + TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue(); + if (ArgValue != 0) + Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour) + << ArgValue; + return false; + } + case PPC::BI__builtin_ppc_mtfsb0: + case PPC::BI__builtin_ppc_mtfsb1: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31); + case PPC::BI__builtin_ppc_mtfsf: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 255); + case PPC::BI__builtin_ppc_mtfsfi: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); + case PPC::BI__builtin_ppc_alignx: + return SemaRef.BuiltinConstantArgPower2(TheCall, 0); + case PPC::BI__builtin_ppc_rdlam: + return SemaRef.ValueIsRunOfOnes(TheCall, 2); + case PPC::BI__builtin_vsx_ldrmb: + case PPC::BI__builtin_vsx_strmb: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16); + case PPC::BI__builtin_altivec_vcntmbb: + case PPC::BI__builtin_altivec_vcntmbh: + case PPC::BI__builtin_altivec_vcntmbw: + case PPC::BI__builtin_altivec_vcntmbd: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); + case PPC::BI__builtin_vsx_xxgenpcvbm: + case PPC::BI__builtin_vsx_xxgenpcvhm: + case PPC::BI__builtin_vsx_xxgenpcvwm: + case PPC::BI__builtin_vsx_xxgenpcvdm: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3); + case PPC::BI__builtin_ppc_test_data_class: { + // Check if the first argument of the __builtin_ppc_test_data_class call is + // valid. The argument must be 'float' or 'double' or '__float128'. + QualType ArgType = TheCall->getArg(0)->getType(); + if (ArgType != QualType(Context.FloatTy) && + ArgType != QualType(Context.DoubleTy) && + ArgType != QualType(Context.Float128Ty)) + return Diag(TheCall->getBeginLoc(), + diag::err_ppc_invalid_test_data_class_type); + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 127); + } + case PPC::BI__builtin_ppc_maxfe: + case PPC::BI__builtin_ppc_minfe: + case PPC::BI__builtin_ppc_maxfl: + case PPC::BI__builtin_ppc_minfl: + case PPC::BI__builtin_ppc_maxfs: + case PPC::BI__builtin_ppc_minfs: { + if (Context.getTargetInfo().getTriple().isOSAIX() && + (BuiltinID == PPC::BI__builtin_ppc_maxfe || + BuiltinID == PPC::BI__builtin_ppc_minfe)) + return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type) + << "builtin" << true << 128 << QualType(Context.LongDoubleTy) + << false << Context.getTargetInfo().getTriple().str(); + // Argument type should be exact. + QualType ArgType = QualType(Context.LongDoubleTy); + if (BuiltinID == PPC::BI__builtin_ppc_maxfl || + BuiltinID == PPC::BI__builtin_ppc_minfl) + ArgType = QualType(Context.DoubleTy); + else if (BuiltinID == PPC::BI__builtin_ppc_maxfs || + BuiltinID == PPC::BI__builtin_ppc_minfs) + ArgType = QualType(Context.FloatTy); + for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I) + if (TheCall->getArg(I)->getType() != ArgType) + return Diag(TheCall->getBeginLoc(), + diag::err_typecheck_convert_incompatible) + << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0; + return false; + } +#define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \ + case PPC::BI__builtin_##Name: \ + return BuiltinPPCMMACall(TheCall, BuiltinID, Types); +#include "clang/Basic/BuiltinsPPC.def" + } + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u); +} + +// Check if the given type is a non-pointer PPC MMA type. This function is used +// in Sema to prevent invalid uses of restricted PPC MMA types. +bool SemaPPC::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { + ASTContext &Context = getASTContext(); + if (Type->isPointerType() || Type->isArrayType()) + return false; + + QualType CoreType = Type.getCanonicalType().getUnqualifiedType(); +#define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty + if (false +#include "clang/Basic/PPCTypes.def" + ) { + Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type); + return true; + } + return false; +} + +/// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str, +/// advancing the pointer over the consumed characters. The decoded type is +/// returned. If the decoded type represents a constant integer with a +/// constraint on its value then Mask is set to that value. The type descriptors +/// used in Str are specific to PPC MMA builtins and are documented in the file +/// defining the PPC builtins. +static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str, + unsigned &Mask) { + bool RequireICE = false; + ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None; + switch (*Str++) { + case 'V': + return Context.getVectorType(Context.UnsignedCharTy, 16, + VectorKind::AltiVecVector); + case 'i': { + char *End; + unsigned size = strtoul(Str, &End, 10); + assert(End != Str && "Missing constant parameter constraint"); + Str = End; + Mask = size; + return Context.IntTy; + } + case 'W': { + char *End; + unsigned size = strtoul(Str, &End, 10); + assert(End != Str && "Missing PowerPC MMA type size"); + Str = End; + QualType Type; + switch (size) { +#define PPC_VECTOR_TYPE(typeName, Id, size) \ + case size: \ + Type = Context.Id##Ty; \ + break; +#include "clang/Basic/PPCTypes.def" + default: + llvm_unreachable("Invalid PowerPC MMA vector type"); + } + bool CheckVectorArgs = false; + while (!CheckVectorArgs) { + switch (*Str++) { + case '*': + Type = Context.getPointerType(Type); + break; + case 'C': + Type = Type.withConst(); + break; + default: + CheckVectorArgs = true; + --Str; + break; + } + } + return Type; + } + default: + return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true); + } +} + +bool SemaPPC::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, + const char *TypeStr) { + + assert((TypeStr[0] != '\0') && + "Invalid types in PPC MMA builtin declaration"); + + ASTContext &Context = getASTContext(); + unsigned Mask = 0; + unsigned ArgNum = 0; + + // The first type in TypeStr is the type of the value returned by the + // builtin. So we first read that type and change the type of TheCall. + QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); + TheCall->setType(type); + + while (*TypeStr != '\0') { + Mask = 0; + QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); + if (ArgNum >= TheCall->getNumArgs()) { + ArgNum++; + break; + } + + Expr *Arg = TheCall->getArg(ArgNum); + QualType PassedType = Arg->getType(); + QualType StrippedRVType = PassedType.getCanonicalType(); + + // Strip Restrict/Volatile qualifiers. + if (StrippedRVType.isRestrictQualified() || + StrippedRVType.isVolatileQualified()) + StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType(); + + // The only case where the argument type and expected type are allowed to + // mismatch is if the argument type is a non-void pointer (or array) and + // expected type is a void pointer. + if (StrippedRVType != ExpectedType) + if (!(ExpectedType->isVoidPointerType() && + (StrippedRVType->isPointerType() || StrippedRVType->isArrayType()))) + return Diag(Arg->getBeginLoc(), + diag::err_typecheck_convert_incompatible) + << PassedType << ExpectedType << 1 << 0 << 0; + + // If the value of the Mask is not 0, we have a constraint in the size of + // the integer argument so here we ensure the argument is a constant that + // is in the valid range. + if (Mask != 0 && + SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true)) + return true; + + ArgNum++; + } + + // In case we exited early from the previous loop, there are other types to + // read from TypeStr. So we need to read them all to ensure we have the right + // number of arguments in TheCall and if it is not the case, to display a + // better error message. + while (*TypeStr != '\0') { + (void)DecodePPCMMATypeFromStr(Context, TypeStr, Mask); + ArgNum++; + } + if (SemaRef.checkArgCount(TheCall, ArgNum)) + return true; + + return false; +} + +bool SemaPPC::BuiltinVSX(CallExpr *TheCall) { + unsigned ExpectedNumArgs = 3; + if (SemaRef.checkArgCount(TheCall, ExpectedNumArgs)) + return true; + + // Check the third argument is a compile time constant + if (!TheCall->getArg(2)->isIntegerConstantExpr(getASTContext())) + return Diag(TheCall->getBeginLoc(), + diag::err_vsx_builtin_nonconstant_argument) + << 3 /* argument index */ << TheCall->getDirectCallee() + << SourceRange(TheCall->getArg(2)->getBeginLoc(), + TheCall->getArg(2)->getEndLoc()); + + QualType Arg1Ty = TheCall->getArg(0)->getType(); + QualType Arg2Ty = TheCall->getArg(1)->getType(); + + // Check the type of argument 1 and argument 2 are vectors. + SourceLocation BuiltinLoc = TheCall->getBeginLoc(); + if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) || + (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) { + return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector) + << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false + << SourceRange(TheCall->getArg(0)->getBeginLoc(), + TheCall->getArg(1)->getEndLoc()); + } + + // Check the first two arguments are the same type. + if (!getASTContext().hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) { + return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector) + << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false + << SourceRange(TheCall->getArg(0)->getBeginLoc(), + TheCall->getArg(1)->getEndLoc()); + } + + // When default clang type checking is turned off and the customized type + // checking is used, the returning type of the function must be explicitly + // set. Otherwise it is _Bool by default. + TheCall->setType(Arg1Ty); + + return false; +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaSystemZ.cpp b/clang/lib/Sema/SemaSystemZ.cpp new file mode 100644 index 000000000000..7e836adbee65 --- /dev/null +++ b/clang/lib/Sema/SemaSystemZ.cpp @@ -0,0 +1,94 @@ +//===------ SemaSystemZ.cpp ------ SystemZ target-specific routines -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to SystemZ. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaSystemZ.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/APSInt.h" +#include + +namespace clang { + +SemaSystemZ::SemaSystemZ(Sema &S) : SemaBase(S) {} + +bool SemaSystemZ::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + if (BuiltinID == SystemZ::BI__builtin_tabort) { + Expr *Arg = TheCall->getArg(0); + if (std::optional AbortCode = + Arg->getIntegerConstantExpr(getASTContext())) + if (AbortCode->getSExtValue() >= 0 && AbortCode->getSExtValue() < 256) + return Diag(Arg->getBeginLoc(), diag::err_systemz_invalid_tabort_code) + << Arg->getSourceRange(); + } + + // For intrinsics which take an immediate value as part of the instruction, + // range check them here. + unsigned i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: return false; + case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_verimb: + case SystemZ::BI__builtin_s390_verimh: + case SystemZ::BI__builtin_s390_verimf: + case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break; + case SystemZ::BI__builtin_s390_vfaeb: + case SystemZ::BI__builtin_s390_vfaeh: + case SystemZ::BI__builtin_s390_vfaef: + case SystemZ::BI__builtin_s390_vfaebs: + case SystemZ::BI__builtin_s390_vfaehs: + case SystemZ::BI__builtin_s390_vfaefs: + case SystemZ::BI__builtin_s390_vfaezb: + case SystemZ::BI__builtin_s390_vfaezh: + case SystemZ::BI__builtin_s390_vfaezf: + case SystemZ::BI__builtin_s390_vfaezbs: + case SystemZ::BI__builtin_s390_vfaezhs: + case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vfisb: + case SystemZ::BI__builtin_s390_vfidb: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); + case SystemZ::BI__builtin_s390_vftcisb: + case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break; + case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vstrcb: + case SystemZ::BI__builtin_s390_vstrch: + case SystemZ::BI__builtin_s390_vstrcf: + case SystemZ::BI__builtin_s390_vstrczb: + case SystemZ::BI__builtin_s390_vstrczh: + case SystemZ::BI__builtin_s390_vstrczf: + case SystemZ::BI__builtin_s390_vstrcbs: + case SystemZ::BI__builtin_s390_vstrchs: + case SystemZ::BI__builtin_s390_vstrcfs: + case SystemZ::BI__builtin_s390_vstrczbs: + case SystemZ::BI__builtin_s390_vstrczhs: + case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vfminsb: + case SystemZ::BI__builtin_s390_vfmaxsb: + case SystemZ::BI__builtin_s390_vfmindb: + case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vsld: i = 2; l = 0; u = 7; break; + case SystemZ::BI__builtin_s390_vsrd: i = 2; l = 0; u = 7; break; + case SystemZ::BI__builtin_s390_vclfnhs: + case SystemZ::BI__builtin_s390_vclfnls: + case SystemZ::BI__builtin_s390_vcfn: + case SystemZ::BI__builtin_s390_vcnf: i = 1; l = 0; u = 15; break; + case SystemZ::BI__builtin_s390_vcrnfs: i = 2; l = 0; u = 15; break; + } + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u); +} + +} // namespace clang diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3e3ed77de710..40a759ea330d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5660,7 +5660,7 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, LocalInstantiationScope Scope(*this); EnterExpressionEvaluationContext EECtx{ - *this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; + *this, ExpressionEvaluationContext::Unevaluated, CSD}; if (!AreArgsDependent && CheckConstraintSatisfaction( diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 440b8bc60eaa..1011db2d2830 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4501,7 +4501,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( // Deduce an argument of type ParamType from an expression with index ArgIdx. auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx, - bool ExplicitObjetArgument) { + bool ExplicitObjectArgument) { // C++ [demp.deduct.call]p1: (DR1391) // Template argument deduction is done by comparing each function template // parameter that contains template-parameters that participate in @@ -4509,7 +4509,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) return TemplateDeductionResult::Success; - if (ExplicitObjetArgument) { + if (ExplicitObjectArgument) { // ... with the type of the corresponding argument return DeduceTemplateArgumentsFromCallArgument( *this, TemplateParams, FirstInnerIndex, ParamType, ObjectType, @@ -4544,14 +4544,14 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( if (ParamIdx == 0 && HasExplicitObject) { if (auto Result = DeduceCallArgument(ParamType, 0, - /*ExplicitObjetArgument=*/true); + /*ExplicitObjectArgument=*/true); Result != TemplateDeductionResult::Success) return Result; continue; } if (auto Result = DeduceCallArgument(ParamType, ArgIdx++, - /*ExplicitObjetArgument=*/false); + /*ExplicitObjectArgument=*/false); Result != TemplateDeductionResult::Success) return Result; @@ -4586,7 +4586,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( PackScope.nextPackElement(), ++ArgIdx) { ParamTypesForArgChecking.push_back(ParamPattern); if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, - /*ExplicitObjetArgument=*/false); + /*ExplicitObjectArgument=*/false); Result != TemplateDeductionResult::Success) return Result; } @@ -4626,8 +4626,9 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( unsigned PackArgEnd = ArgIdx + *ArgPosAfterSubstitution; for (; ArgIdx < PackArgEnd && ArgIdx < Args.size(); ArgIdx++) { ParamTypesForArgChecking.push_back(ParamPattern); - if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx, - /*ExplicitObjetArgument=*/false); + if (auto Result = + DeduceCallArgument(ParamPattern, ArgIdx, + /*ExplicitObjectArgument=*/false); Result != TemplateDeductionResult::Success) return Result; @@ -5133,6 +5134,20 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, return true; MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted, /*Final=*/false); + // Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so + // that the template arguments of the constraint can be preserved. For + // example: + // + // template + // concept C = []() { return true; }(); + // + // We need the argument for T while evaluating type constraint D in + // building the CallExpr to the lambda. + EnterExpressionEvaluationContext EECtx( + S, Sema::ExpressionEvaluationContext::Unevaluated, + ImplicitConceptSpecializationDecl::Create( + S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(), + CanonicalConverted)); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index bb49aae2cb66..4c8eaf2d4ebf 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaAMDGPU.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" @@ -563,7 +564,7 @@ static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr( return; Expr *MaxExpr = Result.getAs(); - S.addAMDGPUFlatWorkGroupSizeAttr(New, Attr, MinExpr, MaxExpr); + S.AMDGPU().addAMDGPUFlatWorkGroupSizeAttr(New, Attr, MinExpr, MaxExpr); } ExplicitSpecifier Sema::instantiateExplicitSpecifier( @@ -607,7 +608,7 @@ static void instantiateDependentAMDGPUWavesPerEUAttr( MaxExpr = Result.getAs(); } - S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr); + S.AMDGPU().addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr); } static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr( @@ -630,7 +631,7 @@ static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr( Expr *YExpr = ResultY.getAs(); Expr *ZExpr = ResultZ.getAs(); - S.addAMDGPUMaxNumWorkGroupsAttr(New, Attr, XExpr, YExpr, ZExpr); + S.AMDGPU().addAMDGPUMaxNumWorkGroupsAttr(New, Attr, XExpr, YExpr, ZExpr); } // This doesn't take any template parameters, but we have a custom action that diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp new file mode 100644 index 000000000000..c0fa05bc1760 --- /dev/null +++ b/clang/lib/Sema/SemaWasm.cpp @@ -0,0 +1,341 @@ +//===------ SemaWasm.cpp ---- WebAssembly target-specific routines --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to WebAssembly. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaWasm.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Attr.h" +#include "clang/Sema/Sema.h" + +namespace clang { + +SemaWasm::SemaWasm(Sema &S) : SemaBase(S) {} + +/// Checks the argument at the given index is a WebAssembly table and if it +/// is, sets ElTy to the element type. +static bool CheckWasmBuiltinArgIsTable(Sema &S, CallExpr *E, unsigned ArgIndex, + QualType &ElTy) { + Expr *ArgExpr = E->getArg(ArgIndex); + const auto *ATy = dyn_cast(ArgExpr->getType()); + if (!ATy || !ATy->getElementType().isWebAssemblyReferenceType()) { + return S.Diag(ArgExpr->getBeginLoc(), + diag::err_wasm_builtin_arg_must_be_table_type) + << ArgIndex + 1 << ArgExpr->getSourceRange(); + } + ElTy = ATy->getElementType(); + return false; +} + +/// Checks the argument at the given index is an integer. +static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, + unsigned ArgIndex) { + Expr *ArgExpr = E->getArg(ArgIndex); + if (!ArgExpr->getType()->isIntegerType()) { + return S.Diag(ArgExpr->getBeginLoc(), + diag::err_wasm_builtin_arg_must_be_integer_type) + << ArgIndex + 1 << ArgExpr->getSourceRange(); + } + return false; +} + +bool SemaWasm::BuiltinWasmRefNullExtern(CallExpr *TheCall) { + if (TheCall->getNumArgs() != 0) + return true; + + TheCall->setType(getASTContext().getWebAssemblyExternrefType()); + + return false; +} + +bool SemaWasm::BuiltinWasmRefNullFunc(CallExpr *TheCall) { + ASTContext &Context = getASTContext(); + if (TheCall->getNumArgs() != 0) { + Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args) + << 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs() + << /*is non object*/ 0; + return true; + } + + // This custom type checking code ensures that the nodes are as expected + // in order to later on generate the necessary builtin. + QualType Pointee = Context.getFunctionType(Context.VoidTy, {}, {}); + QualType Type = Context.getPointerType(Pointee); + Pointee = Context.getAddrSpaceQualType(Pointee, LangAS::wasm_funcref); + Type = Context.getAttributedType(attr::WebAssemblyFuncref, Type, + Context.getPointerType(Pointee)); + TheCall->setType(Type); + + return false; +} + +/// Check that the first argument is a WebAssembly table, and the second +/// is an index to use as index into the table. +bool SemaWasm::BuiltinWasmTableGet(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + + QualType ElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, ElTy)) + return true; + + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, 1)) + return true; + + // If all is well, we set the type of TheCall to be the type of the + // element of the table. + // i.e. a table.get on an externref table has type externref, + // or whatever the type of the table element is. + TheCall->setType(ElTy); + + return false; +} + +/// Check that the first argumnet is a WebAssembly table, the second is +/// an index to use as index into the table and the third is the reference +/// type to set into the table. +bool SemaWasm::BuiltinWasmTableSet(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 3)) + return true; + + QualType ElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, ElTy)) + return true; + + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, 1)) + return true; + + if (!getASTContext().hasSameType(ElTy, TheCall->getArg(2)->getType())) + return true; + + return false; +} + +/// Check that the argument is a WebAssembly table. +bool SemaWasm::BuiltinWasmTableSize(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 1)) + return true; + + QualType ElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, ElTy)) + return true; + + return false; +} + +/// Check that the first argument is a WebAssembly table, the second is the +/// value to use for new elements (of a type matching the table type), the +/// third value is an integer. +bool SemaWasm::BuiltinWasmTableGrow(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 3)) + return true; + + QualType ElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, ElTy)) + return true; + + Expr *NewElemArg = TheCall->getArg(1); + if (!getASTContext().hasSameType(ElTy, NewElemArg->getType())) { + return Diag(NewElemArg->getBeginLoc(), + diag::err_wasm_builtin_arg_must_match_table_element_type) + << 2 << 1 << NewElemArg->getSourceRange(); + } + + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, 2)) + return true; + + return false; +} + +/// Check that the first argument is a WebAssembly table, the second is an +/// integer, the third is the value to use to fill the table (of a type +/// matching the table type), and the fourth is an integer. +bool SemaWasm::BuiltinWasmTableFill(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 4)) + return true; + + QualType ElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, ElTy)) + return true; + + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, 1)) + return true; + + Expr *NewElemArg = TheCall->getArg(2); + if (!getASTContext().hasSameType(ElTy, NewElemArg->getType())) { + return Diag(NewElemArg->getBeginLoc(), + diag::err_wasm_builtin_arg_must_match_table_element_type) + << 3 << 1 << NewElemArg->getSourceRange(); + } + + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, 3)) + return true; + + return false; +} + +/// Check that the first argument is a WebAssembly table, the second is also a +/// WebAssembly table (of the same element type), and the third to fifth +/// arguments are integers. +bool SemaWasm::BuiltinWasmTableCopy(CallExpr *TheCall) { + if (SemaRef.checkArgCount(TheCall, 5)) + return true; + + QualType XElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 0, XElTy)) + return true; + + QualType YElTy; + if (CheckWasmBuiltinArgIsTable(SemaRef, TheCall, 1, YElTy)) + return true; + + Expr *TableYArg = TheCall->getArg(1); + if (!getASTContext().hasSameType(XElTy, YElTy)) { + return Diag(TableYArg->getBeginLoc(), + diag::err_wasm_builtin_arg_must_match_table_element_type) + << 2 << 1 << TableYArg->getSourceRange(); + } + + for (int I = 2; I <= 4; I++) { + if (CheckWasmBuiltinArgIsInteger(SemaRef, TheCall, I)) + return true; + } + + return false; +} + +bool SemaWasm::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + switch (BuiltinID) { + case WebAssembly::BI__builtin_wasm_ref_null_extern: + return BuiltinWasmRefNullExtern(TheCall); + case WebAssembly::BI__builtin_wasm_ref_null_func: + return BuiltinWasmRefNullFunc(TheCall); + case WebAssembly::BI__builtin_wasm_table_get: + return BuiltinWasmTableGet(TheCall); + case WebAssembly::BI__builtin_wasm_table_set: + return BuiltinWasmTableSet(TheCall); + case WebAssembly::BI__builtin_wasm_table_size: + return BuiltinWasmTableSize(TheCall); + case WebAssembly::BI__builtin_wasm_table_grow: + return BuiltinWasmTableGrow(TheCall); + case WebAssembly::BI__builtin_wasm_table_fill: + return BuiltinWasmTableFill(TheCall); + case WebAssembly::BI__builtin_wasm_table_copy: + return BuiltinWasmTableCopy(TheCall); + } + + return false; +} + +WebAssemblyImportModuleAttr * +SemaWasm::mergeImportModuleAttr(Decl *D, + const WebAssemblyImportModuleAttr &AL) { + auto *FD = cast(D); + + if (const auto *ExistingAttr = FD->getAttr()) { + if (ExistingAttr->getImportModule() == AL.getImportModule()) + return nullptr; + Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) + << 0 << ExistingAttr->getImportModule() << AL.getImportModule(); + Diag(AL.getLoc(), diag::note_previous_attribute); + return nullptr; + } + if (FD->hasBody()) { + Diag(AL.getLoc(), diag::warn_import_on_definition) << 0; + return nullptr; + } + return ::new (getASTContext()) + WebAssemblyImportModuleAttr(getASTContext(), AL, AL.getImportModule()); +} + +WebAssemblyImportNameAttr * +SemaWasm::mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL) { + auto *FD = cast(D); + + if (const auto *ExistingAttr = FD->getAttr()) { + if (ExistingAttr->getImportName() == AL.getImportName()) + return nullptr; + Diag(ExistingAttr->getLocation(), diag::warn_mismatched_import) + << 1 << ExistingAttr->getImportName() << AL.getImportName(); + Diag(AL.getLoc(), diag::note_previous_attribute); + return nullptr; + } + if (FD->hasBody()) { + Diag(AL.getLoc(), diag::warn_import_on_definition) << 1; + return nullptr; + } + return ::new (getASTContext()) + WebAssemblyImportNameAttr(getASTContext(), AL, AL.getImportName()); +} + +void SemaWasm::handleWebAssemblyImportModuleAttr(Decl *D, + const ParsedAttr &AL) { + auto *FD = cast(D); + + StringRef Str; + SourceLocation ArgLoc; + if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + if (FD->hasBody()) { + Diag(AL.getLoc(), diag::warn_import_on_definition) << 0; + return; + } + + FD->addAttr(::new (getASTContext()) + WebAssemblyImportModuleAttr(getASTContext(), AL, Str)); +} + +void SemaWasm::handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL) { + auto *FD = cast(D); + + StringRef Str; + SourceLocation ArgLoc; + if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + if (FD->hasBody()) { + Diag(AL.getLoc(), diag::warn_import_on_definition) << 1; + return; + } + + FD->addAttr(::new (getASTContext()) + WebAssemblyImportNameAttr(getASTContext(), AL, Str)); +} + +void SemaWasm::handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL) { + ASTContext &Context = getASTContext(); + if (!isFuncOrMethodForAttrSubject(D)) { + Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; + return; + } + + auto *FD = cast(D); + if (FD->isThisDeclarationADefinition()) { + Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0; + return; + } + + StringRef Str; + SourceLocation ArgLoc; + if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + + D->addAttr(::new (Context) WebAssemblyExportNameAttr(Context, AL, Str)); + D->addAttr(UsedAttr::CreateImplicit(Context)); +} + +} // namespace clang diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4a6e1d23161b..2bc00e1bb3e3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -40,9 +40,11 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/CommentOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticError.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/ExceptionSpecificationType.h" @@ -9403,6 +9405,20 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const { return Diags.Report(Loc, DiagID); } +void ASTReader::warnStackExhausted(SourceLocation Loc) { + // When Sema is available, avoid duplicate errors. + if (SemaObj) { + SemaObj->warnStackExhausted(Loc); + return; + } + + if (WarnedStackExhausted) + return; + WarnedStackExhausted = true; + + Diag(Loc, diag::warn_stack_exhausted); +} + /// Retrieve the identifier table associated with the /// preprocessor. IdentifierTable &ASTReader::getIdentifierTable() { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 61cc99d4df68..765c083ce8df 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -49,6 +49,7 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/Stack.h" #include "clang/Sema/IdentifierResolver.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTRecordReader.h" @@ -4127,7 +4128,10 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { // calls to Decl::getASTContext() by Decl's methods will find the // TranslationUnitDecl without crashing. D->setDeclContext(Context.getTranslationUnitDecl()); - Reader.Visit(D); + + // Reading some declarations can result in deep recursion. + clang::runWithSufficientStackSpace([&] { warnStackExhausted(DeclLoc); }, + [&] { Reader.Visit(D); }); // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e830c4026ea7..eb41a205bc82 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3205,9 +3205,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, } // Sort by diag::kind for deterministic output. - llvm::sort(Mappings, [](const auto &LHS, const auto &RHS) { - return LHS.first < RHS.first; - }); + llvm::sort(Mappings, llvm::less_first()); for (const auto &I : Mappings) { Record.push_back(I.first); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index bbd16dbdb8ff..5a6ab4408eb2 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1733,7 +1733,7 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (Writer.isGeneratingReducedBMI()) { auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D); for (auto *DG : D->getDeclContext()->noload_lookup(Name)) - Writer.GetDeclRef(DG); + Writer.GetDeclRef(DG->getCanonicalDecl()); } Code = serialization::DECL_CLASS_TEMPLATE; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index 0cab17a34244..66a2f6e0acb6 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -42,7 +42,7 @@ DependencyScanningWorkerFilesystem::readFile(StringRef Filename) { } bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated( - EntryRef Ref) { + EntryRef Ref, const LangOptions &LangOpts) { auto &Entry = Ref.Entry; if (Entry.isError() || Entry.isDirectory()) @@ -66,7 +66,7 @@ bool DependencyScanningWorkerFilesystem::ensureDirectiveTokensArePopulated( // dependencies. if (scanSourceForDependencyDirectives(Contents->Original->getBuffer(), Contents->DepDirectiveTokens, - Directives)) { + Directives, LangOpts)) { Contents->DepDirectiveTokens.clear(); // FIXME: Propagate the diagnostic if desired by the client. Contents->DepDirectives.store(new std::optional()); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 0c047b6c5da2..07e1960dd905 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -259,9 +259,7 @@ static void canonicalizeDefines(PreprocessorOptions &PPOpts) { ++Index; } - llvm::stable_sort(SimpleNames, [](const MacroOpt &A, const MacroOpt &B) { - return A.first < B.first; - }); + llvm::stable_sort(SimpleNames, llvm::less_first()); // Keep the last instance of each macro name by going in reverse auto NewEnd = std::unique( SimpleNames.rbegin(), SimpleNames.rend(), @@ -366,11 +364,12 @@ public: // Use the dependency scanning optimized file system if requested to do so. if (DepFS) ScanInstance.getPreprocessorOpts().DependencyDirectivesForFile = - [LocalDepFS = DepFS](FileEntryRef File) + [LocalDepFS = DepFS, + &LangOpts = ScanInstance.getLangOpts()](FileEntryRef File) -> std::optional> { if (llvm::ErrorOr Entry = LocalDepFS->getOrCreateFileSystemEntry(File.getName())) - if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) + if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry, LangOpts)) return Entry->getDirectiveTokens(); return std::nullopt; }; diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp index a77686996879..5ecba5dfece3 100644 --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -260,7 +260,7 @@ static llvm::StringRef stripExecutableExtension(llvm::StringRef Name) { return Name; } -// There are compiler-wrappers (ccache, distcc, gomacc) that take the "real" +// There are compiler-wrappers (ccache, distcc) that take the "real" // compiler as an argument, e.g. distcc gcc -O3 foo.c. // These end up in compile_commands.json when people set CC="distcc gcc". // Clang's driver doesn't understand this, so we need to unwrap. @@ -269,8 +269,7 @@ static bool unwrapCommand(std::vector &Args) { return false; StringRef Wrapper = stripExecutableExtension(llvm::sys::path::filename(Args.front())); - if (Wrapper == "distcc" || Wrapper == "gomacc" || Wrapper == "ccache" || - Wrapper == "sccache") { + if (Wrapper == "distcc" || Wrapper == "ccache" || Wrapper == "sccache") { // Most of these wrappers support being invoked 3 ways: // `distcc g++ file.c` This is the mode we're trying to match. // We need to drop `distcc`. diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp b/clang/test/AST/ast-dump-ctad-alias.cpp index 08a3be5c6b75..cd3b8c682134 100644 --- a/clang/test/AST/ast-dump-ctad-alias.cpp +++ b/clang/test/AST/ast-dump-ctad-alias.cpp @@ -36,8 +36,12 @@ Out2::AInner t(1.0); // CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0 // CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible // CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2::AInner' dependent +// CHECK-NEXT: | | | `-name: 'Out2::AInner' +// CHECK-NEXT: | | | `-TypeAliasTemplateDecl {{.+}} AInner{{$}} // CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner' sugar dependent -// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner' dependent Inner +// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner' dependent +// CHECK-NEXT: | | |-name: 'Inner':'Out::Inner' qualified +// CHECK-NEXT: | | | `-ClassTemplateDecl {{.+}} Inner{{$}} // CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-1-0' // CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0' // CHECK-NEXT: | | |-FunctionTemplate {{.*}} '' diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp index 55bded4c77d4..fea14abb3b2f 100644 --- a/clang/test/AST/ast-dump-template-decls.cpp +++ b/clang/test/AST/ast-dump-template-decls.cpp @@ -116,7 +116,10 @@ template struct C { using type2 = typename C::type1; // CHECK: TypeAliasDecl 0x{{[^ ]*}} col:7 type2 'typename C::type1':'void (int)' // CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C::type1' sugar -// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1' sugar alias C::type1 +// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1' sugar alias +// CHECK-NEXT: name: 'C::type1':'PR55886::C::type1' qualified +// CHECK-NEXT: NestedNameSpecifier TypeSpec 'C':'PR55886::C' +// CHECK-NEXT: TypeAliasTemplateDecl {{.+}} type1 // CHECK-NEXT: TemplateArgument type 'void' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void' // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl @@ -135,7 +138,7 @@ template struct foo { template using bind = Z; }; using t1 = foo::bind; -// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y' sugar Y +// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y' sugar // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... Bs pack_index 3 // CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z' // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... Bs pack_index 2 @@ -149,7 +152,8 @@ template struct D { template using B = int(int (*...p)(T, U)); }; using t2 = D::B; -// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B' sugar alias D::B{{$}} +// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B' sugar alias{{$}} +// CHECK-NEXT: name: 'D::B':'PR56099::D::B' qualified // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1 @@ -170,7 +174,9 @@ template> class D1, class D2> using D = D1 class E {}; using test1 = D; // CHECK: TypeAliasDecl 0x{{[^ ]*}} col:7 test1 'D':'subst_default_argument::E>' -// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A' sugar A +// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A' sugar +// CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified +// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A // CHECK-NEXT: |-TemplateArgument type 'int' // CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2 // CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D' diff --git a/clang/test/AST/ast-dump-template-name.cpp b/clang/test/AST/ast-dump-template-name.cpp index 7972e9f9e9b0..acacdac85795 100644 --- a/clang/test/AST/ast-dump-template-name.cpp +++ b/clang/test/AST/ast-dump-template-name.cpp @@ -13,6 +13,8 @@ namespace qualified { // CHECK-NEXT: TypeAliasDecl // CHECK-NEXT: `-ElaboratedType // CHECK-NEXT: `-TemplateSpecializationType +// CHECK-NEXT: |-name: 'N' qualified +// CHECK-NEXT: | `-TypeAliasTemplateDecl {{.+}} N{{$}} // CHECK-NEXT: |-TemplateArgument template 'foo::A':'qualified::foo::A' qualified{{$}} // CHECK-NEXT: | |-NestedNameSpecifier Namespace 0x{{.+}} 'foo'{{$}} // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}} @@ -27,6 +29,8 @@ namespace dependent { // CHECK-NEXT: TypeAliasDecl // CHECK-NEXT: `-ElaboratedType // CHECK-NEXT: `-TemplateSpecializationType +// CHECK-NEXT: |-name: 'N' qualified +// CHECK-NEXT: | `-TypeAliasTemplateDecl // CHECK-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent{{$}} // CHECK-NEXT: | `-NestedNameSpecifier TypeSpec 'T'{{$}} @@ -47,6 +51,8 @@ namespace subst { // CHECK-NEXT: |-TypeAlias // CHECK-NEXT: `-ElaboratedType // CHECK-NEXT: `-TemplateSpecializationType +// CHECK-NEXT: |-name: 'C':'subst::B::C' qualified +// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} C // CHECK-NEXT: |-TemplateArgument template 'subst::A' subst index 0 // CHECK-NEXT: | |-parameter: TemplateTemplateParmDecl {{.+}} depth 0 index 0 TT{{$}} // CHECK-NEXT: | |-associated ClassTemplateSpecialization {{.+}} 'B'{{$}} diff --git a/clang/test/AST/ast-dump-using-template.cpp b/clang/test/AST/ast-dump-using-template.cpp index 7731c2ad0231..22b9b76612ad 100644 --- a/clang/test/AST/ast-dump-using-template.cpp +++ b/clang/test/AST/ast-dump-using-template.cpp @@ -20,15 +20,19 @@ template using A = S; // CHECK: TypeAliasDecl // CHECK-NEXT: `-ElaboratedType {{.*}} 'S' sugar dependent -// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'S' dependent using S +// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'S' dependent +// CHECK-NEXT: |-name: 'S':'ns::S' qualified +// CHECk-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S' // TemplateName in TemplateArgument. template