aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/FindTarget.cpp13
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp38
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp68
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp40
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp30
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp52
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp24
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp76
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp46
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp16
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp18
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp38
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp14
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp14
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp32
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp80
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp76
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp3
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp26
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp12
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp80
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp16
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp17
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp17
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp132
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp20
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp18
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp20
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp158
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp78
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp189
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp16
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp16
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp5
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp5
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp12
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp30
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp16
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp28
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp8
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp11
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp6
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp10
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp4
-rw-r--r--clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp4
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/docs/UsersManual.rst2
-rw-r--r--clang/docs/analyzer/developer-docs/Statistics.rst2
-rw-r--r--clang/include/clang/AST/NestedNameSpecifierBase.h3
-rw-r--r--clang/include/clang/AST/TypeLoc.h5
-rw-r--r--clang/include/clang/Basic/Attr.td18
-rw-r--r--clang/include/clang/Basic/AttrDocs.td22
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/include/clang/Sema/SemaHLSL.h1
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h5
-rw-r--r--clang/lib/AST/ByteCode/Interp.h2
-rw-r--r--clang/lib/AST/ExprConstant.cpp8
-rw-r--r--clang/lib/AST/TypeLoc.cpp33
-rw-r--r--clang/lib/CIR/CodeGen/Address.h8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXABI.h9
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenClass.cpp33
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp43
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp28
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypes.cpp6
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenVTables.cpp10
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp5
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp11
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp14
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp34
-rw-r--r--clang/lib/Sema/SemaSYCL.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp8
-rw-r--r--clang/lib/Sema/SemaType.cpp10
-rw-r--r--clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp78
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp30
-rw-r--r--clang/test/Analysis/analyzer-stats/entry-point-stats.cpp28
-rw-r--r--clang/test/CIR/CodeGen/virtual-destructor-calls.cpp129
-rw-r--r--clang/test/OpenMP/target_indirect_codegen.cpp12
-rw-r--r--clang/test/OpenMP/target_parallel_num_threads_strict_messages.cpp (renamed from clang/test/OpenMP/amdgcn_parallel_num_threads_strict_messages.cpp)7
-rw-r--r--clang/unittests/StaticAnalyzer/CMakeLists.txt1
-rw-r--r--clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp150
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp6
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_flags.cpp4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_flags.h2
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_flags.inc2
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.h4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.cpp4
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl.h2
-rw-r--r--cross-project-tests/intrinsic-header-tests/wasm_simd128.c4
-rw-r--r--flang/include/flang/Optimizer/Builder/IntrinsicCall.h1
-rw-r--r--flang/lib/Lower/IO.cpp8
-rw-r--r--flang/lib/Optimizer/Builder/IntrinsicCall.cpp15
-rw-r--r--flang/lib/Optimizer/Transforms/CUFOpConversion.cpp4
-rw-r--r--flang/module/cudadevice.f909
-rw-r--r--flang/test/Fir/CUDA/cuda-data-transfer.fir40
-rw-r--r--flang/test/Lower/CUDA/cuda-device-proc.cuf12
-rw-r--r--flang/test/Lower/namelist.f9040
-rw-r--r--libc/src/string/memory_utils/op_aarch64.h18
-rw-r--r--lldb/bindings/python/python-typemaps.swig5
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp8
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h1
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp10
-rw-r--r--lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp1
-rw-r--r--lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp2
-rw-r--r--lldb/source/Plugins/Process/wasm/RegisterContextWasm.h3
-rw-r--r--lldb/source/Plugins/Process/wasm/UnwindWasm.cpp22
-rw-r--r--lldb/source/Target/RegisterContextUnwind.cpp32
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile3
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py45
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp23
-rw-r--r--lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py2
-rw-r--r--lldb/test/API/macosx/mte/TestDarwinMTE.py2
-rw-r--r--lldb/test/API/python_api/default-constructor/sb_filespec.py2
-rw-r--r--lldb/test/Shell/Expr/TestExprLanguageNote.test4
-rwxr-xr-xlldb/utils/lui/lui.py6
-rwxr-xr-xlldb/utils/lui/sandbox.py5
-rw-r--r--llvm/include/llvm/ADT/Bitfields.h88
-rw-r--r--llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h6
-rw-r--r--llvm/include/llvm/Analysis/StaticDataProfileInfo.h18
-rw-r--r--llvm/include/llvm/CodeGen/ISDOpcodes.h6
-rw-r--r--llvm/include/llvm/Frontend/OpenMP/OMPKinds.def2
-rw-r--r--llvm/include/llvm/IR/ConstantFPRange.h9
-rw-r--r--llvm/include/llvm/IR/IRBuilder.h5
-rw-r--r--llvm/include/llvm/Target/TargetSelectionDAG.td1
-rw-r--r--llvm/include/llvm/TargetParser/RISCVTargetParser.h2
-rw-r--r--llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h8
-rw-r--r--llvm/include/llvm/Transforms/Coroutines/SpillUtils.h9
-rw-r--r--llvm/include/llvm/XRay/BlockIndexer.h6
-rw-r--r--llvm/include/llvm/XRay/BlockPrinter.h6
-rw-r--r--llvm/include/llvm/XRay/BlockVerifier.h6
-rw-r--r--llvm/include/llvm/XRay/FDRLogBuilder.h6
-rw-r--r--llvm/include/llvm/XRay/FDRRecordConsumer.h6
-rw-r--r--llvm/include/llvm/XRay/FDRRecordProducer.h6
-rw-r--r--llvm/include/llvm/XRay/FDRRecords.h6
-rw-r--r--llvm/include/llvm/XRay/FDRTraceExpander.h6
-rw-r--r--llvm/include/llvm/XRay/FDRTraceWriter.h6
-rw-r--r--llvm/include/llvm/XRay/FileHeaderReader.h6
-rw-r--r--llvm/include/llvm/XRay/Graph.h7
-rw-r--r--llvm/include/llvm/XRay/InstrumentationMap.h19
-rw-r--r--llvm/include/llvm/XRay/Profile.h6
-rw-r--r--llvm/include/llvm/XRay/RecordPrinter.h6
-rw-r--r--llvm/include/llvm/XRay/Trace.h6
-rw-r--r--llvm/include/llvm/XRay/XRayRecord.h6
-rw-r--r--llvm/include/llvm/XRay/YAMLXRayRecord.h18
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp49
-rw-r--r--llvm/lib/Analysis/StaticDataProfileInfo.cpp40
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AIXException.cpp4
-rw-r--r--llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp4
-rw-r--r--llvm/lib/CodeGen/BasicBlockPathCloning.cpp4
-rw-r--r--llvm/lib/CodeGen/BreakFalseDeps.cpp4
-rw-r--r--llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp4
-rw-r--r--llvm/lib/CodeGen/EdgeBundles.cpp11
-rw-r--r--llvm/lib/CodeGen/ExpandFp.cpp1
-rw-r--r--llvm/lib/CodeGen/GlobalMergeFunctions.cpp10
-rw-r--r--llvm/lib/CodeGen/LiveIntervals.cpp6
-rw-r--r--llvm/lib/CodeGen/MIR2Vec.cpp13
-rw-r--r--llvm/lib/CodeGen/MIRFSDiscriminator.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRNamerPass.cpp17
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp6
-rw-r--r--llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp9
-rw-r--r--llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp18
-rw-r--r--llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp9
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp62
-rw-r--r--llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp8
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp5
-rw-r--r--llvm/lib/CodeGen/MachinePipeliner.cpp13
-rw-r--r--llvm/lib/CodeGen/MachineScheduler.cpp104
-rw-r--r--llvm/lib/CodeGen/MachineTraceMetrics.cpp7
-rw-r--r--llvm/lib/CodeGen/NonRelocatableStringpool.cpp4
-rw-r--r--llvm/lib/CodeGen/SafeStack.cpp4
-rw-r--r--llvm/lib/CodeGen/ScheduleDAGInstrs.cpp6
-rw-r--r--llvm/lib/CodeGen/ScheduleDAGPrinter.cpp80
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp17
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp7
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp1
-rw-r--r--llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp5
-rw-r--r--llvm/lib/CodeGen/StaticDataAnnotator.cpp15
-rw-r--r--llvm/lib/CodeGen/StaticDataSplitter.cpp6
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp3
-rw-r--r--llvm/lib/CodeGen/TargetRegisterInfo.cpp17
-rw-r--r--llvm/lib/IR/ConstantFPRange.cpp144
-rw-r--r--llvm/lib/IR/IRBuilder.cpp13
-rw-r--r--llvm/lib/TableGen/Record.cpp9
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp12
-rw-r--r--llvm/lib/Target/AMDGPU/MIMGInstructions.td28
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp4
-rw-r--r--llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h66
-rw-r--r--llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp205
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrFormats.td16
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfo.cpp8
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td22
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td9
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td143
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrPredicates.td36
-rw-r--r--llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp4
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp21
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td68
-rw-r--r--llvm/lib/TargetParser/RISCVTargetParser.cpp4
-rw-r--r--llvm/lib/Transforms/Coroutines/CoroCloner.h9
-rw-r--r--llvm/lib/Transforms/Coroutines/CoroEarly.cpp2
-rw-r--r--llvm/lib/Transforms/Coroutines/CoroInternal.h9
-rw-r--r--llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp5
-rw-r--r--llvm/lib/Transforms/Coroutines/SpillUtils.cpp37
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineInternal.h2
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp4
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemProfUse.cpp55
-rw-r--r--llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp3
-rw-r--r--llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp15
-rw-r--r--llvm/lib/XRay/BlockIndexer.cpp7
-rw-r--r--llvm/lib/XRay/BlockPrinter.cpp7
-rw-r--r--llvm/lib/XRay/BlockVerifier.cpp18
-rw-r--r--llvm/lib/XRay/FDRRecordProducer.cpp14
-rw-r--r--llvm/lib/XRay/FDRRecords.cpp7
-rw-r--r--llvm/lib/XRay/FDRTraceExpander.cpp7
-rw-r--r--llvm/lib/XRay/FDRTraceWriter.cpp12
-rw-r--r--llvm/lib/XRay/FileHeaderReader.cpp12
-rw-r--r--llvm/lib/XRay/LogBuilderConsumer.cpp7
-rw-r--r--llvm/lib/XRay/Profile.cpp18
-rw-r--r--llvm/lib/XRay/RecordInitializer.cpp7
-rw-r--r--llvm/lib/XRay/RecordPrinter.cpp7
-rw-r--r--llvm/lib/XRay/Trace.cpp18
-rw-r--r--llvm/test/CodeGen/AMDGPU/sched.group.classification.mir59
-rw-r--r--llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir523
-rw-r--r--llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll106
-rw-r--r--llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll1309
-rw-r--r--llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll67
-rw-r--r--llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll13
-rw-r--r--llvm/test/CodeGen/X86/global-variable-partition.ll18
-rw-r--r--llvm/test/CodeGen/X86/setcc-wide-types.ll155
-rw-r--r--llvm/test/MC/WebAssembly/simd-encodings.s8
-rw-r--r--llvm/test/TableGen/listsplat.td6
-rw-r--r--llvm/test/Transforms/PGOProfile/data-access-profile.ll83
-rw-r--r--llvm/unittests/ADT/BitFieldsTest.cpp4
-rw-r--r--llvm/unittests/IR/ConstantFPRangeTest.cpp109
-rw-r--r--llvm/utils/profcheck-xfail.txt77
-rw-r--r--mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt4
-rw-r--r--mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td353
-rw-r--r--mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td1
-rw-r--r--mlir/include/mlir/Interfaces/ViewLikeInterface.h16
-rw-r--r--mlir/include/mlir/Interfaces/ViewLikeInterface.td12
-rw-r--r--mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp36
-rw-r--r--mlir/lib/Dialect/LLVMIR/CMakeLists.txt2
-rw-r--r--mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp3
-rw-r--r--mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp154
-rw-r--r--mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h27
-rw-r--r--mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp17
-rw-r--r--mlir/lib/IR/AsmPrinter.cpp7
-rw-r--r--mlir/test/Analysis/test-alias-analysis.mlir16
-rw-r--r--mlir/test/Dialect/LLVMIR/bytecode.mlir35
-rw-r--r--mlir/test/Dialect/LLVMIR/debuginfo.mlir1
-rw-r--r--mlir/test/Dialect/LLVMIR/roundtrip.mlir6
-rw-r--r--mlir/test/Dialect/XeGPU/xegpu-blocking.mlir98
295 files changed, 6223 insertions, 2041 deletions
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 8aae414..799c64b 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -1040,16 +1040,11 @@ private:
if (auto *S = N.get<Stmt>())
return refInStmt(S, Resolver);
if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
+ if (auto TL = NNSL->getAsTypeLoc())
+ return refInTypeLoc(NNSL->getAsTypeLoc(), Resolver);
// (!) 'DeclRelation::Alias' ensures we do not lose namespace aliases.
- NestedNameSpecifierLoc Qualifier;
- SourceLocation NameLoc;
- if (auto TL = NNSL->getAsTypeLoc()) {
- Qualifier = TL.getPrefix();
- NameLoc = TL.getNonPrefixBeginLoc();
- } else {
- Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix;
- NameLoc = NNSL->getLocalBeginLoc();
- }
+ NestedNameSpecifierLoc Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix;
+ SourceLocation NameLoc = NNSL->getLocalBeginLoc();
return {
ReferenceLoc{Qualifier, NameLoc, false,
explicitReferenceTargets(
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp
index 562b513..cc41603 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-addition %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -8,68 +8,68 @@ void f() {
i = absl::ToUnixHours(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+ // CHECK-FIXES: i = absl::ToUnixHours(t + absl::Hours(5));
i = absl::ToUnixMinutes(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+ // CHECK-FIXES: i = absl::ToUnixMinutes(t + absl::Minutes(5));
i = absl::ToUnixSeconds(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+ // CHECK-FIXES: i = absl::ToUnixSeconds(t + absl::Seconds(5));
i = absl::ToUnixMillis(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+ // CHECK-FIXES: i = absl::ToUnixMillis(t + absl::Milliseconds(5));
i = absl::ToUnixMicros(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+ // CHECK-FIXES: i = absl::ToUnixMicros(t + absl::Microseconds(5));
i = absl::ToUnixNanos(t) + 5;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+ // CHECK-FIXES: i = absl::ToUnixNanos(t + absl::Nanoseconds(5));
i = 3 + absl::ToUnixHours(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixHours(absl::Hours(3) + t);
i = 3 + absl::ToUnixMinutes(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixMinutes(absl::Minutes(3) + t);
i = 3 + absl::ToUnixSeconds(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixSeconds(absl::Seconds(3) + t);
i = 3 + absl::ToUnixMillis(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixMillis(absl::Milliseconds(3) + t);
i = 3 + absl::ToUnixMicros(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixMicros(absl::Microseconds(3) + t);
i = 3 + absl::ToUnixNanos(t);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixNanos(absl::Nanoseconds(3) + t);
// Undoing inverse conversions
i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+ // CHECK-FIXES: i = absl::ToUnixMicros(t + absl::Seconds(1));
// Parens
i = 3 + (absl::ToUnixHours(t));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+ // CHECK-FIXES: i = absl::ToUnixHours(absl::Hours(3) + t);
// Float folding
i = absl::ToUnixSeconds(t) + 5.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+ // CHECK-FIXES: i = absl::ToUnixSeconds(t + absl::Seconds(5));
// We can rewrite the argument of the duration conversion
#define THIRTY absl::FromUnixSeconds(30)
i = absl::ToUnixSeconds(THIRTY) + 1;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+ // CHECK-FIXES: i = absl::ToUnixSeconds(THIRTY + absl::Seconds(1));
#undef THIRTY
// Some other contexts
if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+ // CHECK-FIXES: if (absl::ToUnixSeconds(t + absl::Seconds(1)) > 10) {}
// These should not match
i = 5 + 6;
@@ -88,7 +88,7 @@ template<typename T>
void foo(absl::Time t) {
int i = absl::ToUnixNanos(t) + T{};
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition]
- // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{}))
+ // CHECK-FIXES: int i = absl::ToUnixNanos(t + absl::Nanoseconds(T{}));
}
void g() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp
index 6110dfd..8f49e71 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-comparison %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-comparison %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -11,104 +11,104 @@ void f() {
// Check against the RHS
b = x > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) > d1;
+ // CHECK-FIXES: b = absl::Seconds(x) > d1;
b = x >= absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) >= d1;
+ // CHECK-FIXES: b = absl::Seconds(x) >= d1;
b = x == absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) == d1;
+ // CHECK-FIXES: b = absl::Seconds(x) == d1;
b = x <= absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) <= d1;
+ // CHECK-FIXES: b = absl::Seconds(x) <= d1;
b = x < absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) < d1;
+ // CHECK-FIXES: b = absl::Seconds(x) < d1;
b = x == absl::ToDoubleSeconds(t1 - t2);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) == t1 - t2;
+ // CHECK-FIXES: b = absl::Seconds(x) == t1 - t2;
b = absl::ToDoubleSeconds(d1) > absl::ToDoubleSeconds(d2);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 > d2;
+ // CHECK-FIXES: b = d1 > d2;
// Check against the LHS
b = absl::ToDoubleSeconds(d1) < x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 < absl::Seconds(x);
+ // CHECK-FIXES: b = d1 < absl::Seconds(x);
b = absl::ToDoubleSeconds(d1) <= x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 <= absl::Seconds(x);
+ // CHECK-FIXES: b = d1 <= absl::Seconds(x);
b = absl::ToDoubleSeconds(d1) == x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 == absl::Seconds(x);
+ // CHECK-FIXES: b = d1 == absl::Seconds(x);
b = absl::ToDoubleSeconds(d1) >= x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 >= absl::Seconds(x);
+ // CHECK-FIXES: b = d1 >= absl::Seconds(x);
b = absl::ToDoubleSeconds(d1) > x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 > absl::Seconds(x);
+ // CHECK-FIXES: b = d1 > absl::Seconds(x);
// Comparison against zero
b = absl::ToDoubleSeconds(d1) < 0.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 < absl::ZeroDuration();
+ // CHECK-FIXES: b = d1 < absl::ZeroDuration();
b = absl::ToDoubleSeconds(d1) < 0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: d1 < absl::ZeroDuration();
+ // CHECK-FIXES: b = d1 < absl::ZeroDuration();
// Scales other than Seconds
b = x > absl::ToDoubleMicroseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Microseconds(x) > d1;
+ // CHECK-FIXES: b = absl::Microseconds(x) > d1;
b = x >= absl::ToDoubleMilliseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Milliseconds(x) >= d1;
+ // CHECK-FIXES: b = absl::Milliseconds(x) >= d1;
b = x == absl::ToDoubleNanoseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Nanoseconds(x) == d1;
+ // CHECK-FIXES: b = absl::Nanoseconds(x) == d1;
b = x <= absl::ToDoubleMinutes(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Minutes(x) <= d1;
+ // CHECK-FIXES: b = absl::Minutes(x) <= d1;
b = x < absl::ToDoubleHours(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Hours(x) < d1;
+ // CHECK-FIXES: b = absl::Hours(x) < d1;
// Integer comparisons
b = x > absl::ToInt64Microseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Microseconds(x) > d1;
+ // CHECK-FIXES: b = absl::Microseconds(x) > d1;
b = x >= absl::ToInt64Milliseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Milliseconds(x) >= d1;
+ // CHECK-FIXES: b = absl::Milliseconds(x) >= d1;
b = x == absl::ToInt64Nanoseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Nanoseconds(x) == d1;
+ // CHECK-FIXES: b = absl::Nanoseconds(x) == d1;
b = x == absl::ToInt64Seconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(x) == d1;
+ // CHECK-FIXES: b = absl::Seconds(x) == d1;
b = x <= absl::ToInt64Minutes(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Minutes(x) <= d1;
+ // CHECK-FIXES: b = absl::Minutes(x) <= d1;
b = x < absl::ToInt64Hours(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Hours(x) < d1;
+ // CHECK-FIXES: b = absl::Hours(x) < d1;
// Other abseil-duration checks folded into this one
b = static_cast<double>(5) > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(5) > d1;
+ // CHECK-FIXES: b = absl::Seconds(5) > d1;
b = double(5) > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(5) > d1;
+ // CHECK-FIXES: b = absl::Seconds(5) > d1;
b = float(5) > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(5) > d1;
+ // CHECK-FIXES: b = absl::Seconds(5) > d1;
b = ((double)5) > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(5) > d1;
+ // CHECK-FIXES: b = absl::Seconds(5) > d1;
b = 5.0 > absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Seconds(5) > d1;
+ // CHECK-FIXES: b = absl::Seconds(5) > d1;
// A long expression
bool some_condition;
@@ -125,20 +125,20 @@ void f() {
int y;
b = (y + 5) * 10 > absl::ToDoubleMilliseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: absl::Milliseconds((y + 5) * 10) > d1;
+ // CHECK-FIXES: b = absl::Milliseconds((y + 5) * 10) > d1;
// We should still transform the expression inside this macro invocation
#define VALUE_IF(v, e) v ? (e) : 0
int a = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+ // CHECK-FIXES: int a = VALUE_IF(1, absl::Seconds(5) > d1);
#undef VALUE_IF
#define VALUE_IF_2(e) (e)
#define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0)
int a2 = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the duration domain [abseil-duration-comparison]
- // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+ // CHECK-FIXES: int a2 = VALUE_IF(1, absl::Seconds(5) > d1);
#undef VALUE_IF
#undef VALUE_IF_2
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp
index 368b9d6..b5183a9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -9,56 +9,56 @@ void f() {
i = static_cast<int>(absl::ToDoubleHours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Hours(d1);
+ // CHECK-FIXES: i = absl::ToInt64Hours(d1);
x = static_cast<float>(absl::ToInt64Hours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleHours(d1);
+ // CHECK-FIXES: x = absl::ToDoubleHours(d1);
i = static_cast<int>(absl::ToDoubleMinutes(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Minutes(d1);
+ // CHECK-FIXES: i = absl::ToInt64Minutes(d1);
x = static_cast<float>(absl::ToInt64Minutes(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMinutes(d1);
+ // CHECK-FIXES: x = absl::ToDoubleMinutes(d1);
i = static_cast<int>(absl::ToDoubleSeconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Seconds(d1);
+ // CHECK-FIXES: i = absl::ToInt64Seconds(d1);
x = static_cast<float>(absl::ToInt64Seconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleSeconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d1);
i = static_cast<int>(absl::ToDoubleMilliseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Milliseconds(d1);
+ // CHECK-FIXES: i = absl::ToInt64Milliseconds(d1);
x = static_cast<float>(absl::ToInt64Milliseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMilliseconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleMilliseconds(d1);
i = static_cast<int>(absl::ToDoubleMicroseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Microseconds(d1);
+ // CHECK-FIXES: i = absl::ToInt64Microseconds(d1);
x = static_cast<float>(absl::ToInt64Microseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1);
i = static_cast<int>(absl::ToDoubleNanoseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Nanoseconds(d1);
+ // CHECK-FIXES: i = absl::ToInt64Nanoseconds(d1);
x = static_cast<float>(absl::ToInt64Nanoseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleNanoseconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleNanoseconds(d1);
// Functional-style casts
i = int(absl::ToDoubleHours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Hours(d1);
+ // CHECK-FIXES: i = absl::ToInt64Hours(d1);
x = float(absl::ToInt64Microseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1);
// C-style casts
i = (int) absl::ToDoubleHours(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Hours(d1);
+ // CHECK-FIXES: i = absl::ToInt64Hours(d1);
x = (float) absl::ToInt64Microseconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+ // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1);
// Type aliasing
typedef int FancyInt;
@@ -66,17 +66,17 @@ void f() {
FancyInt j = static_cast<FancyInt>(absl::ToDoubleHours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToInt64Hours(d1);
+ // CHECK-FIXES: FancyInt j = absl::ToInt64Hours(d1);
FancyFloat k = static_cast<FancyFloat>(absl::ToInt64Microseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:18: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+ // CHECK-FIXES: FancyFloat k = absl::ToDoubleMicroseconds(d1);
// Macro handling
// We want to transform things in macro arguments
#define EXTERNAL(x) (x) + 5
i = EXTERNAL(static_cast<int>(absl::ToDoubleSeconds(d1)));
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
- // CHECK-FIXES: EXTERNAL(absl::ToInt64Seconds(d1));
+ // CHECK-FIXES: i = EXTERNAL(absl::ToInt64Seconds(d1));
#undef EXTERNAL
// We don't want to transform this which get split across macro boundaries
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp
index 2f38dbf..9daaa72 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-factory-float %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-factory-float %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -7,26 +7,26 @@ void ConvertFloatTest() {
d = absl::Seconds(60.0);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(60);
+ // CHECK-FIXES: d = absl::Seconds(60);
d = absl::Minutes(300.0);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Minutes(300);
+ // CHECK-FIXES: d = absl::Minutes(300);
d = absl::Milliseconds(1e2);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Milliseconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Milliseconds(100);
+ // CHECK-FIXES: d = absl::Milliseconds(100);
d = absl::Seconds(3.0f);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(3);
+ // CHECK-FIXES: d = absl::Seconds(3);
d = absl::Seconds(3.);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(3);
+ // CHECK-FIXES: d = absl::Seconds(3);
d = absl::Seconds(0x3.p0);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(3);
+ // CHECK-FIXES: d = absl::Seconds(3);
d = absl::Seconds(0x3.p1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(6);
+ // CHECK-FIXES: d = absl::Seconds(6);
// Ignored expressions
@@ -65,7 +65,7 @@ void InTemplate() {
d = absl::Minutes(1.0); // 2
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Minutes(1); // 2
+ // CHECK-FIXES: d = absl::Minutes(1); // 2
}
void Instantiate() {
@@ -78,27 +78,27 @@ void ConvertCastTest() {
d = absl::Seconds(static_cast<double>(5));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(5);
+ // CHECK-FIXES: d = absl::Seconds(5);
d = absl::Minutes(static_cast<float>(5));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Minutes(5);
+ // CHECK-FIXES: d = absl::Minutes(5);
d = absl::Seconds((double) 5);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(5);
+ // CHECK-FIXES: d = absl::Seconds(5);
d = absl::Minutes((float) 5);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Minutes(5);
+ // CHECK-FIXES: d = absl::Minutes(5);
d = absl::Seconds(double(5));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Seconds(5);
+ // CHECK-FIXES: d = absl::Seconds(5);
d = absl::Minutes(float(5));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float]
- // CHECK-FIXES: absl::Minutes(5);
+ // CHECK-FIXES: d = absl::Minutes(5);
// This should not be flagged
d = absl::Seconds(static_cast<int>(5.0));
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp
index dd5f808..7213f5c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-factory-scale %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-factory-scale %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -11,87 +11,87 @@ void ScaleTest() {
// Zeroes
d = absl::Hours(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Minutes(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Milliseconds(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Microseconds(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Nanoseconds(0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(0.0);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(0x0.000001p-126f);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(int{0});
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(int64_t{0});
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
d = absl::Seconds(float{0});
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::ZeroDuration();
+ // CHECK-FIXES: d = absl::ZeroDuration();
// Fold seconds into minutes
d = absl::Seconds(30 * 60);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Minutes(30);
+ // CHECK-FIXES: d = absl::Minutes(30);
d = absl::Seconds(60 * 30);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Minutes(30);
+ // CHECK-FIXES: d = absl::Minutes(30);
// Try a few more exotic multiplications
d = absl::Seconds(60 * 30 * 60);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Minutes(60 * 30);
+ // CHECK-FIXES: d = absl::Minutes(60 * 30);
d = absl::Seconds(1e-3 * 30);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Milliseconds(30);
+ // CHECK-FIXES: d = absl::Milliseconds(30);
d = absl::Milliseconds(30 * 1000);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Seconds(30);
+ // CHECK-FIXES: d = absl::Seconds(30);
d = absl::Milliseconds(30 * 0.001);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Microseconds(30);
+ // CHECK-FIXES: d = absl::Microseconds(30);
// Multiple steps
d = absl::Seconds(5 * 3600);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Hours(5);
+ // CHECK-FIXES: d = absl::Hours(5);
d = absl::Microseconds(5 * 1e6);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Seconds(5);
+ // CHECK-FIXES: d = absl::Seconds(5);
d = absl::Seconds(5 * 1e-6);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Microseconds(5);
+ // CHECK-FIXES: d = absl::Microseconds(5);
d = absl::Microseconds(5 * 1000000);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Seconds(5);
+ // CHECK-FIXES: d = absl::Seconds(5);
// Division
d = absl::Hours(30 / 60.);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Minutes(30);
+ // CHECK-FIXES: d = absl::Minutes(30);
d = absl::Seconds(30 / 1000.);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Milliseconds(30);
+ // CHECK-FIXES: d = absl::Milliseconds(30);
d = absl::Milliseconds(30 / 1e3);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Microseconds(30);
+ // CHECK-FIXES: d = absl::Microseconds(30);
d = absl::Seconds(30 / 1e6);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale]
- // CHECK-FIXES: absl::Microseconds(30);
+ // CHECK-FIXES: d = absl::Microseconds(30);
// None of these should trigger the check
d = absl::Seconds(60);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp
index 167258e3..53b558b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-subtraction %t -- -- -I %S/Inputs
+// RUN: %check_clang_tidy %s abseil-duration-subtraction %t -- -- -I %S/Inputs
#include "absl/time/time.h"
@@ -8,34 +8,34 @@ void f() {
x = absl::ToDoubleSeconds(d) - 1.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(1))
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(1));
x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(d1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(d - d1);
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d - d1);
x = absl::ToDoubleSeconds(d) - 6.5 - 8.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(6.5)) - 8.0;
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(6.5)) - 8.0;
x = absl::ToDoubleHours(d) - 1.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleHours(d - absl::Hours(1))
+ // CHECK-FIXES: x = absl::ToDoubleHours(d - absl::Hours(1));
x = absl::ToDoubleMinutes(d) - 1;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleMinutes(d - absl::Minutes(1))
+ // CHECK-FIXES: x = absl::ToDoubleMinutes(d - absl::Minutes(1));
x = absl::ToDoubleMilliseconds(d) - 9;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleMilliseconds(d - absl::Milliseconds(9))
+ // CHECK-FIXES: x = absl::ToDoubleMilliseconds(d - absl::Milliseconds(9));
x = absl::ToDoubleMicroseconds(d) - 9;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleMicroseconds(d - absl::Microseconds(9))
+ // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d - absl::Microseconds(9));
x = absl::ToDoubleNanoseconds(d) - 42;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleNanoseconds(d - absl::Nanoseconds(42))
+ // CHECK-FIXES: x = absl::ToDoubleNanoseconds(d - absl::Nanoseconds(42));
// We can rewrite the argument of the duration conversion
#define THIRTY absl::Seconds(30)
x = absl::ToDoubleSeconds(THIRTY) - 1.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(THIRTY - absl::Seconds(1))
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(THIRTY - absl::Seconds(1));
#undef THIRTY
// Some other contexts
@@ -46,10 +46,10 @@ void f() {
// A nested occurrence
x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(5));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(5))
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(5));
x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(absl::ToDoubleSeconds(d1)));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction]
- // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(absl::ToDoubleSeconds(d1)))
+ // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(absl::ToDoubleSeconds(d1)));
// These should not match
x = 5 - 6;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp
index f4c69c5..92891b6 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs
+// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs
#include "absl/time/time.h"
@@ -8,86 +8,86 @@ void f() {
// Floating point
d2 = absl::Hours(absl::ToDoubleHours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Minutes(absl::ToDoubleMinutes(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Seconds(absl::ToDoubleSeconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
// Integer point
d2 = absl::Hours(absl::ToInt64Hours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Minutes(absl::ToInt64Minutes(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Seconds(absl::ToInt64Seconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Microseconds(absl::ToInt64Microseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Hours(d1 / absl::Hours(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Minutes(d1 / absl::Minutes(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Seconds(d1 / absl::Seconds(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Milliseconds(d1 / absl::Milliseconds(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Microseconds(d1 / absl::Microseconds(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Nanoseconds(d1 / absl::Nanoseconds(1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Hours(absl::FDivDuration(d1, absl::Hours(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Minutes(absl::FDivDuration(d1, absl::Minutes(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Microseconds(absl::FDivDuration(d1, absl::Microseconds(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
d2 = absl::Nanoseconds(absl::FDivDuration(d1, absl::Nanoseconds(1)));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1
+ // CHECK-FIXES: d2 = d1;
// As macro argument
#define PLUS_FIVE_S(x) x + absl::Seconds(5)
d2 = PLUS_FIVE_S(absl::Seconds(absl::ToInt64Seconds(d1)));
// CHECK-MESSAGES: [[@LINE-1]]:20: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: PLUS_FIVE_S(d1)
+ // CHECK-FIXES: d2 = PLUS_FIVE_S(d1);
#undef PLUS_FIVE_S
// Split by macro: should not change
@@ -103,40 +103,40 @@ void f() {
// Multiplication
d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Microseconds(absl::ToInt64Microseconds(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Seconds(absl::ToInt64Seconds(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Minutes(absl::ToDoubleMinutes(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Hours(absl::ToInt64Hours(d1) * 2);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = d1 * 2
+ // CHECK-FIXES: d2 = d1 * 2;
d2 = absl::Nanoseconds(2 * absl::ToDoubleNanoseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
d2 = absl::Microseconds(2 * absl::ToInt64Microseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
d2 = absl::Milliseconds(2 * absl::ToDoubleMilliseconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
d2 = absl::Seconds(2 * absl::ToInt64Seconds(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
d2 = absl::Minutes(2 * absl::ToDoubleMinutes(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
d2 = absl::Hours(2 * absl::ToInt64Hours(d1));
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
- // CHECK-FIXES: d2 = 2 * d1
+ // CHECK-FIXES: d2 = 2 * d1;
// These should not match
d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1));
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp
index b5e866c..8fa1b1e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-redundant-strcat-calls %t -- -- -isystem %clang_tidy_headers
+// RUN: %check_clang_tidy %s abseil-redundant-strcat-calls %t -- -- -isystem %clang_tidy_headers
#include <string>
namespace absl {
@@ -69,7 +69,7 @@ using absl::StrCat;
void Positives() {
std::string S = StrCat(1, StrCat("A", StrCat(1.1)));
// CHECK-MESSAGES: [[@LINE-1]]:19: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
- // CHECK-FIXES: string S = StrCat(1, "A", 1.1);
+ // CHECK-FIXES: std::string S = StrCat(1, "A", 1.1);
S = StrCat(StrCat(StrCat(StrCat(StrCat(1)))));
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: multiple calls to 'absl::StrCat' can be flattened into a single call
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp
index 4de43ec..ad3ce4c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s abseil-time-comparison %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s abseil-time-comparison %t -- -- -I%S/Inputs
#include "absl/time/time.h"
@@ -11,67 +11,67 @@ void f() {
// Check against the RHS
b = x > absl::ToUnixSeconds(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) > t1;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) > t1;
b = x >= absl::ToUnixSeconds(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) >= t1;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) >= t1;
b = x == absl::ToUnixSeconds(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) == t1;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) == t1;
b = x <= absl::ToUnixSeconds(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) <= t1;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) <= t1;
b = x < absl::ToUnixSeconds(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) < t1;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) < t1;
b = x == absl::ToUnixSeconds(t1 - d2);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixSeconds(x) == t1 - d2;
+ // CHECK-FIXES: b = absl::FromUnixSeconds(x) == t1 - d2;
b = absl::ToUnixSeconds(t1) > absl::ToUnixSeconds(t2);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 > t2;
+ // CHECK-FIXES: b = t1 > t2;
// Check against the LHS
b = absl::ToUnixSeconds(t1) < x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 < absl::FromUnixSeconds(x);
+ // CHECK-FIXES: b = t1 < absl::FromUnixSeconds(x);
b = absl::ToUnixSeconds(t1) <= x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 <= absl::FromUnixSeconds(x);
+ // CHECK-FIXES: b = t1 <= absl::FromUnixSeconds(x);
b = absl::ToUnixSeconds(t1) == x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 == absl::FromUnixSeconds(x);
+ // CHECK-FIXES: b = t1 == absl::FromUnixSeconds(x);
b = absl::ToUnixSeconds(t1) >= x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 >= absl::FromUnixSeconds(x);
+ // CHECK-FIXES: b = t1 >= absl::FromUnixSeconds(x);
b = absl::ToUnixSeconds(t1) > x;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 > absl::FromUnixSeconds(x);
+ // CHECK-FIXES: b = t1 > absl::FromUnixSeconds(x);
// Comparison against zero
b = absl::ToUnixSeconds(t1) < 0.0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 < absl::UnixEpoch();
+ // CHECK-FIXES: b = t1 < absl::UnixEpoch();
b = absl::ToUnixSeconds(t1) < 0;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: t1 < absl::UnixEpoch();
+ // CHECK-FIXES: b = t1 < absl::UnixEpoch();
// Scales other than Seconds
b = x > absl::ToUnixMicros(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixMicros(x) > t1;
+ // CHECK-FIXES: b = absl::FromUnixMicros(x) > t1;
b = x >= absl::ToUnixMillis(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixMillis(x) >= t1;
+ // CHECK-FIXES: b = absl::FromUnixMillis(x) >= t1;
b = x == absl::ToUnixNanos(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixNanos(x) == t1;
+ // CHECK-FIXES: b = absl::FromUnixNanos(x) == t1;
b = x <= absl::ToUnixMinutes(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixMinutes(x) <= t1;
+ // CHECK-FIXES: b = absl::FromUnixMinutes(x) <= t1;
b = x < absl::ToUnixHours(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixHours(x) < t1;
+ // CHECK-FIXES: b = absl::FromUnixHours(x) < t1;
// A long expression
bool some_condition;
@@ -88,20 +88,20 @@ void f() {
int y;
b = (y + 5) * 10 > absl::ToUnixMillis(t1);
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: absl::FromUnixMillis((y + 5) * 10) > t1;
+ // CHECK-FIXES: b = absl::FromUnixMillis((y + 5) * 10) > t1;
// We should still transform the expression inside this macro invocation
#define VALUE_IF(v, e) v ? (e) : 0
int a = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1));
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+ // CHECK-FIXES: int a = VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
#undef VALUE_IF
#define VALUE_IF_2(e) (e)
#define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0)
int a2 = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1));
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the time domain [abseil-time-comparison]
- // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+ // CHECK-FIXES: int a2 = VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
#undef VALUE_IF
#undef VALUE_IF_2
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp
index 82014e8f4..dde0681 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-time-subtraction %t -- -- -I %S/Inputs
+// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-time-subtraction %t -- -- -I %S/Inputs
#include "absl/time/time.h"
@@ -89,7 +89,7 @@ void f() {
#define SECONDS(z) absl::Seconds(z)
d = SECONDS(x - absl::ToUnixSeconds(t));
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction]
- // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t))
+ // CHECK-FIXES: d = SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t));
#undef SECONDS
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp
index b5dfb4f..67fbe3f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
using int64_t = long long;
@@ -49,22 +49,22 @@ void arithmeticOperatorBasicPositive() {
ConvertibleTo<int64_t> c;
d *= (c + c) * c + c;
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c)
+ // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c);
d /= (c + c) * c + c;
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c)
+ // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c);
d = d * c * c;
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
// CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c)
+ // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c);
d = c * d * c;
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
// CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c)
+ // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c);
d = d / c * c;
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
// CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c)
+ // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c);
}
void arithmeticOperatorBasicNegative() {
@@ -407,7 +407,7 @@ template <typename T> void factoryTemplateAndMacro() {
// CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
(void)absl::Nanoseconds(CONVERTIBLE_TMP);
// CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP));
T_CALL_FACTORTY_INSIDE_MACRO;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
}
@@ -424,7 +424,7 @@ void factoryInMacros() {
// CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>())));
(void)absl::Nanoseconds(CONVERTIBLE_TMP);
// CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
- // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
+ // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP));
ONLY_WARN_INSIDE_MACRO_FACTORY;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
factoryTemplateAndMacro<ConvertibleTo<int>>();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp
index 9aaca68..6b5b946 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s altera-struct-pack-align %t -- -header-filter=.*
+// RUN: %check_clang_tidy %s altera-struct-pack-align %t -- -header-filter=.*
// Struct needs both alignment and packing
struct error {
@@ -10,8 +10,7 @@ struct error {
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'error'
// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'error' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error' to 16 bytes
-// CHECK-FIXES: __attribute__((packed))
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16)));
// Struct is explicitly packed, but needs alignment
struct error_packed {
@@ -21,7 +20,7 @@ struct error_packed {
} __attribute__((packed));
// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error_packed' is inefficient due to poor alignment; currently aligned to 1 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error_packed' to 16 bytes
-// CHECK-FIXES: __attribute__((aligned(16)))
+// CHECK-FIXES: } __attribute__((aligned(16))) __attribute__((packed));
// Struct is properly packed, but needs alignment
struct align_only {
@@ -34,7 +33,7 @@ struct align_only {
};
// CHECK-MESSAGES: :[[@LINE-8]]:8: warning: accessing fields in struct 'align_only' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-9]]:8: note: use "__attribute__((aligned(16)))" to align struct 'align_only' to 16 bytes
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((aligned(16)));
// Struct is perfectly packed but wrongly aligned
struct bad_align {
@@ -44,7 +43,7 @@ struct bad_align {
} __attribute__((packed)) __attribute__((aligned(8)));
// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align' to 16 bytes
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16)));
struct bad_align2 {
char a;
@@ -53,7 +52,7 @@ struct bad_align2 {
} __attribute__((packed)) __attribute__((aligned(32)));
// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align2' is inefficient due to poor alignment; currently aligned to 32 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align2' to 16 bytes
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16)));
struct bad_align3 {
char a;
@@ -62,7 +61,7 @@ struct bad_align3 {
} __attribute__((packed)) __attribute__((aligned(4)));
// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align3' is inefficient due to poor alignment; currently aligned to 4 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align3' to 16 bytes
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16)));
// Struct is both perfectly packed and aligned
struct success {
@@ -116,5 +115,4 @@ struct ContainsStructWithNoFields2 {
// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'ContainsStructWithNoFields2'
// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'ContainsStructWithNoFields2' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]
// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'ContainsStructWithNoFields2' to 16 bytes
-// CHECK-FIXES: __attribute__((packed))
-// CHECK-FIXES: __attribute__((aligned(16)));
+// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16)));
diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp
index b2c299b..d1d77d3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-memfd-create %t
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t
#define MFD_ALLOW_SEALING 1
#define __O_CLOEXEC 3
@@ -17,19 +17,19 @@ extern "C" int memfd_create(const char *name, unsigned int flags);
void a() {
memfd_create(NULL, MFD_ALLOW_SEALING);
// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]
- // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)
+ // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);
TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING));
// CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'
- // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));
}
void f() {
memfd_create(NULL, 3);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'
- // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)
+ // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC);
TEMP_FAILURE_RETRY(memfd_create(NULL, 3));
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'
- // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC))
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC));
int flag = 3;
memfd_create(NULL, flag);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp
index 651e469..46e30ab 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-open %t
+// RUN: %check_clang_tidy %s android-cloexec-open %t
#define O_RDWR 1
#define O_EXCL 2
@@ -19,67 +19,67 @@ extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
void a() {
open("filename", O_RDWR);
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: open("filename", O_RDWR | O_CLOEXEC);
TEMP_FAILURE_RETRY(open("filename", O_RDWR));
// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC));
open("filename", O_RDWR | O_EXCL);
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: open("filename", O_RDWR | O_EXCL | O_CLOEXEC);
TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL));
// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'open' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL | O_CLOEXEC));
}
void b() {
open64("filename", O_RDWR);
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: open64("filename", O_RDWR | O_CLOEXEC);
TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
// CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC));
open64("filename", O_RDWR | O_EXCL);
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: open64("filename", O_RDWR | O_EXCL | O_CLOEXEC);
TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL));
// CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'open64' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL | O_CLOEXEC));
}
void c() {
openat(0, "filename", O_RDWR);
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: openat(0, "filename", O_RDWR | O_CLOEXEC);
TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
// CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC));
openat(0, "filename", O_RDWR | O_EXCL);
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: openat(0, "filename", O_RDWR | O_EXCL | O_CLOEXEC);
TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL));
// CHECK-MESSAGES: :[[@LINE-1]]:59: warning: 'openat' should use O_CLOEXEC where
- // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL | O_CLOEXEC));
}
void f() {
open("filename", 3);
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: open("filename", 3 | O_CLOEXEC);
TEMP_FAILURE_RETRY(open("filename", 3));
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", 3 | O_CLOEXEC));
open64("filename", 3);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: open64("filename", 3 | O_CLOEXEC);
TEMP_FAILURE_RETRY(open64("filename", 3));
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", 3 | O_CLOEXEC));
openat(0, "filename", 3);
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: openat(0, "filename", 3 | O_CLOEXEC);
TEMP_FAILURE_RETRY(openat(0, "filename", 3));
// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where
- // CHECK-FIXES: 3 | O_CLOEXEC
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", 3 | O_CLOEXEC));
int flag = 3;
open("filename", flag);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp
index d4d58640..3a25a93 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-socket %t
+// RUN: %check_clang_tidy %s android-cloexec-socket %t
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
@@ -17,25 +17,25 @@ extern "C" int socket(int domain, int type, int protocol);
void a() {
socket(0, SOCK_STREAM, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket]
- // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)
+ // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0);
TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0));
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket'
- // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0))
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0));
socket(0, SOCK_STREAM | SOCK_DGRAM, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket'
- // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)
+ // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0);
TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0));
// CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket'
- // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0))
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0));
}
void f() {
socket(0, 3, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket'
- // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0)
+ // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0);
TEMP_FAILURE_RETRY(socket(0, 3, 0));
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket'
- // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0))
+ // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0));
int flag = 3;
socket(0, flag, 0);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp
index 82b6ea8..81d5cc5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s bugprone-incorrect-enable-shared-from-this %t
+// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-incorrect-enable-shared-from-this %t
// NOLINTBEGIN
namespace std {
@@ -8,15 +8,15 @@ namespace std {
class BadClassExample : std::enable_shared_from_this<BadClassExample> {};
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: public std::enable_shared_from_this<BadClassExample>
+// CHECK-FIXES: class BadClassExample : public std::enable_shared_from_this<BadClassExample> {};
class BadClass2Example : private std::enable_shared_from_this<BadClass2Example> {};
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: public std::enable_shared_from_this<BadClass2Example>
+// CHECK-FIXES: class BadClass2Example : public std::enable_shared_from_this<BadClass2Example> {};
struct BadStructExample : private std::enable_shared_from_this<BadStructExample> {};
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'BadStructExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: public std::enable_shared_from_this<BadStructExample>
+// CHECK-FIXES: struct BadStructExample : public std::enable_shared_from_this<BadStructExample> {};
class GoodClassExample : public std::enable_shared_from_this<GoodClassExample> {};
@@ -29,15 +29,15 @@ class dummy_class2 {};
class BadMultiClassExample : std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 {};
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: public std::enable_shared_from_this<BadMultiClassExample>, dummy_class1
+// CHECK-FIXES: class BadMultiClassExample : public std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 {};
class BadMultiClass2Example : dummy_class1, std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 {};
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: dummy_class1, public std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2
+// CHECK-FIXES: class BadMultiClass2Example : dummy_class1, public std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 {};
class BadMultiClass3Example : dummy_class1, dummy_class2, std::enable_shared_from_this<BadMultiClass3Example> {};
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass3Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this]
-// CHECK-FIXES: dummy_class1, dummy_class2, public std::enable_shared_from_this<BadMultiClass3Example>
+// CHECK-FIXES: class BadMultiClass3Example : dummy_class1, dummy_class2, public std::enable_shared_from_this<BadMultiClass3Example> {};
class ClassBase : public std::enable_shared_from_this<ClassBase> {};
class PrivateInheritClassBase : private ClassBase {};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp
index 66cd6ba..9f45367 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s bugprone-move-forwarding-reference %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -std=c++14-or-later %s bugprone-move-forwarding-reference %t -- -- -fno-delayed-template-parsing
namespace std {
template <typename> struct remove_reference;
@@ -121,5 +121,5 @@ template <typename T, typename U> void f11(U &&SomeU) {
template <typename T> void f12() {
[] (auto&& x) { T SomeT(std::move(x)); };
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference passed to
- // CHECK-FIXES: [] (auto&& x) { T SomeT(std::forward<decltype(x)>(x)); }
+ // CHECK-FIXES: [] (auto&& x) { T SomeT(std::forward<decltype(x)>(x)); };
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c
index b241d68..99d19ec 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
// RUN: -- -I %S/Inputs/not-null-terminated-result
#include "not-null-terminated-result-c.h"
@@ -40,7 +40,7 @@ int bad_strncmp_1(char *str1, const char *str2) {
int length = strlen(str1) + 1;
return strncmp(str1, str2, length);
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str1, str2, length - 1);
+ // CHECK-FIXES: return strncmp(str1, str2, length - 1);
}
int good_strncmp_1(char *str1, const char *str2) {
@@ -51,13 +51,13 @@ int good_strncmp_1(char *str1, const char *str2) {
int bad_strncmp_2(char *str2) {
return strncmp(str2, "foobar", (strlen("foobar") + 1));
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str2, "foobar", (strlen("foobar")));
+ // CHECK-FIXES: return strncmp(str2, "foobar", (strlen("foobar")));
}
int bad_strncmp_3(char *str3) {
return strncmp(str3, "foobar", 1 + strlen("foobar"));
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str3, "foobar", strlen("foobar"));
+ // CHECK-FIXES: return strncmp(str3, "foobar", strlen("foobar"));
}
int good_strncmp_2_3(char *str) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp
index 8124b3b..8465b2b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
// RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result
#include "not-null-terminated-result-cxx.h"
@@ -27,7 +27,7 @@ void bad_memcpy_known_dest(const char *src) {
char dest01[13];
memcpy(dest01, src, strlen(src));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
- // CHECK-FIXES: dest01[14];
+ // CHECK-FIXES: char dest01[14];
// CHECK-FIXES-NEXT: strcpy_s(dest01, src);
}
@@ -44,7 +44,7 @@ void bad_memcpy_full_source_length(std::string src) {
char *dest20 = reinterpret_cast<char *>(malloc(src.size()));
memcpy(dest20, src.data(), src.size());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result]
- // CHECK-FIXES: dest20 = reinterpret_cast<char *>(malloc(src.size() + 1));
+ // CHECK-FIXES: char *dest20 = reinterpret_cast<char *>(malloc(src.size() + 1));
// CHECK-FIXES-NEXT: strcpy(dest20, src.data());
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c
index 366c169..dccf4ed 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
// RUN: -- -I %S/Inputs/not-null-terminated-result
// FIXME: Something wrong with the APInt un/signed conversion on Windows:
@@ -70,13 +70,13 @@ void good_strerror_s(int errno) {
int bad_strncmp_1(char *str0, const char *str1) {
return strncmp(str0, str1, (strlen(str0) + 1));
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str0, str1, (strlen(str0)));
+ // CHECK-FIXES: return strncmp(str0, str1, (strlen(str0)));
}
int bad_strncmp_2(char *str2, const char *str3) {
return strncmp(str2, str3, 1 + strlen(str2));
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str2, str3, strlen(str2));
+ // CHECK-FIXES: return strncmp(str2, str3, strlen(str2));
}
int good_strncmp_1_2(char *str4, const char *str5) {
@@ -86,7 +86,7 @@ int good_strncmp_1_2(char *str4, const char *str5) {
int bad_strncmp_3(char *str6) {
return strncmp(str6, "string", 7);
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: strncmp(str6, "string", 6);
+ // CHECK-FIXES: return strncmp(str6, "string", 6);
}
int good_strncmp_3(char *str7) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp
index 06e2db9..8047db3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp
@@ -1,5 +1,5 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \
-// RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result
+// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -I %S/Inputs/not-null-terminated-result
// FIXME: Something wrong with the APInt un/signed conversion on Windows:
// in 'wcsncmp(wcs6, L"string", 7);' it tries to inject '4294967302' as length.
@@ -58,13 +58,13 @@ void good_wmemmove_s_1(wchar_t *dest, const wchar_t *src) {
int bad_wcsncmp_1(wchar_t *wcs0, const wchar_t *wcs1) {
return wcsncmp(wcs0, wcs1, (wcslen(wcs0) + 1));
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: wcsncmp(wcs0, wcs1, (wcslen(wcs0)));
+ // CHECK-FIXES: return wcsncmp(wcs0, wcs1, (wcslen(wcs0)));
}
int bad_wcsncmp_2(wchar_t *wcs2, const wchar_t *wcs3) {
return wcsncmp(wcs2, wcs3, 1 + wcslen(wcs2));
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: wcsncmp(wcs2, wcs3, wcslen(wcs2));
+ // CHECK-FIXES: return wcsncmp(wcs2, wcs3, wcslen(wcs2));
}
int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) {
@@ -74,7 +74,7 @@ int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) {
int bad_wcsncmp_3(wchar_t *wcs6) {
return wcsncmp(wcs6, L"string", 7);
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result]
- // CHECK-FIXES: wcsncmp(wcs6, L"string", 6);
+ // CHECK-FIXES: return wcsncmp(wcs6, L"string", 6);
}
int good_wcsncmp_3(wchar_t *wcs7) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
index 8db0536..d0dfd97 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-posix-return %t
+// RUN: %check_clang_tidy %s bugprone-posix-return %t
#define NULL nullptr
#define ZERO 0
@@ -43,40 +43,40 @@ extern "C" int pthread_yield(void);
void warningLessThanZero() {
if (posix_fadvise(0, 0, 0, 0) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: the comparison always evaluates to false because posix_fadvise always returns non-negative values
- // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > 0
+ // CHECK-FIXES: if (posix_fadvise(0, 0, 0, 0) > 0) {}
if (posix_fallocate(0, 0, 0) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning:
- // CHECK-FIXES: posix_fallocate(0, 0, 0) > 0
+ // CHECK-FIXES: if (posix_fallocate(0, 0, 0) > 0) {}
if (posix_madvise(NULL, 0, 0) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
- // CHECK-FIXES: posix_madvise(NULL, 0, 0) > 0
+ // CHECK-FIXES: if (posix_madvise(NULL, 0, 0) > 0) {}
if (posix_memalign(NULL, 0, 0) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning:
- // CHECK-FIXES: posix_memalign(NULL, 0, 0) > 0
+ // CHECK-FIXES: if (posix_memalign(NULL, 0, 0) > 0) {}
if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:59: warning:
- // CHECK-FIXES: posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0
+ // CHECK-FIXES: if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0) {}
if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:60: warning:
- // CHECK-FIXES: posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0
+ // CHECK-FIXES: if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0) {}
if (pthread_create(NULL, NULL, NULL, NULL) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: the comparison always evaluates to false because pthread_create always returns non-negative values
- // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > 0
+ // CHECK-FIXES: if (pthread_create(NULL, NULL, NULL, NULL) > 0) {}
if (pthread_attr_setaffinity_np(NULL, 0, NULL) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:50: warning:
- // CHECK-FIXES: pthread_attr_setaffinity_np(NULL, 0, NULL) > 0
+ // CHECK-FIXES: if (pthread_attr_setaffinity_np(NULL, 0, NULL) > 0) {}
if (pthread_attr_setschedpolicy(NULL, 0) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:44: warning:
- // CHECK-FIXES: pthread_attr_setschedpolicy(NULL, 0) > 0)
+ // CHECK-FIXES: if (pthread_attr_setschedpolicy(NULL, 0) > 0) {}
if (pthread_attr_init(NULL) < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning:
- // CHECK-FIXES: pthread_attr_init(NULL) > 0
+ // CHECK-FIXES: if (pthread_attr_init(NULL) > 0) {}
if (pthread_yield() < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
- // CHECK-FIXES: pthread_yield() > 0
- if (0 > pthread_yield() ) {}
+ // CHECK-FIXES: if (pthread_yield() > 0) {}
+ if (0 > pthread_yield()) {}
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning:
- // CHECK-FIXES: 0 < pthread_yield()
+ // CHECK-FIXES: if (0 < pthread_yield()) {}
}
@@ -137,7 +137,7 @@ void warningEqualsNegative() {
void WarningWithMacro() {
if (posix_fadvise(0, 0, 0, 0) < ZERO) {}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
- // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > ZERO
+ // CHECK-FIXES: if (posix_fadvise(0, 0, 0, 0) > ZERO) {}
if (posix_fadvise(0, 0, 0, 0) >= ZERO) {}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
if (posix_fadvise(0, 0, 0, 0) == NEGATIVE_ONE) {}
@@ -150,7 +150,7 @@ void WarningWithMacro() {
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
if (pthread_create(NULL, NULL, NULL, NULL) < ZERO) {}
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
- // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > ZERO
+ // CHECK-FIXES: if (pthread_create(NULL, NULL, NULL, NULL) > ZERO) {}
if (pthread_create(NULL, NULL, NULL, NULL) >= ZERO) {}
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
if (pthread_create(NULL, NULL, NULL, NULL) == NEGATIVE_ONE) {}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp
index 050e38d..b85ba02 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-stringview-nullptr -std=c++17 %t
+// RUN: %check_clang_tidy %s bugprone-stringview-nullptr -std=c++17 %t
namespace std {
@@ -148,7 +148,8 @@ void temporary_construction() /* a */ {
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(std::string_view()) /* a4 */;
- (void)(std::string_view({})) /* a5 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(std::string_view({})) /* a5 */;
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(std::string_view()) /* a5 */;
}
@@ -171,7 +172,8 @@ void temporary_construction() /* a */ {
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(std::string_view{}) /* a9 */;
- (void)(std::string_view{{}}) /* a10 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(std::string_view{{}}) /* a10 */;
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(std::string_view{}) /* a10 */;
}
@@ -202,7 +204,8 @@ void temporary_construction() /* a */ {
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
// CHECK-FIXES: (void)((std::string_view){}) /* a16 */;
- (void)((std::string_view){{}}) /* a17 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)((std::string_view){{}}) /* a17 */;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default
// CHECK-FIXES: (void)((std::string_view){}) /* a17 */;
@@ -230,7 +233,8 @@ void temporary_construction() /* a */ {
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
// CHECK-FIXES: (void)((const std::string_view){}) /* a23 */;
- (void)((const std::string_view){{}}) /* a24 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)((const std::string_view){{}}) /* a24 */;
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
// CHECK-FIXES: (void)((const std::string_view){}) /* a24 */;
}
@@ -316,7 +320,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b13 = {};
- std::string_view b14 = {{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ std::string_view b14 = {{}};
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b14 = {};
@@ -336,7 +341,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b18 = {};
- const std::string_view b19 = {{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ const std::string_view b19 = {{}};
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b19 = {};
}
@@ -382,7 +388,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b28;
- std::string_view b29({}); // Default `const CharT*`
+ // Default `const CharT*`
+ std::string_view b29({});
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b29;
@@ -402,7 +409,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b33;
- const std::string_view b34({}); // Default `const CharT*`
+ // Default `const CharT*`
+ const std::string_view b34({});
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b34;
}
@@ -448,7 +456,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b43{};
- std::string_view b44{{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ std::string_view b44{{}};
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view b44{};
@@ -468,7 +477,8 @@ void stack_construction() /* b */ {
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b48{};
- const std::string_view b49{{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ const std::string_view b49{{}};
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view b49{};
}
@@ -557,7 +567,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view c13 = {};
- std::string_view c14 = {{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ std::string_view c14 = {{}};
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view c14 = {};
@@ -577,7 +588,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view c18 = {};
- const std::string_view c19 = {{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ const std::string_view c19 = {{}};
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view c19 = {};
};
@@ -621,7 +633,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view c28{};
- std::string_view c29{{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ std::string_view c29{{}};
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default
// CHECK-FIXES: std::string_view c29{};
@@ -641,7 +654,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view c33{};
- const std::string_view c34{{}}; // Default `const CharT*`
+ // Default `const CharT*`
+ const std::string_view c34{{}};
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default
// CHECK-FIXES: const std::string_view c34{};
};
@@ -694,7 +708,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
// CHECK-FIXES: c43(),
- c44({}) { // Default `const CharT*`
+ // Default `const CharT*`
+ c44({}) {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
// CHECK-FIXES: c44() {
}
@@ -754,7 +769,8 @@ void field_construction() /* c */ {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
// CHECK-FIXES: c53{},
- c54{{}} { // Default `const CharT*`
+ // Default `const CharT*`
+ c54{{}} {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default
// CHECK-FIXES: c54{} {
}
@@ -852,7 +868,8 @@ void default_argument_construction() /* d */ {
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
// CHECK-FIXES: void d13(std::string_view sv = {});
- void d14(std::string_view sv = {{}}); // Default `const CharT*`
+ // Default `const CharT*`
+ void d14(std::string_view sv = {{}});
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default
// CHECK-FIXES: void d14(std::string_view sv = {});
@@ -872,7 +889,8 @@ void default_argument_construction() /* d */ {
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: constructing{{.*}}default
// CHECK-FIXES: void d18(const std::string_view sv = {});
- void d19(const std::string_view sv = {{}}); // Default `const CharT*`
+ // Default `const CharT*`
+ void d19(const std::string_view sv = {{}});
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: constructing{{.*}}default
// CHECK-FIXES: void d19(const std::string_view sv = {});
}
@@ -920,7 +938,8 @@ void heap_construction() /* e */ {
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new std::string_view()) /* e4 */;
- (void)(new std::string_view({})) /* e5 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(new std::string_view({})) /* e5 */;
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new std::string_view()) /* e5 */;
@@ -940,7 +959,8 @@ void heap_construction() /* e */ {
// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new const std::string_view()) /* e9 */;
- (void)(new const std::string_view({})) /* e10 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(new const std::string_view({})) /* e10 */;
// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new const std::string_view()) /* e10 */;
}
@@ -986,7 +1006,8 @@ void heap_construction() /* e */ {
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new std::string_view{}) /* e19 */;
- (void)(new std::string_view{{}}) /* e20 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(new std::string_view{{}}) /* e20 */;
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new std::string_view{}) /* e20 */;
@@ -1006,7 +1027,8 @@ void heap_construction() /* e */ {
// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new const std::string_view{}) /* e24 */;
- (void)(new const std::string_view{{}}) /* e25 */; // Default `const CharT*`
+ // Default `const CharT*`
+ (void)(new const std::string_view{{}}) /* e25 */;
// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default
// CHECK-FIXES: (void)(new const std::string_view{}) /* e25 */;
}
@@ -1054,7 +1076,8 @@ void function_argument_initialization() /* f */ {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: passing{{.*}}empty string
// CHECK-FIXES: function("") /* f4 */;
- function({{}}) /* f5 */; // Default `const CharT*`
+ // Default `const CharT*`
+ function({{}}) /* f5 */;
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: passing{{.*}}empty string
// CHECK-FIXES: function("") /* f5 */;
}
@@ -1102,7 +1125,8 @@ void assignment(std::string_view sv) /* g */ {
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: assignment{{.*}}default
// CHECK-FIXES: sv = {} /* g4 */;
- sv = {{}} /* g5 */; // Default `const CharT*`
+ // Default `const CharT*`
+ sv = {{}} /* g5 */;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: assignment{{.*}}default
// CHECK-FIXES: sv = {} /* g5 */;
}
@@ -1150,7 +1174,8 @@ void pointer_assignment(std::string_view *sv_ptr) /* h */ {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: assignment{{.*}}default
// CHECK-FIXES: *sv_ptr = {} /* h4 */;
- *sv_ptr = {{}} /* h5 */; // Default `const CharT*`
+ // Default `const CharT*`
+ *sv_ptr = {{}} /* h5 */;
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: assignment{{.*}}default
// CHECK-FIXES: *sv_ptr = {} /* h5 */;
}
@@ -1566,7 +1591,8 @@ void return_statement() /* q */ {
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing{{.*}}default
// CHECK-FIXES: []() -> SV { return {}; } /* q6 */;
- []() -> SV { return {{}}; } /* q7 */; // Default `const CharT*`
+ // Default `const CharT*`
+ []() -> SV { return {{}}; } /* q7 */;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing{{.*}}default
// CHECK-FIXES: []() -> SV { return {}; } /* q7 */;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp
index d670fa9..399018e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-suspicious-string-compare %t -- \
+// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
// RUN: -config='{CheckOptions: \
// RUN: {bugprone-suspicious-string-compare.WarnOnImplicitComparison: true, \
// RUN: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison: true}}' \
@@ -117,187 +117,187 @@ int test_implicit_compare_with_functions() {
if (memcmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memcmp' is called without explicitly comparing result
- // CHECK-FIXES: memcmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (memcmp(A, "a", 1) != 0)
if (wmemcmp(W, L"a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wmemcmp' is called without explicitly comparing result
- // CHECK-FIXES: wmemcmp(W, L"a", 1) != 0)
+ // CHECK-FIXES: if (wmemcmp(W, L"a", 1) != 0)
if (memicmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memicmp' is called without explicitly comparing result
- // CHECK-FIXES: memicmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (memicmp(A, "a", 1) != 0)
if (_memicmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp' is called without explicitly comparing result
- // CHECK-FIXES: _memicmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (_memicmp(A, "a", 1) != 0)
if (_memicmp_l(A, "a", 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _memicmp_l(A, "a", 1, locale) != 0)
+ // CHECK-FIXES: if (_memicmp_l(A, "a", 1, locale) != 0)
if (strcmp(A, "a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
- // CHECK-FIXES: strcmp(A, "a") != 0)
+ // CHECK-FIXES: if (strcmp(A, "a") != 0)
if (strncmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result
- // CHECK-FIXES: strncmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (strncmp(A, "a", 1) != 0)
if (strcasecmp(A, "a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcasecmp' is called without explicitly comparing result
- // CHECK-FIXES: strcasecmp(A, "a") != 0)
+ // CHECK-FIXES: if (strcasecmp(A, "a") != 0)
if (strncasecmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncasecmp' is called without explicitly comparing result
- // CHECK-FIXES: strncasecmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (strncasecmp(A, "a", 1) != 0)
if (stricmp(A, "a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'stricmp' is called without explicitly comparing result
- // CHECK-FIXES: stricmp(A, "a") != 0)
+ // CHECK-FIXES: if (stricmp(A, "a") != 0)
if (strcmpi(A, "a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmpi' is called without explicitly comparing result
- // CHECK-FIXES: strcmpi(A, "a") != 0)
+ // CHECK-FIXES: if (strcmpi(A, "a") != 0)
if (_stricmp(A, "a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp' is called without explicitly comparing result
- // CHECK-FIXES: _stricmp(A, "a") != 0)
+ // CHECK-FIXES: if (_stricmp(A, "a") != 0)
if (strnicmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strnicmp' is called without explicitly comparing result
- // CHECK-FIXES: strnicmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (strnicmp(A, "a", 1) != 0)
if (_strnicmp(A, "a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp' is called without explicitly comparing result
- // CHECK-FIXES: _strnicmp(A, "a", 1) != 0)
+ // CHECK-FIXES: if (_strnicmp(A, "a", 1) != 0)
if (_stricmp_l(A, "a", locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _stricmp_l(A, "a", locale) != 0)
+ // CHECK-FIXES: if (_stricmp_l(A, "a", locale) != 0)
if (_strnicmp_l(A, "a", 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _strnicmp_l(A, "a", 1, locale) != 0)
+ // CHECK-FIXES: if (_strnicmp_l(A, "a", 1, locale) != 0)
if (wcscmp(W, L"a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscmp' is called without explicitly comparing result
- // CHECK-FIXES: wcscmp(W, L"a") != 0)
+ // CHECK-FIXES: if (wcscmp(W, L"a") != 0)
if (wcsncmp(W, L"a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsncmp' is called without explicitly comparing result
- // CHECK-FIXES: wcsncmp(W, L"a", 1) != 0)
+ // CHECK-FIXES: if (wcsncmp(W, L"a", 1) != 0)
if (wcscasecmp(W, L"a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscasecmp' is called without explicitly comparing result
- // CHECK-FIXES: wcscasecmp(W, L"a") != 0)
+ // CHECK-FIXES: if (wcscasecmp(W, L"a") != 0)
if (wcsicmp(W, L"a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsicmp' is called without explicitly comparing result
- // CHECK-FIXES: wcsicmp(W, L"a") != 0)
+ // CHECK-FIXES: if (wcsicmp(W, L"a") != 0)
if (_wcsicmp(W, L"a"))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp' is called without explicitly comparing result
- // CHECK-FIXES: _wcsicmp(W, L"a") != 0)
+ // CHECK-FIXES: if (_wcsicmp(W, L"a") != 0)
if (_wcsicmp_l(W, L"a", locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _wcsicmp_l(W, L"a", locale) != 0)
+ // CHECK-FIXES: if (_wcsicmp_l(W, L"a", locale) != 0)
if (wcsnicmp(W, L"a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsnicmp' is called without explicitly comparing result
- // CHECK-FIXES: wcsnicmp(W, L"a", 1) != 0)
+ // CHECK-FIXES: if (wcsnicmp(W, L"a", 1) != 0)
if (_wcsnicmp(W, L"a", 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp' is called without explicitly comparing result
- // CHECK-FIXES: _wcsnicmp(W, L"a", 1) != 0)
+ // CHECK-FIXES: if (_wcsnicmp(W, L"a", 1) != 0)
if (_wcsnicmp_l(W, L"a", 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _wcsnicmp_l(W, L"a", 1, locale) != 0)
+ // CHECK-FIXES: if (_wcsnicmp_l(W, L"a", 1, locale) != 0)
if (_mbscmp(U, V))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbscmp(U, V) != 0)
+ // CHECK-FIXES: if (_mbscmp(U, V) != 0)
if (_mbsncmp(U, V, 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbsncmp(U, V, 1) != 0)
+ // CHECK-FIXES: if (_mbsncmp(U, V, 1) != 0)
if (_mbsnbcmp(U, V, 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnbcmp(U, V, 1) != 0)
+ // CHECK-FIXES: if (_mbsnbcmp(U, V, 1) != 0)
if (_mbsnbicmp(U, V, 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnbicmp(U, V, 1) != 0)
+ // CHECK-FIXES: if (_mbsnbicmp(U, V, 1) != 0)
if (_mbsicmp(U, V))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbsicmp(U, V) != 0)
+ // CHECK-FIXES: if (_mbsicmp(U, V) != 0)
if (_mbsnicmp(U, V, 1))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnicmp(U, V, 1) != 0)
+ // CHECK-FIXES: if (_mbsnicmp(U, V, 1) != 0)
if (_mbscmp_l(U, V, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbscmp_l(U, V, locale) != 0)
+ // CHECK-FIXES: if (_mbscmp_l(U, V, locale) != 0)
if (_mbsncmp_l(U, V, 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbsncmp_l(U, V, 1, locale) != 0)
+ // CHECK-FIXES: if (_mbsncmp_l(U, V, 1, locale) != 0)
if (_mbsicmp_l(U, V, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbsicmp_l(U, V, locale) != 0)
+ // CHECK-FIXES: if (_mbsicmp_l(U, V, locale) != 0)
if (_mbsnicmp_l(U, V, 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnicmp_l(U, V, 1, locale) != 0)
+ // CHECK-FIXES: if (_mbsnicmp_l(U, V, 1, locale) != 0)
if (_mbsnbcmp_l(U, V, 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnbcmp_l(U, V, 1, locale) != 0)
+ // CHECK-FIXES: if (_mbsnbcmp_l(U, V, 1, locale) != 0)
if (_mbsnbicmp_l(U, V, 1, locale))
return 0;
// CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp_l' is called without explicitly comparing result
- // CHECK-FIXES: _mbsnbicmp_l(U, V, 1, locale) != 0)
+ // CHECK-FIXES: if (_mbsnbicmp_l(U, V, 1, locale) != 0)
return 1;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp
index 3d21396..985ebc2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-swapped-arguments %t
+// RUN: %check_clang_tidy %s bugprone-swapped-arguments %t
void F(int, double);
@@ -9,7 +9,7 @@ void G(T a, U b) {
F(a, b); // no-warning
F(2.0, 4);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'double' to 'int' followed by argument converted from 'int' to 'double', potentially swapped arguments.
-// CHECK-FIXES: F(4, 2.0)
+// CHECK-FIXES: F(4, 2.0);
}
void funShortFloat(short, float);
@@ -20,7 +20,7 @@ void funBoolFloat(bool, float);
void foo() {
F(1.0, 3);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'double' to 'int' followed by argument converted from 'int' to 'double', potentially swapped arguments.
-// CHECK-FIXES: F(3, 1.0)
+// CHECK-FIXES: F(3, 1.0);
#define M(x, y) x##y()
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp
index e8d7db1..2f5e6c7 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-prefer-member-initializer %t -- -- -fcxx-exceptions
+// RUN: %check_clang_tidy %s cppcoreguidelines-prefer-member-initializer %t -- -- -fcxx-exceptions
extern void __assert_fail (__const char *__assertion, __const char *__file,
unsigned int __line, __const char *__function)
@@ -398,7 +398,7 @@ public:
}
explicit Complex19(int) {
- // CHECK-FIXES: Complex19(int) : n(12) {
+ // CHECK-FIXES: explicit Complex19(int) : n(12) {
n = 12;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer]
// CHECK-FIXES: {{^\ *$}}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp
index 6fd5227..057ab3b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-bounds-constant-array-index %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
typedef __SIZE_TYPE__ size_t;
@@ -151,7 +151,6 @@ void g() {
for (int i = 0; i < 10; ++i) {
a[i] = i;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression
- // CHECK-FIXES: gsl::at(a, i) = i;
gsl::at(a, i) = i; // OK, gsl::at() instead of []
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp
index c15d444..d1c45ec 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: {cppcoreguidelines-pro-type-member-init.UseAssignment: true}}" -- -fsigned-char
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: {cppcoreguidelines-pro-type-member-init.UseAssignment: true}}" -- -fsigned-char
struct T {
int i;
@@ -30,7 +30,7 @@ struct S {
double d;
// CHECK-FIXES: double d = 0.0;
long double ld;
- // CHECK-FIXES: double ld = 0.0L;
+ // CHECK-FIXES: long double ld = 0.0L;
int *ptr;
// CHECK-FIXES: int *ptr = nullptr;
T t;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp
index 8896732..890d1d2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11,c++14,c++17 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing
// FIXME: Fix the checker to work in C++20 mode.
struct PositiveFieldBeforeConstructor {
@@ -105,7 +105,7 @@ template <class T> class NegativeTemplateConstructor {
int FIELD; \
}; \
// Ensure FIELD is not initialized since fixes inside of macros are disabled.
-// CHECK-FIXES: int FIELD;
+// CHECK-FIXES: int FIELD; {{\\}}
UNINITIALIZED_FIELD_IN_MACRO_BODY(F);
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
@@ -429,7 +429,7 @@ template struct PositiveTemplateVirtualDestructor<int>;
virtual ~UninitializedFieldVirtual##FIELD() {} \
}; \
// Ensure FIELD is not initialized since fixes inside of macros are disabled.
-// CHECK-FIXES: int FIELD;
+// CHECK-FIXES: int FIELD; {{\\}}
UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(F);
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp
index 44d0251..725a709 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-virtual-class-destructor %t -- --fix-notes
+// RUN: %check_clang_tidy %s cppcoreguidelines-virtual-class-destructor %t -- --fix-notes
// CHECK-MESSAGES: :[[@LINE+4]]:8: warning: destructor of 'PrivateVirtualBaseStruct' is private and prevents using the type [cppcoreguidelines-virtual-class-destructor]
// CHECK-MESSAGES: :[[@LINE+3]]:8: note: make it public and virtual
@@ -163,7 +163,7 @@ protected:
// CHECK-FIXES: class OverridingDerivedClass : ProtectedNonVirtualClass {
// CHECK-FIXES-NEXT: public:
// CHECK-FIXES-NEXT: virtual ~OverridingDerivedClass() = default;
-// CHECK-FIXES-NEXT: void f() override;
+// CHECK-FIXES-NEXT: void f() override; // is implicitly virtual
// CHECK-FIXES-NEXT: };
class OverridingDerivedClass : ProtectedNonVirtualClass {
public:
@@ -186,7 +186,7 @@ class NonOverridingDerivedClass : ProtectedNonVirtualClass {
// CHECK-MESSAGES: :[[@LINE+5]]:8: note: make it public and virtual
// CHECK-FIXES: struct OverridingDerivedStruct : ProtectedNonVirtualBaseStruct {
// CHECK-FIXES-NEXT: virtual ~OverridingDerivedStruct() = default;
-// CHECK-FIXES-NEXT: void f() override;
+// CHECK-FIXES-NEXT: void f() override; // is implicitly virtual
// CHECK-FIXES-NEXT: };
struct OverridingDerivedStruct : ProtectedNonVirtualBaseStruct {
void f() override; // is implicitly virtual
@@ -289,26 +289,18 @@ protected:
virtual CONCAT(~Foo, Bar2()); // FIXME: We should have a fixit for this.
};
-// CHECK-MESSAGES: :[[@LINE+6]]:7: warning: destructor of 'FooBar3' is protected and virtual [cppcoreguidelines-virtual-class-destructor]
-// CHECK-MESSAGES: :[[@LINE+5]]:7: note: make it protected and non-virtual
-// CHECK-FIXES: class FooBar3 {
-// CHECK-FIXES-NEXT: protected:
-// CHECK-FIXES-NEXT: ~FooBar3();
-// CHECK-FIXES-NEXT: };
+// CHECK-MESSAGES: :[[@LINE+2]]:7: warning: destructor of 'FooBar3' is protected and virtual [cppcoreguidelines-virtual-class-destructor]
+// CHECK-MESSAGES: :[[@LINE+1]]:7: note: make it protected and non-virtual
class FooBar3 {
protected:
- CONCAT(vir, tual) ~FooBar3();
+ CONCAT(vir, tual) ~FooBar3(); // FIXME: We should have a fixit for this.
};
-// CHECK-MESSAGES: :[[@LINE+6]]:7: warning: destructor of 'FooBar4' is protected and virtual [cppcoreguidelines-virtual-class-destructor]
-// CHECK-MESSAGES: :[[@LINE+5]]:7: note: make it protected and non-virtual
-// CHECK-FIXES: class FooBar4 {
-// CHECK-FIXES-NEXT: protected:
-// CHECK-FIXES-NEXT: ~CONCAT(Foo, Bar4());
-// CHECK-FIXES-NEXT: };
+// CHECK-MESSAGES: :[[@LINE+2]]:7: warning: destructor of 'FooBar4' is protected and virtual [cppcoreguidelines-virtual-class-destructor]
+// CHECK-MESSAGES: :[[@LINE+1]]:7: note: make it protected and non-virtual
class FooBar4 {
protected:
- CONCAT(vir, tual) ~CONCAT(Foo, Bar4());
+ CONCAT(vir, tual) ~CONCAT(Foo, Bar4()); // FIXME: We should have a fixit for this.
};
// CHECK-MESSAGES: :[[@LINE+3]]:7: warning: destructor of 'FooBar5' is protected and virtual [cppcoreguidelines-virtual-class-destructor]
diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp
index 94d5462..ea77272 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s google-build-explicit-make-pair %t
+// RUN: %check_clang_tidy %s google-build-explicit-make-pair %t
namespace std {
template <class T1, class T2>
@@ -17,7 +17,7 @@ void templ(T a, T b) {
std::make_pair<T, unsigned>(a, b);
std::make_pair<int, int>(1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
-// CHECK-FIXES: std::make_pair(1, 2)
+// CHECK-FIXES: std::make_pair(1, 2);
}
template <typename T>
@@ -26,15 +26,15 @@ int t();
void test(int i) {
std::make_pair<int, int>(i, i);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
-// CHECK-FIXES: std::make_pair(i, i)
+// CHECK-FIXES: std::make_pair(i, i);
std::make_pair<unsigned, int>(i, i);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
-// CHECK-FIXES: std::pair<unsigned, int>(i, i)
+// CHECK-FIXES: std::pair<unsigned, int>(i, i);
std::make_pair<int, unsigned>(i, i);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
-// CHECK-FIXES: std::pair<int, unsigned>(i, i)
+// CHECK-FIXES: std::pair<int, unsigned>(i, i);
#define M std::make_pair<int, unsigned>(i, i);
M
diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m b/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m
index f62af8f..9d02702 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m
+++ b/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s google-objc-avoid-nsobject-new %t
+// RUN: %check_clang_tidy %s google-objc-avoid-nsobject-new %t
@interface NSObject
+ (instancetype)new;
@@ -25,18 +25,18 @@
void CheckSpecificInitRecommendations(void) {
NSObject *object = [NSObject new];
// CHECK-MESSAGES: [[@LINE-1]]:22: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
- // CHECK-FIXES: [NSObject alloc] init];
+ // CHECK-FIXES: NSObject *object = {{[[][[]}}NSObject alloc] init];
NSDate *correctDate = [NSDate date];
NSDate *incorrectDate = [NSDate new];
// CHECK-MESSAGES: [[@LINE-1]]:27: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
- // CHECK-FIXES: [NSDate date];
+ // CHECK-FIXES: NSDate *incorrectDate = [NSDate date];
NSObject *macroCreated = ALLOCATE_OBJECT(NSObject); // Shouldn't warn on macros.
NSMutableDictionary *dict = [NSMutableDictionary<NSString *, NSString *> new];
// CHECK-MESSAGES: [[@LINE-1]]:31: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
- // CHECK-FIXES: [NSMutableDictionary<NSString *, NSString *> alloc] init];
+ // CHECK-FIXES: NSMutableDictionary *dict = {{[[][[]}}NSMutableDictionary<NSString *, NSString *> alloc] init];
}
@interface Foo : NSObject
diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp
index cf24d2d..edb11b9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s google-upgrade-googletest-case %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy %s google-upgrade-googletest-case %t -- -- -I%S/Inputs
// RUN: %check_clang_tidy -check-suffix=NOSUITE %s google-upgrade-googletest-case %t -- -- -DNOSUITE -I%S/Inputs/gtest/nosuite
#include "gtest/gtest.h"
@@ -89,12 +89,14 @@ public:
// CHECK-FIXES: static void TearDownTestSuite();
};
-template <typename T> void FooTypedTest<T>::SetUpTestCase() {}
-// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case'
+template <typename T>
+void FooTypedTest<T>::SetUpTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
// CHECK-FIXES: void FooTypedTest<T>::SetUpTestSuite() {}
-template <typename T> void FooTypedTest<T>::TearDownTestCase() {}
-// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case'
+template <typename T>
+void FooTypedTest<T>::TearDownTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
// CHECK-FIXES: void FooTypedTest<T>::TearDownTestSuite() {}
class BarTest : public testing::Test {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp
index 6b4c917..4edcc05 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t
+// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t
struct X;
struct Y;
@@ -79,7 +79,7 @@ bool foo(Y *y, Z *z) {
break;
} while (cast<X>(y));
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional
- // CHECK-FIXES: while (isa<X>(y));
+ // CHECK-FIXES: } while (isa<X>(y));
if (dyn_cast<X>(y))
return true;
@@ -100,7 +100,7 @@ bool foo(Y *y, Z *z) {
break;
} while (dyn_cast<X>(y));
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used
- // CHECK-FIXES: while (isa<X>(y));
+ // CHECK-FIXES: } while (isa<X>(y));
if (y && isa<X>(y))
return true;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp
index 5dd3a9d..07b4f33 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s llvm-prefer-register-over-unsigned %t
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t
namespace llvm {
class Register {
@@ -23,8 +23,8 @@ llvm::RegisterLike getRegLike();
void apply_1() {
unsigned Reg1 = getReg();
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg1' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned]
- // CHECK-FIXES: apply_1()
- // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
+ // CHECK-FIXES: void apply_1() {
+ // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
}
void apply_2() {
@@ -34,110 +34,110 @@ void apply_2() {
// DeclContext for the function so we can't elide the llvm:: in this
// case. Fortunately, it doesn't actually occur in the LLVM code base.
// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: variable 'Reg2' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned]
- // CHECK-FIXES: apply_2()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: llvm::Register Reg2 = getReg();
+ // CHECK-FIXES: void apply_2() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: llvm::Register Reg2 = getReg();
}
namespace llvm {
void apply_3() {
unsigned Reg3 = getReg();
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg3' declared as 'unsigned int'; use 'Register' instead [llvm-prefer-register-over-unsigned]
- // CHECK-FIXES: apply_3()
- // CHECK-FIXES-NEXT: Register Reg3 = getReg();
+ // CHECK-FIXES: void apply_3() {
+ // CHECK-FIXES-NEXT: Register Reg3 = getReg();
}
} // end namespace llvm
void done_1() {
llvm::Register Reg1 = getReg();
- // CHECK-FIXES: done_1()
- // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
+ // CHECK-FIXES: void done_1() {
+ // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
}
void done_2() {
using namespace llvm;
Register Reg2 = getReg();
- // CHECK-FIXES: done_2()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: Register Reg2 = getReg();
+ // CHECK-FIXES: void done_2() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: Register Reg2 = getReg();
}
namespace llvm {
void done_3() {
Register Reg3 = getReg();
- // CHECK-FIXES: done_3()
- // CHECK-FIXES-NEXT: Register Reg3 = getReg();
+ // CHECK-FIXES: void done_3() {
+ // CHECK-FIXES-NEXT: Register Reg3 = getReg();
}
} // end namespace llvm
void do_nothing_1() {
unsigned Reg1 = getRegLike();
- // CHECK-FIXES: do_nothing_1()
- // CHECK-FIXES-NEXT: unsigned Reg1 = getRegLike();
+ // CHECK-FIXES: void do_nothing_1() {
+ // CHECK-FIXES-NEXT: unsigned Reg1 = getRegLike();
}
void do_nothing_2() {
using namespace llvm;
unsigned Reg2 = getRegLike();
- // CHECK-FIXES: do_nothing_2()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: unsigned Reg2 = getRegLike();
+ // CHECK-FIXES: void do_nothing_2() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: unsigned Reg2 = getRegLike();
}
namespace llvm {
void do_nothing_3() {
unsigned Reg3 = getRegLike();
- // CHECK-FIXES: do_nothing_3()
- // CHECK-FIXES-NEXT: unsigned Reg3 = getRegLike();
+ // CHECK-FIXES: void do_nothing_3() {
+ // CHECK-FIXES-NEXT: unsigned Reg3 = getRegLike();
}
} // end namespace llvm
void fn1(llvm::Register R);
void do_nothing_4() {
fn1(getReg());
- // CHECK-FIXES: do_nothing_4()
- // CHECK-FIXES-NEXT: fn1(getReg());
+ // CHECK-FIXES: void do_nothing_4() {
+ // CHECK-FIXES-NEXT: fn1(getReg());
}
void fn2(unsigned R);
void do_nothing_5() {
fn2(getReg());
- // CHECK-FIXES: do_nothing_5()
- // CHECK-FIXES-NEXT: fn2(getReg());
+ // CHECK-FIXES: void do_nothing_5() {
+ // CHECK-FIXES-NEXT: fn2(getReg());
}
void do_nothing_6() {
using namespace llvm;
Register Reg6{getReg()};
- // CHECK-FIXES: do_nothing_6()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: Register Reg6{getReg()};
+ // CHECK-FIXES: void do_nothing_6() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: Register Reg6{getReg()};
}
void do_nothing_7() {
using namespace llvm;
Register Reg7;
Reg7.Reg = getReg();
- // CHECK-FIXES: do_nothing_7()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: Register Reg7;
- // CHECK-FIXES-NEXT: Reg7.Reg = getReg();
+ // CHECK-FIXES: void do_nothing_7() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: Register Reg7;
+ // CHECK-FIXES-NEXT: Reg7.Reg = getReg();
}
void do_nothing_8() {
using namespace llvm;
RegisterLike Reg8{getReg()};
- // CHECK-FIXES: do_nothing_8()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: RegisterLike Reg8{getReg()};
+ // CHECK-FIXES: void do_nothing_8() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: RegisterLike Reg8{getReg()};
}
void do_nothing_9() {
using namespace llvm;
RegisterLike Reg9;
Reg9.Reg = getReg();
- // CHECK-FIXES: do_nothing_9()
- // CHECK-FIXES-NEXT: using namespace llvm;
- // CHECK-FIXES-NEXT: RegisterLike Reg9;
- // CHECK-FIXES-NEXT: Reg9.Reg = getReg();
+ // CHECK-FIXES: void do_nothing_9() {
+ // CHECK-FIXES-NEXT: using namespace llvm;
+ // CHECK-FIXES-NEXT: RegisterLike Reg9;
+ // CHECK-FIXES-NEXT: Reg9.Reg = getReg();
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp
index 05c9971..be64029 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s llvm-twine-local %t
+// RUN: %check_clang_tidy %s llvm-twine-local %t
namespace llvm {
class Twine {
@@ -24,7 +24,7 @@ int main() {
const Twine t = Twine("a") + "b" + Twine(42);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t = (Twine("a") + "b" + Twine(42)).str();
+// CHECK-FIXES: const std::string t = (Twine("a") + "b" + Twine(42)).str();
foo(Twine("a") + "b");
Twine Prefix = false ? "__INT_FAST" : "__UINT_FAST";
@@ -35,31 +35,31 @@ int main() {
const Twine t2 = Twine();
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t2 = (Twine()).str();
+// CHECK-FIXES: const std::string t2 = (Twine()).str();
foo(Twine() + "b");
const Twine t3 = Twine(42);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t3 = (Twine(42)).str();
+// CHECK-FIXES: const std::string t3 = (Twine(42)).str();
const Twine t4 = Twine(42) + "b";
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str();
+// CHECK-FIXES: const std::string t4 = (Twine(42) + "b").str();
const Twine t5 = Twine() + "b";
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t5 = (Twine() + "b").str();
+// CHECK-FIXES: const std::string t5 = (Twine() + "b").str();
const Twine t6 = true ? Twine() : Twine(42);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str();
+// CHECK-FIXES: const std::string t6 = (true ? Twine() : Twine(42)).str();
const Twine t7 = false ? Twine() : Twine("b");
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
-// CHECK-FIXES: std::string t7 = (false ? Twine() : Twine("b")).str();
+// CHECK-FIXES: const std::string t7 = (false ? Twine() : Twine("b")).str();
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp
index 0971a16..b57eab0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s llvm-use-new-mlir-op-builder %t
+// RUN: %check_clang_tidy %s llvm-use-new-mlir-op-builder %t
namespace mlir {
class Location {};
@@ -36,25 +36,24 @@ struct NamedOp {
template <typename T>
void g(mlir::OpBuilder &b) {
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
- // CHECK-FIXES: T::create(b, b.getUnknownLoc(), "gaz")
+ // CHECK-FIXES: T::create(b, b.getUnknownLoc(), "gaz");
b.create<T>(b.getUnknownLoc(), "gaz");
}
void f() {
mlir::OpBuilder builder;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
- // CHECK-FIXES: mlir:: ModuleOp::create(builder, builder.getUnknownLoc())
+ // CHECK-FIXES: mlir:: ModuleOp::create(builder, builder.getUnknownLoc());
builder.create<mlir:: ModuleOp>(builder.getUnknownLoc());
using mlir::NamedOp;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
- // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), "baz")
+ // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), "baz");
builder.create<NamedOp>(builder.getUnknownLoc(), "baz");
- // CHECK-MESSAGES: :[[@LINE+4]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
- // CHECK-FIXES: NamedOp::create(builder,
- // CHECK-FIXES: builder.getUnknownLoc(),
- // CHECK-FIXES: "caz")
+ // CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
+ // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(),
+ // CHECK-FIXES: "caz");
builder.
create<NamedOp>(
builder.getUnknownLoc(),
@@ -67,7 +66,7 @@ void f() {
mlir::ImplicitLocOpBuilder ib;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
- // CHECK-FIXES: mlir::ModuleOp::create(ib)
+ // CHECK-FIXES: mlir::ModuleOp::create(ib);
ib.create<mlir::ModuleOp>( );
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder]
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
index a44a712..e20680c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t \
+// RUN: %check_clang_tidy %s misc-const-correctness %t \
// RUN: -config='{CheckOptions: {\
// RUN: misc-const-correctness.AnalyzeValues: false,\
// RUN: misc-const-correctness.AnalyzeReferences: false,\
@@ -14,7 +14,7 @@ void pointee_to_const() {
int a[] = {1, 2};
int *p_local0 = &a[0];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'int *' can be declared 'const'
- // CHECK-FIXES: int const*p_local0
+ // CHECK-FIXES: int const*p_local0 = &a[0];
p_local0 = &a[1];
}
@@ -22,7 +22,7 @@ void array_of_pointer_to_const() {
int a[] = {1, 2};
int *p_local0[1] = {&a[0]};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'int *[1]' can be declared 'const'
- // CHECK-FIXES: int const*p_local0[1]
+ // CHECK-FIXES: int const*p_local0[1] = {&a[0]};
p_local0[0] = &a[1];
}
@@ -31,7 +31,7 @@ void template_fn() {
T a[] = {1, 2};
T *p_local0 = &a[0];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'char *' can be declared 'const'
- // CHECK-FIXES: T const*p_local0
+ // CHECK-FIXES: T const*p_local0 = &a[0];
p_local0 = &a[1];
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
index 74be3dc..02d32c0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t \
+// RUN: %check_clang_tidy %s misc-const-correctness %t \
// RUN: -config='{CheckOptions: \
// RUN: {misc-const-correctness.AnalyzeValues: true,\
// RUN: misc-const-correctness.WarnPointersAsValues: true,\
@@ -10,32 +10,31 @@ void potential_const_pointer() {
double np_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
double *p_local0 = &np_local0[1];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double *' can be declared 'const'
- // CHECK-FIXES: double *const p_local0
+ // CHECK-FIXES: double *const p_local0 = &np_local0[1];
using doublePtr = double*;
using doubleArray = double[15];
doubleArray np_local1;
doublePtr p_local1 = &np_local1[0];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'doublePtr' (aka 'double *') can be declared 'const'
- // CHECK-FIXES: doublePtr const p_local1
+ // CHECK-FIXES: doublePtr const p_local1 = &np_local1[0];
}
void range_for() {
int np_local0[2] = {1, 2};
int *p_local0[2] = {&np_local0[0], &np_local0[1]};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[2]' can be declared 'const'
- // CHECK-FIXES: int *const p_local0[2]
+ // CHECK-FIXES: int *const p_local0[2] = {&np_local0[0], &np_local0[1]};
for (const int *p_local1 : p_local0) {
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'const int *' can be declared 'const'
- // CHECK-FIXES: for (const int *const p_local1 : p_local0)
+ // CHECK-FIXES: for (const int *const p_local1 : p_local0) {
}
int *p_local2[2] = {nullptr, nullptr};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const'
- // CHECK-FIXES: int *const p_local2[2]
+ // CHECK-FIXES: int *const p_local2[2] = {nullptr, nullptr};
for (const auto *con_ptr : p_local2) {
}
-
}
template <typename T>
@@ -59,7 +58,7 @@ void EmitProtocolMethodList(T &&Methods) {
// some expressions are type-dependent.
SmallVector<const int *> p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const'
- // CHECK-FIXES: SmallVector<const int *> const p_local0
+ // CHECK-FIXES: SmallVector<const int *> const p_local0;
SmallVector<const int *> np_local0;
for (const auto *I : Methods) {
if (I == nullptr)
@@ -70,6 +69,6 @@ void EmitProtocolMethodList(T &&Methods) {
void instantiate() {
int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const'
- // CHECK-FIXES: int *const p_local0[4]
+ // CHECK-FIXES: int *const p_local0[4] = {nullptr, nullptr, nullptr, nullptr};
EmitProtocolMethodList(p_local0);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
index 17dcf12..4cef7f4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t -- \
+// RUN: %check_clang_tidy %s misc-const-correctness %t -- \
// RUN: -config="{CheckOptions: {\
// RUN: misc-const-correctness.TransformValues: true, \
// RUN: misc-const-correctness.WarnPointersAsValues: false, \
@@ -38,7 +38,7 @@ void some_function(double, wchar_t);
void some_function(double np_arg0, wchar_t np_arg1) {
int p_local0 = 2;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 2;
int np_local0;
const int np_local1 = 42;
@@ -60,7 +60,7 @@ void some_function(double np_arg0, wchar_t np_arg1) {
int function_try_block() try {
int p_local0 = 0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 0;
return p_local0;
} catch (...) {
return 0;
@@ -69,13 +69,13 @@ int function_try_block() try {
void nested_scopes() {
int p_local0 = 2;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 2;
int np_local0 = 42;
{
int p_local1 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: int const p_local1 = 42;
np_local0 *= 2;
}
}
@@ -89,7 +89,7 @@ void some_lambda_environment_capture_all_by_reference(double np_arg0) {
int np_local0 = 0;
int p_local0 = 1;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 1;
int np_local2;
const int np_local3 = 2;
@@ -99,14 +99,14 @@ void some_lambda_environment_capture_all_by_reference(double np_arg0) {
int p_local1 = 0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: int const p_local1 = 0;
}
void some_lambda_environment_capture_all_by_value(double np_arg0) {
int np_local0 = 0;
int p_local0 = 1;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 1;
int np_local1;
const int np_local2 = 2;
@@ -139,12 +139,12 @@ void some_pointer_taking(int *out) {
int p_local1 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: int const p_local1 = 42;
const int *const p0_p_local1 = &p_local1;
int p_local2 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local2
+ // CHECK-FIXES: int const p_local2 = 42;
function_in_pointer(&p_local2);
}
@@ -163,19 +163,19 @@ void some_reference_taking() {
int p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 42;
const int &r0_p_local0 = p_local0;
int p_local1 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: int const p_local1 = 42;
function_in_ref(p_local1);
}
double *non_const_pointer_return() {
double p_local0 = 0.0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local0
+ // CHECK-FIXES: double const p_local0 = 0.0;
double np_local0 = 24.4;
return &np_local0;
@@ -184,10 +184,10 @@ double *non_const_pointer_return() {
const double *const_pointer_return() {
double p_local0 = 0.0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local0
+ // CHECK-FIXES: double const p_local0 = 0.0;
double p_local1 = 24.4;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local1
+ // CHECK-FIXES: double const p_local1 = 24.4;
return &p_local1;
}
@@ -195,10 +195,10 @@ const double *const_pointer_return() {
const double &const_ref_return() {
double p_local0 = 0.0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local0
+ // CHECK-FIXES: double const p_local0 = 0.0;
double p_local1 = 24.4;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local1
+ // CHECK-FIXES: double const p_local1 = 24.4;
return p_local1;
}
@@ -237,7 +237,7 @@ void define_locals(T np_arg0, T &np_arg1, int np_arg2) {
// non-template values are ok still.
int p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 42;
np_local4 += p_local0;
}
@@ -306,19 +306,19 @@ void direct_class_access() {
ConstNonConstClass p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local0
+ // CHECK-FIXES: ConstNonConstClass const p_local0;
p_local0.constMethod();
ConstNonConstClass p_local1;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'ConstNonConstClass' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local1
+ // CHECK-FIXES: ConstNonConstClass const p_local1;
double np_local1;
p_local1.modifyingMethod(np_local1);
double np_local2;
ConstNonConstClass p_local2(np_local2);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'ConstNonConstClass' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local2(np_local2)
+ // CHECK-FIXES: ConstNonConstClass const p_local2(np_local2);
ConstNonConstClass np_local3;
np_local3.NonConstMember = 42.;
@@ -328,14 +328,14 @@ void direct_class_access() {
ConstNonConstClass p_local3;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'ConstNonConstClass' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local3
+ // CHECK-FIXES: ConstNonConstClass const p_local3;
const double val0 = p_local3.NonConstMember;
const double val1 = p_local3.NonConstMemberRef;
const double val2 = *p_local3.NonConstMemberPtr;
ConstNonConstClass p_local4;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'ConstNonConstClass' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local4
+ // CHECK-FIXES: ConstNonConstClass const p_local4;
*np_local4.NonConstMemberPtr = 42.;
}
@@ -347,7 +347,7 @@ void class_access_array() {
ConstNonConstClass p_local0[2];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const'
- // CHECK-FIXES: ConstNonConstClass const p_local0[2]
+ // CHECK-FIXES: ConstNonConstClass const p_local0[2];
p_local0[0].constMethod();
np_local0[1].constMethod();
}
@@ -367,10 +367,10 @@ void internal_operator_calls() {
OperatorsAsConstAsPossible np_local1;
OperatorsAsConstAsPossible p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'OperatorsAsConstAsPossible' can be declared 'const'
- // CHECK-FIXES: OperatorsAsConstAsPossible const p_local0
+ // CHECK-FIXES: OperatorsAsConstAsPossible const p_local0;
OperatorsAsConstAsPossible p_local1;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'OperatorsAsConstAsPossible' can be declared 'const'
- // CHECK-FIXES: OperatorsAsConstAsPossible const p_local1
+ // CHECK-FIXES: OperatorsAsConstAsPossible const p_local1;
np_local0 += p_local0;
np_local1 = p_local0 + p_local1;
@@ -383,10 +383,10 @@ void internal_operator_calls() {
NonConstOperators p_local2;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'NonConstOperators' can be declared 'const'
- // CHECK-FIXES: NonConstOperators const p_local2
+ // CHECK-FIXES: NonConstOperators const p_local2;
NonConstOperators p_local3 = p_local2 - p_local2;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'NonConstOperators' can be declared 'const'
- // CHECK-FIXES: NonConstOperators const p_local3
+ // CHECK-FIXES: NonConstOperators const p_local3 = p_local2 - p_local2;
}
struct MyVector {
@@ -411,17 +411,17 @@ void vector_usage() {
double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local0[10]
+ // CHECK-FIXES: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
double p_local1 = p_local0[5];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local1
+ // CHECK-FIXES: double const p_local1 = p_local0[5];
- // The following subscript calls suprisingly choose the non-const operator
+ // The following subscript calls surprisingly choose the non-const operator
// version.
MyVector np_local2;
double p_local2 = np_local2[42];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local2
+ // CHECK-FIXES: double const p_local2 = np_local2[42];
MyVector np_local3;
const double np_local4 = np_local3[42];
@@ -430,7 +430,7 @@ void vector_usage() {
const MyVector np_local5{};
double p_local3 = np_local5[42];
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double' can be declared 'const'
- // CHECK-FIXES: double const p_local3
+ // CHECK-FIXES: double const p_local3 = np_local5[42];
}
void const_handle(const double &np_local0);
@@ -460,27 +460,27 @@ void handle_from_array() {
// Constant handles are ok
double p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local1[10]
+ // CHECK-FIXES: double const p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
const double *p_local2 = &p_local1[2]; // Could be `const double *const`, but warning deactivated by default
double p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local3[10]
+ // CHECK-FIXES: double const p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
const double &const_ref = p_local3[2];
double p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local4[10]
+ // CHECK-FIXES: double const p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
const double *const_ptr;
const_ptr = &p_local4[2];
double p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local5' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local5[10]
+ // CHECK-FIXES: double const p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
const_handle(p_local5[2]);
double p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local6' of type 'double[10]' can be declared 'const'
- // CHECK-FIXES: double const p_local6[10]
+ // CHECK-FIXES: double const p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};
const_handle(&p_local6[2]);
}
@@ -513,15 +513,15 @@ void range_for() {
int p_local0[2] = {1, 2};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int[2]' can be declared 'const'
- // CHECK-FIXES: int const p_local0[2]
+ // CHECK-FIXES: int const p_local0[2] = {1, 2};
for (int value : p_local0) {
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'value' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const value
+ // CHECK-FIXES: for (int const value : p_local0) {
}
int p_local1[2] = {1, 2};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int[2]' can be declared 'const'
- // CHECK-FIXES: int const p_local1[2]
+ // CHECK-FIXES: int const p_local1[2] = {1, 2};
for (const int &const_ref : p_local1) {
}
}
@@ -552,7 +552,7 @@ void conversion_operators() {
ModifyingConversion np_local0;
NonModifyingConversion p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'NonModifyingConversion' can be declared 'const'
- // CHECK-FIXES: NonModifyingConversion const p_local0
+ // CHECK-FIXES: NonModifyingConversion const p_local0;
int np_local1 = np_local0;
np_local1 = p_local0;
@@ -561,16 +561,16 @@ void conversion_operators() {
void casts() {
decltype(sizeof(void *)) p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))'
- // CHECK-FIXES: decltype(sizeof(void *)) const p_local0
+ // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 = 42;
auto np_local0 = reinterpret_cast<void *>(p_local0);
np_local0 = nullptr;
int p_local1 = 43;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: int const p_local1 = 43;
short p_local2 = static_cast<short>(p_local1);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'short' can be declared 'const'
- // CHECK-FIXES: short const p_local2
+ // CHECK-FIXES: short const p_local2 = static_cast<short>(p_local1);
int np_local1 = p_local2;
int &np_local2 = static_cast<int &>(np_local1);
@@ -584,7 +584,7 @@ void ternary_operator() {
int p_local0 = 3, np_local3 = 5;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-NOT-FIXES: int const p_local0 = 3
+ // CHECK-NOT-FIXES: int const p_local0 = 3, np_local3 = 5;
const int &np_local4 = true ? p_local0 : ++np_local3;
int np_local5[3] = {1, 2, 3};
@@ -636,13 +636,13 @@ struct TMPClass {
void meta_type() {
TMPClass<int> p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass<int>' can be declared 'const'
- // CHECK-FIXES: TMPClass<int> const p_local0
+ // CHECK-FIXES: TMPClass<int> const p_local0;
p_local0.alwaysConst();
p_local0.sometimesConst();
TMPClass<double> p_local1;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass<double>' can be declared 'const'
- // CHECK-FIXES: TMPClass<double> const p_local1
+ // CHECK-FIXES: TMPClass<double> const p_local1;
p_local1.alwaysConst();
TMPClass<double> np_local0;
@@ -659,7 +659,7 @@ template <typename T>
void placement_new_in_unique_ptr() {
int p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 42;
int np_local0 = p_local0;
new to_construct<T>(np_local0);
}
@@ -696,7 +696,7 @@ void TestRegisters() {
HardwareRegister p_reg1{3, 22};
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_reg1' of type 'HardwareRegister' can be declared 'const'
- // CHECK-FIXES: HardwareRegister const p_reg1
+ // CHECK-FIXES: HardwareRegister const p_reg1{3, 22};
const unsigned p_val = p_reg1.another;
}
@@ -745,7 +745,7 @@ struct A {
void f() {
int p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 42;
int np_local0 = 42;
f_signature action = my_alloc;
action(np_local0);
@@ -795,7 +795,7 @@ void for_bad_iterators() {
non_const_iterator np_local3;
for (int p_local0 : np_local3)
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: for (int const p_local0 : np_local3)
;
// Horrible code constructs...
@@ -805,21 +805,21 @@ void for_bad_iterators() {
non_const_iterator np_local5;
for (int p_local1 : np_local4, np_local5)
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: for (int const p_local1 : np_local4, np_local5)
;
non_const_iterator np_local6;
non_const_iterator np_local7;
for (int p_local2 : 1 > 2 ? np_local6 : np_local7)
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local2' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local2
+ // CHECK-FIXES: for (int const p_local2 : 1 > 2 ? np_local6 : np_local7)
;
non_const_iterator np_local8;
non_const_iterator np_local9;
for (int p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9))
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local3' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local3
+ // CHECK-FIXES: for (int const p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9))
;
}
}
@@ -836,23 +836,23 @@ struct good_iterator {
void good_iterators() {
good_iterator p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'good_iterator' can be declared 'const'
- // CHECK-FIXES: good_iterator const p_local0
+ // CHECK-FIXES: good_iterator const p_local0;
good_iterator &p_local1 = p_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'good_iterator &' can be declared 'const'
- // CHECK-FIXES: good_iterator const&p_local1
+ // CHECK-FIXES: good_iterator const&p_local1 = p_local0;
for (int p_local2 : p_local1) {
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local2' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local2
+ // CHECK-FIXES: for (int const p_local2 : p_local1) {
(void)p_local2;
}
good_iterator p_local3;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'good_iterator' can be declared 'const'
- // CHECK-FIXES: good_iterator const p_local3
+ // CHECK-FIXES: good_iterator const p_local3;
for (int p_local4 : p_local3)
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local4' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local4
+ // CHECK-FIXES: for (int const p_local4 : p_local3)
;
good_iterator np_local1;
for (int &np_local2 : np_local1)
@@ -871,11 +871,11 @@ void for_ok_iterators_array() {
int np_local0[42];
int(&p_local0)[42] = np_local0;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int (&)[42]' can be declared 'const'
- // CHECK-FIXES: int const(&p_local0)[42]
+ // CHECK-FIXES: int const(&p_local0)[42] = np_local0;
for (int p_local1 : p_local0) {
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local1
+ // CHECK-FIXES: for (int const p_local1 : p_local0) {
(void)p_local1;
}
}
@@ -891,7 +891,7 @@ void complex_usage() {
int np_local0 = 42;
int p_local0 = 42;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'
- // CHECK-FIXES: int const p_local0
+ // CHECK-FIXES: int const p_local0 = 42;
int np_local1 = 42;
(np_local0 == p_local0 ? np_local0 : (p_local0, np_local1))++;
}
@@ -920,7 +920,7 @@ void create_false_positive() {
int np_local0 = 42;
list_init p_local0 = {np_local0};
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init' can be declared 'const'
- // CHECK-FIXES: list_init const p_local0
+ // CHECK-FIXES: list_init const p_local0 = {np_local0};
}
struct list_init_derived {
base &member;
@@ -929,7 +929,7 @@ void list_init_derived_func() {
derived np_local0;
list_init_derived p_local0 = {np_local0};
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init_derived' can be declared 'const'
- // CHECK-FIXES: list_init_derived const p_local0
+ // CHECK-FIXES: list_init_derived const p_local0 = {np_local0};
}
template <typename L, typename R>
struct ref_pair {
@@ -945,7 +945,7 @@ void cast_in_class_hierarchy() {
derived np_local0;
base p_local1 = static_cast<base &>(np_local0);
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local1' of type 'base' can be declared 'const'
- // CHECK-FIXES: base const p_local1
+ // CHECK-FIXES: base const p_local1 = static_cast<base &>(np_local0);
}
void function_ref_target(int);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp
index c48a2ee..853ec77 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s misc-definitions-in-headers %t -- --fix-notes
+// RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- --fix-notes
int f() {
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers]
@@ -25,7 +25,7 @@ class CA {
void CA::f2() { }
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file;
-// CHECK-FIXES: inline void CA::f2() {
+// CHECK-FIXES: inline void CA::f2() { }
template <>
int CA::f3() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp
index 4baf839..f473f26 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp
@@ -1,7 +1,7 @@
// RUN: mkdir -p %t.dir
// RUN: echo "static void staticFunctionHeader(int i) {;}" > %t.dir/header.h
// RUN: echo "static void staticFunctionHeader(int /*i*/) {;}" > %t.dir/header-fixed.h
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11 %s misc-unused-parameters %t.dir/code -- -header-filter='.*' -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy -std=c++11 %s misc-unused-parameters %t.dir/code -- -header-filter='.*' -- -fno-delayed-template-parsing
// RUN: diff %t.dir/header.h %t.dir/header-fixed.h
// FIXME: Make the test work in all language modes.
@@ -67,41 +67,41 @@ static void staticFunctionA(int i);
// CHECK-FIXES: static void staticFunctionA();
static void staticFunctionA(int i) {;}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
-// CHECK-FIXES: static void staticFunctionA()
+// CHECK-FIXES: static void staticFunctionA() {;}
static void staticFunctionB(int i, int j) { (void)i; }
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
-// CHECK-FIXES: static void staticFunctionB(int i)
+// CHECK-FIXES: static void staticFunctionB(int i) { (void)i; }
static void staticFunctionC(int i, int j) { (void)j; }
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
-// CHECK-FIXES: static void staticFunctionC(int j)
+// CHECK-FIXES: static void staticFunctionC(int j) { (void)j; }
static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; }
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
-// CHECK-FIXES: static void staticFunctionD(int i, int k)
+// CHECK-FIXES: static void staticFunctionD(int i, int k) { (void)i; (void)k; }
static void staticFunctionE(int i = 4) {;}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
-// CHECK-FIXES: static void staticFunctionE()
+// CHECK-FIXES: static void staticFunctionE() {;}
static void staticFunctionF(int i = 4);
// CHECK-FIXES: static void staticFunctionF();
static void staticFunctionF(int i) {;}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
-// CHECK-FIXES: static void staticFunctionF()
+// CHECK-FIXES: static void staticFunctionF() {;}
static void staticFunctionG(int i[]);
// CHECK-FIXES: static void staticFunctionG();
static void staticFunctionG(int i[]) {;}
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
-// CHECK-FIXES: static void staticFunctionG()
+// CHECK-FIXES: static void staticFunctionG() {;}
static void staticFunctionH(void (*fn)());
// CHECK-FIXES: static void staticFunctionH();
static void staticFunctionH(void (*fn)()) {;}
// CHECK-MESSAGES: :[[@LINE-1]]:36: warning
-// CHECK-FIXES: static void staticFunctionH()
+// CHECK-FIXES: static void staticFunctionH() {;}
static void someCallSites() {
staticFunctionA(1);
@@ -298,7 +298,7 @@ using fn = void(int);
void f(fn *);
void test() {
// CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused
- // CHECK-FIXES: f([](int /*I*/) {
+ // CHECK-FIXES: f([](int /*I*/) { return; });
f([](int I) { return; });
}
} // namespace lambda
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp
index 342c96a..6aa7d48 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s modernize-avoid-bind %t
+// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-avoid-bind %t
namespace std {
inline namespace impl {
@@ -229,19 +229,19 @@ void testFunctionObjects() {
D *e = nullptr;
auto AAA = std::bind(d, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto AAA = [d] { d(1, 2); }
+ // CHECK-FIXES: auto AAA = [d] { d(1, 2); };
auto BBB = std::bind(*e, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto BBB = [e] { (*e)(1, 2); }
+ // CHECK-FIXES: auto BBB = [e] { (*e)(1, 2); };
auto CCC = std::bind(D{}, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto CCC = [] { D{}(1, 2); }
+ // CHECK-FIXES: auto CCC = [] { D{}(1, 2); };
auto DDD = std::bind(D(), 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto DDD = [] { D()(1, 2); }
+ // CHECK-FIXES: auto DDD = [] { D()(1, 2); };
auto EEE = std::bind(*D::create(), 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
@@ -384,11 +384,11 @@ struct E {
auto III = std::bind(&D::operator(), d, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto III = [d] { (*d)(1, 2); }
+ // CHECK-FIXES: auto III = [d] { (*d)(1, 2); };
auto JJJ = std::bind(&D::operator(), &dd, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto JJJ = [ObjectPtr = &dd] { (*ObjectPtr)(1, 2); }
+ // CHECK-FIXES: auto JJJ = [ObjectPtr = &dd] { (*ObjectPtr)(1, 2); };
auto KKK = std::bind(&D::operator(), _1, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
@@ -396,11 +396,11 @@ struct E {
auto LLL = std::bind(&D::operator bool, d);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto LLL = [d] { return d->operator bool(); }
+ // CHECK-FIXES: auto LLL = [d] { return d->operator bool(); };
auto MMM = std::bind(&E::operator(), this, 1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
- // CHECK-FIXES: auto MMM = [this] { return (*this)(1, 2); }
+ // CHECK-FIXES: auto MMM = [this] { return (*this)(1, 2); };
}
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
index 78adbeb..35cb550 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp
@@ -1,10 +1,10 @@
// RUN: mkdir -p %t.dir
// RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++17 -check-suffix=NORMAL %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir
+// RUN: %check_clang_tidy -std=c++17 -check-suffix=NORMAL %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir
// RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES
// Restore header file and re-run with c++20:
// RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++20 -check-suffixes=NORMAL,CPP20 %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir
+// RUN: %check_clang_tidy -std=c++20 -check-suffixes=NORMAL,CPP20 %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir
// RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES
#include "modernize-concat-nested-namespaces.h"
@@ -38,16 +38,16 @@ void t();
namespace n9 {
namespace n10 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n9::n10
+// CHECK-FIXES-NORMAL: namespace n9::n10 {
void t();
} // namespace n10
} // namespace n9
-// CHECK-FIXES-NORMAL: }
+// CHECK-FIXES-NORMAL: } // namespace n9::n10
namespace n11 {
namespace n12 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n11::n12
+// CHECK-FIXES-NORMAL: namespace n11::n12 {
namespace n13 {
void t();
}
@@ -71,7 +71,7 @@ namespace n18 {
namespace n19 {
namespace n20 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n18::n19::n20
+// CHECK-FIXES-NORMAL: namespace n18::n19::n20 {
void t();
} // namespace n20
} // namespace n19
@@ -94,11 +94,11 @@ namespace {
namespace n24 {
namespace n25 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n24::n25
+// CHECK-FIXES-NORMAL: namespace n24::n25 {
void t();
} // namespace n25
} // namespace n24
-// CHECK-FIXES-NORMAL: }
+// CHECK-FIXES-NORMAL: } // namespace n24::n25
} // namespace
} // namespace n23
@@ -136,7 +136,7 @@ void t();
namespace n39 {
namespace n40 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n39::n40
+// CHECK-FIXES-NORMAL: namespace n39::n40 {
#ifdef IEXIST
void t() {}
#endif
@@ -147,7 +147,7 @@ void t() {}
namespace n41 {
namespace n42 {
// CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
-// CHECK-FIXES-NORMAL: namespace n41::n42
+// CHECK-FIXES-NORMAL: namespace n41::n42 {
#ifdef IDONTEXIST
void t() {}
#endif
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
index 419e7f8..2f744eb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert
#include "structures.h"
@@ -18,7 +18,7 @@ void f() {
int K;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert]
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: Sum += I;
// CHECK-FIXES-NEXT: int K;
@@ -27,7 +27,7 @@ void f() {
Sum += Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -36,7 +36,7 @@ void f() {
int Y = Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: int X = I;
// CHECK-FIXES-NEXT: int Y = I + 2;
@@ -45,7 +45,7 @@ void f() {
X = Arr[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: int X = N;
// CHECK-FIXES-NEXT: X = I;
@@ -53,7 +53,7 @@ void f() {
Arr[I] += 1;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: I += 1;
for (int I = 0; I < N; ++I) {
@@ -61,7 +61,7 @@ void f() {
Arr[I]++;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: int X = I + 2;
// CHECK-FIXES-NEXT: I++;
@@ -69,14 +69,14 @@ void f() {
Arr[I] = 4 + Arr[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: I = 4 + I;
for (int I = 0; I < NMinusOne + 1; ++I) {
Sum += Arr[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: Sum += I;
for (int I = 0; I < N; ++I) {
@@ -84,7 +84,7 @@ void f() {
Sum += Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -96,7 +96,7 @@ void f() {
size += sizeof((Matrix[I]));
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Matrix)
+ // CHECK-FIXES: for (auto & I : Matrix) {
// CHECK-FIXES-NEXT: size += sizeof(I);
// CHECK-FIXES-NEXT: size += sizeof I;
// CHECK-FIXES-NEXT: size += sizeof(I);
@@ -106,7 +106,7 @@ void f() {
Teas[I].g();
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Tea : Teas)
+ // CHECK-FIXES: for (auto & Tea : Teas) {
// CHECK-FIXES-NEXT: Tea.g();
for (int I = 0; N > I; ++I) {
@@ -114,7 +114,7 @@ void f() {
Sum += Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -123,7 +123,7 @@ void f() {
Sum += Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -132,7 +132,7 @@ void f() {
Sum += Arr[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
// CHECK-FIXES-NEXT: Sum += I + 2;
}
@@ -142,7 +142,7 @@ const int *constArray() {
printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : ConstArr)
+ // CHECK-FIXES: for (int I : ConstArr) {
// CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I);
const NonTriviallyCopyable NonCopy[N]{};
@@ -150,7 +150,7 @@ const int *constArray() {
printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : NonCopy)
+ // CHECK-FIXES: for (const auto & I : NonCopy) {
// CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
const TriviallyCopyableButBig Big[N]{};
@@ -158,7 +158,7 @@ const int *constArray() {
printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : Big)
+ // CHECK-FIXES: for (const auto & I : Big) {
// CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
bool Something = false;
@@ -167,7 +167,7 @@ const int *constArray() {
return &ConstArr[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const int & I : ConstArr)
+ // CHECK-FIXES: for (const int & I : ConstArr) {
// CHECK-FIXES-NEXT: if (Something)
// CHECK-FIXES-NEXT: return &I;
@@ -182,14 +182,14 @@ struct HasArr {
printf("%d", Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: printf("%d", I);
for (int I = 0; I < N; ++I) {
printf("%d", ValArr[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : ValArr)
+ // CHECK-FIXES: for (auto & I : ValArr) {
// CHECK-FIXES-NEXT: printf("%d", I.X);
}
@@ -198,14 +198,14 @@ struct HasArr {
printf("%d", this->Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : this->Arr)
+ // CHECK-FIXES: for (int I : this->Arr) {
// CHECK-FIXES-NEXT: printf("%d", I);
for (int I = 0; I < N; ++I) {
printf("%d", this->ValArr[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : this->ValArr)
+ // CHECK-FIXES: for (auto & I : this->ValArr) {
// CHECK-FIXES-NEXT: printf("%d", I.X);
}
};
@@ -217,14 +217,14 @@ struct HasIndirectArr {
printf("%d", HA.Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : HA.Arr)
+ // CHECK-FIXES: for (int I : HA.Arr) {
// CHECK-FIXES-NEXT: printf("%d", I);
for (int I = 0; I < N; ++I) {
printf("%d", HA.ValArr[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : HA.ValArr)
+ // CHECK-FIXES: for (auto & I : HA.ValArr) {
// CHECK-FIXES-NEXT: printf("%d", I.X);
}
@@ -233,14 +233,14 @@ struct HasIndirectArr {
printf("%d", this->HA.Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : this->HA.Arr)
+ // CHECK-FIXES: for (int I : this->HA.Arr) {
// CHECK-FIXES-NEXT: printf("%d", I);
for (int I = 0; I < N; ++I) {
printf("%d", this->HA.ValArr[I].X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : this->HA.ValArr)
+ // CHECK-FIXES: for (auto & I : this->HA.ValArr) {
// CHECK-FIXES-NEXT: printf("%d", I.X);
}
};
@@ -285,7 +285,7 @@ void f() {
printf("I found %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Tt)
+ // CHECK-FIXES: for (int & It : Tt) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
// Do not crash because of Qq.begin() converting. Q::iterator converts with a
@@ -295,7 +295,7 @@ void f() {
printf("I found %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Qq)
+ // CHECK-FIXES: for (int & It : Qq) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
T *Pt;
@@ -303,7 +303,7 @@ void f() {
printf("I found %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : *Pt)
+ // CHECK-FIXES: for (int & It : *Pt) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
S Ss;
@@ -311,7 +311,7 @@ void f() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
S *Ps;
@@ -319,42 +319,42 @@ void f() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & P : *Ps)
+ // CHECK-FIXES: for (auto & P : *Ps) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES: for (auto It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
printf("s has value %d\n", It->X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
It->X = 3;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.X = 3;
for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
(*It).X = 3;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.X = 3;
for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
It->nonConstFun(4, 5);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
U Uu;
@@ -362,14 +362,14 @@ void f() {
printf("s has value %d\n", It->X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES: for (auto & It : Uu) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES: for (auto & It : Uu) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
@@ -389,7 +389,7 @@ void f() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES: for (int & It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
for (dependent<int>::iterator It(V.begin()), E = V.end();
@@ -397,7 +397,7 @@ void f() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES: for (int & It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
doublyDependent<int, int> Intmap;
@@ -406,7 +406,7 @@ void f() {
printf("Intmap[%d] = %d", It->first, It->second);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Intmap)
+ // CHECK-FIXES: for (auto & It : Intmap) {
// CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second);
// PtrSet's iterator dereferences by value so auto & can't be used.
@@ -418,7 +418,7 @@ void f() {
(void) *I;
}
// CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs)
+ // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) {
}
// This container uses an iterator where the dereference type is a typedef of
@@ -432,7 +432,7 @@ void f() {
(void) *I;
}
// CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & Int_ptr : Int_ptrs)
+ // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) {
}
{
@@ -451,49 +451,49 @@ void f() {
printf("%d\n", (**I).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Dpp)
+ // CHECK-FIXES: for (auto & I : Dpp) {
// CHECK-FIXES-NEXT: printf("%d\n", (*I).X);
for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
printf("%d\n", (*I)->X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Dpp)
+ // CHECK-FIXES: for (auto & I : Dpp) {
// CHECK-FIXES-NEXT: printf("%d\n", I->X);
for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) {
printf("s0 has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X);
for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) {
printf("s1 has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X);
for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) {
printf("s2 has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : *Ps)
+ // CHECK-FIXES: for (auto & It : *Ps) {
// CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X);
for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) {
printf("s3 has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : *Ps)
+ // CHECK-FIXES: for (auto & It : *Ps) {
// CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X);
for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) {
printf("s4 has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES: for (auto It : Ss) {
// CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X);
}
@@ -507,7 +507,7 @@ void different_type() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES: for (auto It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
S *Ps;
@@ -515,7 +515,7 @@ void different_type() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto P : *Ps)
+ // CHECK-FIXES: for (auto P : *Ps) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
dependent<int> V;
@@ -524,7 +524,7 @@ void different_type() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int It : V)
+ // CHECK-FIXES: for (int It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
for (dependent<int>::const_iterator It(V.begin()), E = V.end();
@@ -532,7 +532,7 @@ void different_type() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int It : V)
+ // CHECK-FIXES: for (int It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
}
@@ -634,7 +634,7 @@ void f() {
Sum += V[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -643,7 +643,7 @@ void f() {
Sum += V.at(I) + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -652,7 +652,7 @@ void f() {
Sum += Pv->at(I) + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : *Pv)
+ // CHECK-FIXES: for (int I : *Pv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -665,7 +665,7 @@ void f() {
Sum += (*Pv)[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : *Pv)
+ // CHECK-FIXES: for (int I : *Pv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -674,7 +674,7 @@ void f() {
Sum += Cv->at(I) + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : *Cv)
+ // CHECK-FIXES: for (int I : *Cv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -683,7 +683,7 @@ void f() {
Sum += V[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -692,7 +692,7 @@ void f() {
Sum += V[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -701,7 +701,7 @@ void f() {
Sum += V[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -710,7 +710,7 @@ void f() {
Sum += VD[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : VD)
+ // CHECK-FIXES: for (int I : VD) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -719,7 +719,7 @@ void f() {
Sum += V[I] + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
@@ -727,14 +727,14 @@ void f() {
V[I] = 0;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : V)
+ // CHECK-FIXES: for (int & I : V) {
// CHECK-FIXES-NEXT: I = 0;
for (int I = 0, E = std::size(V); E != I; ++I) {
V[I] = 0;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : V)
+ // CHECK-FIXES: for (int & I : V) {
// CHECK-FIXES-NEXT: I = 0;
// Although 'length' might be a valid free function, only size() is standardized
@@ -748,7 +748,7 @@ void f() {
Sum += Vals[I].X;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Val : Vals)
+ // CHECK-FIXES: for (auto & Val : Vals) {
// CHECK-FIXES-NEXT: Sum += Val.X;
}
@@ -760,7 +760,7 @@ void constness() {
Sum += Constv[I].X + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : Constv)
+ // CHECK-FIXES: for (const auto & I : Constv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
// CHECK-FIXES-NEXT: Sum += I.X + 2;
@@ -769,7 +769,7 @@ void constness() {
Sum += Constv.at(I).X + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : Constv)
+ // CHECK-FIXES: for (const auto & I : Constv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
// CHECK-FIXES-NEXT: Sum += I.X + 2;
@@ -778,7 +778,7 @@ void constness() {
Sum += Pconstv->at(I).X + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : *Pconstv)
+ // CHECK-FIXES: for (const auto & I : *Pconstv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
// CHECK-FIXES-NEXT: Sum += I.X + 2;
@@ -791,7 +791,7 @@ void constness() {
Sum += (*Pconstv)[I].X + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (const auto & I : *Pconstv)
+ // CHECK-FIXES: for (const auto & I : *Pconstv) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
// CHECK-FIXES-NEXT: Sum += I.X + 2;
}
@@ -804,14 +804,14 @@ void constRef(const dependent<int>& ConstVRef) {
sum += ConstVRef[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : ConstVRef)
+ // CHECK-FIXES: for (int I : ConstVRef) {
// CHECK-FIXES-NEXT: sum += I;
for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) {
sum += *I;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : ConstVRef)
+ // CHECK-FIXES: for (int I : ConstVRef) {
// CHECK-FIXES-NEXT: sum += I;
}
@@ -889,7 +889,7 @@ void derefByValueTest() {
printf("%d\n", DBV[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (unsigned int I : DBV)
+ // CHECK-FIXES: for (unsigned int I : DBV) {
// CHECK-FIXES-NEXT: printf("%d\n", I);
for (unsigned I = 0, E = DBV.size(); I < E; ++I) {
@@ -897,7 +897,7 @@ void derefByValueTest() {
printf("%d\n", DBV[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (unsigned int I : DBV)
+ // CHECK-FIXES: for (unsigned int I : DBV) {
// CHECK-FIXES-NEXT: auto f = [DBV, &I]() {};
// CHECK-FIXES-NEXT: printf("%d\n", I);
}
@@ -960,7 +960,7 @@ template <unsigned p> void _dependenceArrayTest() {
for (unsigned j = 0; j < 3; ++j)
printf("%d", test[j][i]);
// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: (auto & j : test)
+ // CHECK-FIXES: for (auto & j : test)
// CHECK-FIXES: printf("%d", j[i]);
}
void dependenceArrayTest() {
@@ -992,13 +992,13 @@ void test() {
auto V = [T = Arr[I]]() {};
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: auto V = [T = I]() {};
for (int I = 0; I < N; ++I) {
auto V = [T = 10 + Arr[I]]() {};
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: auto V = [T = 10 + I]() {};
for (int I = 0; I < N; ++I) {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp
index 6091f0a..59f472c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t
+// RUN: %check_clang_tidy %s modernize-loop-convert %t
struct Str {
Str() = default;
@@ -43,7 +43,7 @@ void memberFunctionsAndOperators() {
Array[I].constMember(0);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: I.constMember(0);
for (int I = 0; I < N; ++I) {
@@ -51,14 +51,14 @@ void memberFunctionsAndOperators() {
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: if (I < OtherStr)
for (int I = 0; I < N; ++I) {
if (Right[I] < OtherRight)
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (const auto & I : Right)
+ // CHECK-FIXES: for (const auto & I : Right) {
// CHECK-FIXES-NEXT: if (I < OtherRight)
// Calling non-const member functions is not.
@@ -66,21 +66,21 @@ void memberFunctionsAndOperators() {
Array[I].nonConstMember(0);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES: for (auto & I : Array) {
// CHECK-FIXES-NEXT: I.nonConstMember(0);
for (int I = 0; I < N; ++I) {
Array[I] = OtherStr;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES: for (auto & I : Array) {
// CHECK-FIXES-NEXT: I = OtherStr;
for (int I = 0; I < N; ++I) {
Right[I] = OtherRight;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES: for (auto & I : Right) {
// CHECK-FIXES-NEXT: I = OtherRight;
}
@@ -90,14 +90,14 @@ void usedAsParameterToFunctionOrOperator() {
copyArg(Array[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: copyArg(I);
for (int I = 0; I < N; ++I) {
copyArg(Right[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES: for (auto & I : Right) {
// CHECK-FIXES-NEXT: copyArg(I);
// Using as a const reference argument is allowed.
@@ -105,7 +105,7 @@ void usedAsParameterToFunctionOrOperator() {
constRefArg(Array[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: constRefArg(I);
for (int I = 0; I < N; ++I) {
@@ -113,14 +113,14 @@ void usedAsParameterToFunctionOrOperator() {
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: if (OtherStr < I)
for (int I = 0; I < N; ++I) {
constRefArg(Right[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (const auto & I : Right)
+ // CHECK-FIXES: for (const auto & I : Right) {
// CHECK-FIXES-NEXT: constRefArg(I);
// Using as a non-const reference is not.
@@ -128,20 +128,20 @@ void usedAsParameterToFunctionOrOperator() {
nonConstRefArg(Array[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES: for (auto & I : Array) {
// CHECK-FIXES-NEXT: nonConstRefArg(I);
for (int I = 0; I < N; ++I) {
nonConstRefArg(Right[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES: for (auto & I : Right) {
// CHECK-FIXES-NEXT: nonConstRefArg(I);
for (int I = 0; I < N; ++I) {
if (OtherRight < Right[I])
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Right)
+ // CHECK-FIXES: for (auto & I : Right) {
// CHECK-FIXES-NEXT: if (OtherRight < I)
}
@@ -151,19 +151,19 @@ void primitiveTypes() {
copyArg(Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: copyArg(Int);
for (int I = 0; I < N; ++I) {
constRefArg(Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: constRefArg(Int);
for (int I = 0; I < N; ++I) {
nonConstRefArg(Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES: for (int & Int : Ints) {
// CHECK-FIXES-NEXT: nonConstRefArg(Int);
// Builtin operators.
@@ -173,7 +173,7 @@ void primitiveTypes() {
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: if (Int < N)
for (int I = 0; I < N; ++I) {
@@ -181,7 +181,7 @@ void primitiveTypes() {
foo();
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: if (N == Int)
// Assignment.
@@ -189,21 +189,21 @@ void primitiveTypes() {
Ints[I] = OtherInt;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES: for (int & Int : Ints) {
// CHECK-FIXES-NEXT: Int = OtherInt;
for (int I = 0; I < N; ++I) {
OtherInt = Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: OtherInt = Int;
for (int I = 0; I < N; ++I) {
OtherInt = Ints[I] = OtherInt;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES: for (int & Int : Ints) {
// CHECK-FIXES-NEXT: OtherInt = Int = OtherInt;
// Arithmetic operations.
@@ -211,21 +211,21 @@ void primitiveTypes() {
OtherInt += Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: OtherInt += Int;
for (int I = 0; I < N; ++I) {
Ints[I] += Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES: for (int & Int : Ints) {
// CHECK-FIXES-NEXT: Int += Int;
for (int I = 0; I < N; ++I) {
int Res = 5 * (Ints[I] + 1) - Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: int Res = 5 * (Int + 1) - Int;
}
@@ -238,7 +238,7 @@ void takingReferences() {
Str &K = Array[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & I : Array)
+ // CHECK-FIXES: for (auto & I : Array) {
// CHECK-FIXES-NEXT: Str &J = I;
// CHECK-FIXES-NEXT: Str &K = I;
for (int I = 0; I < N; ++I) {
@@ -246,7 +246,7 @@ void takingReferences() {
const Str &K = Array[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
// CHECK-FIXES-NEXT: const Str &J = I;
// CHECK-FIXES-NEXT: const Str &K = I;
@@ -256,7 +256,7 @@ void takingReferences() {
int &K = Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & Int : Ints)
+ // CHECK-FIXES: for (int & Int : Ints) {
// CHECK-FIXES-NEXT: int &J = Int;
// CHECK-FIXES-NEXT: int &K = Int;
for (int I = 0; I < N; ++I) {
@@ -264,7 +264,7 @@ void takingReferences() {
const int &K = Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: const int &J = Int;
// CHECK-FIXES-NEXT: const int &K = Int;
@@ -274,27 +274,27 @@ void takingReferences() {
(void)J;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto J : Array)
+ // CHECK-FIXES: for (auto J : Array) {
for (int I = 0; I < N; ++I) {
Str &J = Array[I];
(void)J;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto & J : Array)
+ // CHECK-FIXES: for (auto & J : Array) {
for (int I = 0; I < N; ++I) {
const int &J = Ints[I];
(void)J;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int J : Ints)
+ // CHECK-FIXES: for (int J : Ints) {
for (int I = 0; I < N; ++I) {
int &J = Ints[I];
(void)J;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int & J : Ints)
+ // CHECK-FIXES: for (int & J : Ints) {
}
template <class T>
@@ -315,7 +315,7 @@ void testContainerOfConstIents() {
OtherInt -= Ints[I];
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
vector<const Str> Strs;
for (int I = 0; I < Strs.size(); ++I) {
@@ -323,7 +323,7 @@ void testContainerOfConstIents() {
constRefArg(Strs[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
- // CHECK-FIXES: for (auto Str : Strs)
+ // CHECK-FIXES: for (auto Str : Strs) {
}
// When we are inside a const-qualified member functions, all the data members
@@ -341,20 +341,20 @@ class TestInsideConstFunction {
copyArg(Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
for (int I = 0; I < N; ++I) {
Array[I].constMember(0);
constRefArg(Array[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
- // CHECK-FIXES: for (auto I : Array)
+ // CHECK-FIXES: for (auto I : Array) {
for (int I = 0; I < V.size(); ++I) {
if (V[I])
copyArg(V[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
- // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES: for (int I : V) {
}
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp
index 1ac555f..161427c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert
#include "structures.h"
@@ -14,7 +14,7 @@ void f() {
int B = Arr[I][A];
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES: for (auto & I : Arr) {
// CHECK-FIXES-NEXT: int A = 0;
// CHECK-FIXES-NEXT: int B = I[A];
@@ -51,7 +51,7 @@ void aliasing() {
int Y = T.X;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & T : Arr)
+ // CHECK-FIXES: for (auto & T : Arr) {
// CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: int Y = T.X;
@@ -64,7 +64,7 @@ void aliasing() {
int Z = Arr[I].X + T.X;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES: for (auto & I : Arr) {
// CHECK-FIXES-NEXT: Val &T = I;
// CHECK-FIXES-NEXT: int Y = T.X;
// CHECK-FIXES-NEXT: int Z = I.X + T.X;
@@ -75,7 +75,7 @@ void aliasing() {
int Z = Arr[I].X + T.X;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES: for (auto & I : Arr) {
// CHECK-FIXES-NEXT: Val T = I;
// CHECK-FIXES-NEXT: int Y = T.X;
// CHECK-FIXES-NEXT: int Z = I.X + T.X;
@@ -88,7 +88,7 @@ void aliasing() {
int Y = T.X;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & T : V)
+ // CHECK-FIXES: for (auto & T : V) {
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: int Y = T.X;
@@ -99,7 +99,7 @@ void aliasing() {
int Y = T.X;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & T : *Pv)
+ // CHECK-FIXES: for (auto & T : *Pv) {
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: int Y = T.X;
@@ -108,7 +108,7 @@ void aliasing() {
int Y = T.X;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Arr)
+ // CHECK-FIXES: for (auto & I : Arr) {
// CHECK-FIXES-NEXT: Val &T = func(I);
// CHECK-FIXES-NEXT: int Y = T.X;
@@ -119,8 +119,8 @@ void aliasing() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Alias : IntArr)
- // CHECK-FIXES-NEXT: if (Alias)
+ // CHECK-FIXES: for (int Alias : IntArr) {
+ // CHECK-FIXES-NEXT: if (Alias) {
for (unsigned I = 0; I < N; ++I) {
while (int Alias = IntArr[I]) {
@@ -128,8 +128,8 @@ void aliasing() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Alias : IntArr)
- // CHECK-FIXES-NEXT: while (Alias)
+ // CHECK-FIXES: for (int Alias : IntArr) {
+ // CHECK-FIXES-NEXT: while (Alias) {
for (unsigned I = 0; I < N; ++I) {
switch (int Alias = IntArr[I]) {
@@ -138,8 +138,8 @@ void aliasing() {
}
}
// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Alias : IntArr)
- // CHECK-FIXES-NEXT: switch (Alias)
+ // CHECK-FIXES: for (int Alias : IntArr) {
+ // CHECK-FIXES-NEXT: switch (Alias) {
for (unsigned I = 0; I < N; ++I) {
for (int Alias = IntArr[I]; Alias < N; ++Alias) {
@@ -147,8 +147,8 @@ void aliasing() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Alias : IntArr)
- // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias)
+ // CHECK-FIXES: for (int Alias : IntArr) {
+ // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias) {
for (unsigned I = 0; I < N; ++I) {
for (unsigned J = 0; int Alias = IntArr[I]; ++J) {
@@ -156,15 +156,15 @@ void aliasing() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Alias : IntArr)
- // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
+ // CHECK-FIXES: for (int Alias : IntArr) {
+ // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J) {
struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
for (int I = 0; I < N; ++I) {
IntRef Int(IntArr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : IntArr)
+ // CHECK-FIXES: for (int I : IntArr) {
// CHECK-FIXES-NEXT: IntRef Int(I);
int *PtrArr[N];
@@ -173,7 +173,7 @@ void aliasing() {
printf("%d\n", *P);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto P : PtrArr)
+ // CHECK-FIXES: for (auto P : PtrArr) {
// CHECK-FIXES-NEXT: printf("%d\n", *P);
IntRef Refs[N];
@@ -182,7 +182,7 @@ void aliasing() {
printf("%d\n", *P);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Ref : Refs)
+ // CHECK-FIXES: for (auto & Ref : Refs) {
// CHECK-FIXES-NEXT: int *P = Ref;
// CHECK-FIXES-NEXT: printf("%d\n", *P);
@@ -212,7 +212,7 @@ void refs_and_vals() {
Alias.X = 0;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto Alias : S_const)
+ // CHECK-FIXES: for (auto Alias : S_const) {
// CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: Alias.X = 0;
@@ -223,7 +223,7 @@ void refs_and_vals() {
Alias.X = 0;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto Alias : Ss)
+ // CHECK-FIXES: for (auto Alias : Ss) {
// CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: Alias.X = 0;
@@ -234,7 +234,7 @@ void refs_and_vals() {
Alias.X = 0;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Alias : Ss)
+ // CHECK-FIXES: for (auto & Alias : Ss) {
// CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
// CHECK-FIXES-NEXT: {}
// CHECK-FIXES-NEXT: Alias.X = 0;
@@ -246,7 +246,7 @@ void refs_and_vals() {
unsigned Othersize = Other.size();
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Dep)
+ // CHECK-FIXES: for (int & It : Dep) {
// CHECK-FIXES-NEXT: printf("%d\n", It);
// CHECK-FIXES-NEXT: const int& Idx = Other[0];
// CHECK-FIXES-NEXT: unsigned Othersize = Other.size();
@@ -255,7 +255,7 @@ void refs_and_vals() {
Other.at(i);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & i : Other)
+ // CHECK-FIXES: for (int & i : Other) {
// CHECK-FIXES: i;
for (int I = 0, E = Dep.size(); I != E; ++I) {
@@ -273,21 +273,21 @@ struct MemberNaming {
printf("%d\n", Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: printf("%d\n", Int);
for (int I = 0; I < N; ++I) {
printf("%d\n", Ints_[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Int : Ints_)
+ // CHECK-FIXES: for (int Int : Ints_) {
// CHECK-FIXES-NEXT: printf("%d\n", Int);
for (int I = 0; I < DInts.size(); ++I) {
printf("%d\n", DInts[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (int DInt : DInts)
+ // CHECK-FIXES: for (int DInt : DInts) {
// CHECK-FIXES-NEXT: printf("%d\n", DInt);
}
@@ -298,14 +298,14 @@ void MemberNaming::outOfLine() {
printf("%d\n", Ints[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Int : Ints)
+ // CHECK-FIXES: for (int Int : Ints) {
// CHECK-FIXES-NEXT: printf("%d\n", Int);
for (int I = 0; I < N; ++I) {
printf("%d\n", Ints_[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Int : Ints_)
+ // CHECK-FIXES: for (int Int : Ints_) {
// CHECK-FIXES-NEXT: printf("%d\n", Int);
}
@@ -334,7 +334,7 @@ void sameNames() {
(void)Nums[I];
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Nums)
+ // CHECK-FIXES: for (int & I : Nums) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2 + Num;
// CHECK-FIXES-NEXT: (void)I;
@@ -346,7 +346,7 @@ void sameNames() {
(void)Nums[I];
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Nums)
+ // CHECK-FIXES: for (int & I : Nums) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2 + Num + Elem;
// CHECK-FIXES-NEXT: (void)I;
@@ -357,7 +357,7 @@ void oldIndexConflict() {
printf("Num: %d\n", Nums[Num]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int Num : Nums)
+ // CHECK-FIXES: for (int Num : Nums) {
// CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
S Things;
@@ -365,7 +365,7 @@ void oldIndexConflict() {
printf("Thing: %d %d\n", Thing->X, (*Thing).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Thing : Things)
+ // CHECK-FIXES: for (auto & Thing : Things) {
// CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
}
@@ -376,7 +376,7 @@ void macroConflict() {
printf("Max of 3 and 5: %d\n", MAX(3, 5));
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : MAXs)
+ // CHECK-FIXES: for (auto & It : MAXs) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
// CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
@@ -385,7 +385,7 @@ void macroConflict() {
printf("Max of 3 and 5: %d\n", MAX(3, 5));
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto It : MAXs)
+ // CHECK-FIXES: for (auto It : MAXs) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
// CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
@@ -396,8 +396,8 @@ void macroConflict() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : DEFs)
- // CHECK-FIXES-NEXT: if (It == DEF)
+ // CHECK-FIXES: for (int & It : DEFs) {
+ // CHECK-FIXES-NEXT: if (It == DEF) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
}
@@ -407,7 +407,7 @@ void keywordConflict() {
*It = 5;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : ints)
+ // CHECK-FIXES: for (int & It : ints) {
// CHECK-FIXES-NEXT: It = 5;
U __FUNCTION__s;
@@ -416,7 +416,7 @@ void keywordConflict() {
int __FUNCTION__s_It = (*It).X + 2;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : __FUNCTION__s)
+ // CHECK-FIXES: for (auto & It : __FUNCTION__s) {
// CHECK-FIXES-NEXT: int __FUNCTION__s_It = It.X + 2;
}
@@ -435,7 +435,7 @@ void typeConflict() {
*It = sizeof(Val);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Vals)
+ // CHECK-FIXES: for (int & It : Vals) {
// CHECK-FIXES-NEXT: It = sizeof(Val);
typedef struct Val TD;
@@ -454,7 +454,7 @@ void typeConflict() {
(void) *It;
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : TDs)
+ // CHECK-FIXES: for (auto & It : TDs) {
// CHECK-FIXES-NEXT: TD V;
// CHECK-FIXES-NEXT: V.X = 5;
@@ -464,7 +464,7 @@ void typeConflict() {
*It = sizeof(St);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Sts)
+ // CHECK-FIXES: for (int & It : Sts) {
// CHECK-FIXES-NEXT: It = sizeof(St);
}
@@ -528,8 +528,8 @@ void f() {
}
// CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead
// CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Arr)
- // CHECK-FIXES-NEXT: for (auto & J : Arr)
+ // CHECK-FIXES: for (auto & I : Arr) {
+ // CHECK-FIXES-NEXT: for (auto & J : Arr) {
// CHECK-FIXES-NEXT: int K = I.X + J.X;
// CHECK-FIXES-NOT: int L = I.X + I.X;
@@ -542,8 +542,8 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Nest)
- // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J)
+ // CHECK-FIXES: for (auto & I : Nest) {
+ // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J) {
// CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
// Note that the order of M and N are switched for this test.
@@ -554,8 +554,8 @@ void f() {
}
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
// CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[I])
- // CHECK-FIXES: for (int J = 0; J < M; ++J)
- // CHECK-FIXES-NEXT: for (auto & I : Nest)
+ // CHECK-FIXES: for (int J = 0; J < M; ++J) {
+ // CHECK-FIXES-NEXT: for (auto & I : Nest) {
// CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
// The inner loop is also convertible.
@@ -566,8 +566,8 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : NestT)
- // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI)
+ // CHECK-FIXES: for (auto & I : NestT) {
+ // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI) {
// CHECK-FIXES-NEXT: printf("%d", *TI);
// The inner loop is also convertible.
@@ -578,8 +578,8 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto I : NestS)
- // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI)
+ // CHECK-FIXES: for (auto I : NestS) {
+ // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI) {
// CHECK-FIXES-NEXT: printf("%d", *SI);
for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
@@ -590,7 +590,7 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto Ss : NestS)
+ // CHECK-FIXES: for (auto Ss : NestS) {
for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
S &Ss = *I;
@@ -600,7 +600,7 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Ss : NestS)
+ // CHECK-FIXES: for (auto & Ss : NestS) {
Foo foo;
for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
@@ -611,7 +611,7 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto Ss : NestS)
+ // CHECK-FIXES: for (auto Ss : NestS) {
for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
S &Ss = *I;
@@ -621,7 +621,7 @@ void f() {
}
}
// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & Ss : NestS)
+ // CHECK-FIXES: for (auto & Ss : NestS) {
}
@@ -638,7 +638,7 @@ void complexContainer() {
MutableVal J = *I;
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & I : Exes[Index].getS())
+ // CHECK-FIXES: for (auto & I : Exes[Index].getS()) {
// CHECK-FIXES-NEXT: MutableVal K = I;
// CHECK-FIXES-NEXT: MutableVal J = I;
}
@@ -650,7 +650,7 @@ void f() {
printf("I found %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : Tt)
+ // CHECK-FIXES: for (int & It : Tt) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
T *Pt;
@@ -658,7 +658,7 @@ void f() {
printf("I found %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : *Pt)
+ // CHECK-FIXES: for (int & It : *Pt) {
// CHECK-FIXES-NEXT: printf("I found %d\n", It);
S Ss;
@@ -666,7 +666,7 @@ void f() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
S *Ps;
@@ -674,35 +674,35 @@ void f() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & P : *Ps)
+ // CHECK-FIXES: for (auto & P : *Ps) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
printf("s has value %d\n", It->X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
It->X = 3;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.X = 3;
for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
(*It).X = 3;
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.X = 3;
for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
It->nonConstFun(4, 5);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Ss)
+ // CHECK-FIXES: for (auto & It : Ss) {
// CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
U Uu;
@@ -710,14 +710,14 @@ void f() {
printf("s has value %d\n", It->X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES: for (auto & It : Uu) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : Uu)
+ // CHECK-FIXES: for (auto & It : Uu) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
U::iterator A;
@@ -733,7 +733,7 @@ void f() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES: for (int & It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
for (dependent<int>::iterator It(V.begin());
@@ -741,7 +741,7 @@ void f() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & It : V)
+ // CHECK-FIXES: for (int & It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
doublyDependent<int, int> intmap;
@@ -750,7 +750,7 @@ void f() {
printf("intmap[%d] = %d", It->first, It->second);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto & It : intmap)
+ // CHECK-FIXES: for (auto & It : intmap) {
// CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second);
}
@@ -765,7 +765,7 @@ void different_type() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto It : Ss)
+ // CHECK-FIXES: for (auto It : Ss) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
S *Ps;
@@ -773,7 +773,7 @@ void different_type() {
printf("s has value %d\n", (*It).X);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (auto P : *Ps)
+ // CHECK-FIXES: for (auto P : *Ps) {
// CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
dependent<int> V;
@@ -781,14 +781,14 @@ void different_type() {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int It : V)
+ // CHECK-FIXES: for (int It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
for (dependent<int>::const_iterator It(V.begin()); It != V.end(); ++It) {
printf("Fibonacci number is %d\n", *It);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int It : V)
+ // CHECK-FIXES: for (int It : V) {
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
}
@@ -808,7 +808,7 @@ void messing_with_macros() {
printf("Value: %d\n", Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: printf("Value: %d\n", I);
for (int I = 0; I < N; ++I) {
@@ -821,7 +821,7 @@ void messing_with_macros() {
THREE_PARAM(Arr[I], Arr[I], Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES: for (int & I : Arr) {
// CHECK-FIXES-NEXT: TWO_PARAM(I, I);
// CHECK-FIXES-NEXT: THREE_PARAM(I, I, I);
}
@@ -907,10 +907,11 @@ void capturesIndex() {
F(Arr[I]);
}
// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
- // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k)
- // CHECK-FIXES-NEXT: printf("%d\n", I + k);
- // CHECK-FIXES: F(I);
+ // CHECK-FIXES: for (int I : Arr) {
+ // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k) {
+ // CHECK-FIXES-NEXT: printf("%d\n", I + k);
+ // CHECK-FIXES-NEXT: };
+ // CHECK-FIXES-NEXT: F(I);
}
void implicitCapture() {
@@ -939,8 +940,8 @@ void implicitCapture() {
};
}
// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
- // CHECK-FIXES-NEXT: auto G3 = [&]()
+ // CHECK-FIXES: for (int I : Arr) {
+ // CHECK-FIXES-NEXT: auto G3 = [&]() {
// CHECK-FIXES-NEXT: int R3 = I;
// CHECK-FIXES-NEXT: int J3 = I + R3;
@@ -950,8 +951,8 @@ void implicitCapture() {
};
}
// CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
- // CHECK-FIXES-NEXT: auto G4 = [=]()
+ // CHECK-FIXES: for (int I : Arr) {
+ // CHECK-FIXES-NEXT: auto G4 = [=]() {
// CHECK-FIXES-NEXT: int R4 = I + 5;
// Alias by value.
@@ -962,8 +963,8 @@ void implicitCapture() {
};
}
// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int R5 : Arr)
- // CHECK-FIXES-NEXT: auto G5 = [&]()
+ // CHECK-FIXES: for (int R5 : Arr) {
+ // CHECK-FIXES-NEXT: auto G5 = [&]() {
// CHECK-FIXES-NEXT: int J5 = 8 + R5;
// Alias by reference.
@@ -974,8 +975,8 @@ void implicitCapture() {
};
}
// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int & R6 : Arr)
- // CHECK-FIXES-NEXT: auto G6 = [&]()
+ // CHECK-FIXES: for (int & R6 : Arr) {
+ // CHECK-FIXES-NEXT: auto G6 = [&]() {
// CHECK-FIXES-NEXT: int J6 = -1 + R6;
}
@@ -1029,14 +1030,14 @@ void captureByValue() {
auto C1 = [&Arr, I]() { if (Arr[I] == 1); };
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Arr)
+ // CHECK-FIXES: for (int I : Arr) {
// CHECK-FIXES-NEXT: auto C1 = [&Arr, &I]() { if (I == 1); };
for (unsigned I = 0; I < Dep.size(); ++I) {
auto C2 = [&Dep, I]() { if (Dep[I] == 2); };
}
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Dep)
+ // CHECK-FIXES: for (int I : Dep) {
// CHECK-FIXES-NEXT: auto C2 = [&Dep, &I]() { if (I == 2); };
}
@@ -1062,7 +1063,7 @@ void f() {
E Ee{ { { g( { Array[I] } ) } } };
}
// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for (int I : Array)
+ // CHECK-FIXES: for (int I : Array) {
// CHECK-FIXES-NEXT: int A{ I };
// CHECK-FIXES-NEXT: int B{ g(I) };
// CHECK-FIXES-NEXT: int C{ g( { I } ) };
@@ -1079,7 +1080,7 @@ void bug28341() {
if (value > 127)
;
// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
- // CHECK-FIXES: for(unsigned char value : v)
+ // CHECK-FIXES: for(unsigned char value : v) {
// CHECK-FIXES-NEXT: if (value > 127)
}
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
index 65ece77..686b998 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-make-shared %t -- -- -I %S/Inputs/smart-ptr
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -I %S/Inputs/smart-ptr
#include "shared_ptr.h"
// CHECK-FIXES: #include <memory>
@@ -226,7 +226,7 @@ void initialization(int T, Base b) {
// CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
PAggr.reset(new APair{T, 1});
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
- // CHECK-FIXES: std::make_shared<APair>(APair{T, 1});
+ // CHECK-FIXES: PAggr = std::make_shared<APair>(APair{T, 1});
// Test different kinds of initialization of the pointee, when the shared_ptr
// is initialized with braces.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
index 13103c7..bcdf4fb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr
+// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr
#include "unique_ptr.h"
#include "initializer_list.h"
@@ -271,7 +271,7 @@ void initialization(int T, Base b) {
// CHECK-FIXES: std::unique_ptr<APair> PAggr = std::make_unique<APair>(APair{T, 1});
PAggr.reset(new APair{T, 1});
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
- // CHECK-FIXES: std::make_unique<APair>(APair{T, 1});
+ // CHECK-FIXES: PAggr = std::make_unique<APair>(APair{T, 1});
// Check aggregate init with intermediate temporaries.
std::unique_ptr<APair> PAggrTemp = std::unique_ptr<APair>(new APair({T, 1}));
@@ -480,7 +480,7 @@ void initialization(int T, Base b) {
std::unique_ptr<int[]> FI;
FI.reset(new int[5]()); // value initialization.
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
- // CHECK-FIXES: FI = std::make_unique<int[]>(5);
+ // CHECK-FIXES: FI = std::make_unique<int[]>(5); // value initialization.
// The check doesn't give warnings and fixes for cases where the original new
// expression does default initialization.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp
index ae270dc..9dc05b9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-min-max-use-initializer-list %t
+// RUN: %check_clang_tidy %s modernize-min-max-use-initializer-list %t
// CHECK-FIXES: #include <algorithm>
namespace utils {
@@ -206,7 +206,7 @@ int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than);
// CHECK-FIXES: int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than);
int max8 = std::max(1, std::max(2, 3, fless_than), less_than);
-// CHECK-FIXES: int max8 = std::max(1, std::max(2, 3, fless_than), less_than)
+// CHECK-FIXES: int max8 = std::max(1, std::max(2, 3, fless_than), less_than);
int min8 = std::min(1, std::min(2, 3, fless_than), less_than);
// CHECK-FIXES: int min8 = std::min(1, std::min(2, 3, fless_than), less_than);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp
index 7538862..cc237f4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing
namespace {
// POD types are trivially move constructible.
@@ -92,7 +92,7 @@ struct H {
using namespace ns_H;
H::H(const HMovable &M) : M(M) {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
-// CHECK-FIXES: H(HMovable M) : M(std::move(M)) {}
+// CHECK-FIXES: H::H(HMovable M) : M(std::move(M)) {}
// Try messing up with macros.
#define MOVABLE_PARAM(Name) const Movable & Name
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp
index 935163b..6311497 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-redundant-void-arg %t
+// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t
#define NULL 0
@@ -452,22 +452,22 @@ struct DefinitionWithNoBody {
#define BODY {}
#define LAMBDA1 [](void){}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
-// CHECK-FIXES: LAMBDA1 [](){}
+// CHECK-FIXES: #define LAMBDA1 [](){}
#define LAMBDA2 [](void)BODY
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
-// CHECK-FIXES: LAMBDA2 []()BODY
+// CHECK-FIXES: #define LAMBDA2 []()BODY
#define LAMBDA3(captures, args, body) captures args body
#define WRAP(...) __VA_ARGS__
#define LAMBDA4 (void)LAMBDA3([],(void),BODY)
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
-// CHECK-FIXES: LAMBDA4 (void)LAMBDA3([],(),BODY)
+// CHECK-FIXES: #define LAMBDA4 (void)LAMBDA3([],(),BODY)
#define LAMBDA5 []() -> void (*)(void) {return BODY;}
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
-// CHECK-FIXES: LAMBDA5 []() -> void (*)() {return BODY;}
+// CHECK-FIXES: #define LAMBDA5 []() -> void (*)() {return BODY;}
void lambda_expression_with_macro_test(){
(void)LAMBDA1;
(void)LAMBDA2;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp
index dea0857..2281c1a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/replace-auto-ptr
+// RUN: %check_clang_tidy %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/replace-auto-ptr
// CHECK-FIXES: #include <utility>
@@ -15,7 +15,7 @@ std::auto_ptr<Derived> create_derived_ptr();
// Test function return values (declaration)
std::auto_ptr<char> f_5();
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
-// CHECK-FIXES: std::unique_ptr<char> f_5()
+// CHECK-FIXES: std::unique_ptr<char> f_5();
// Test function parameters.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp
index 5b620ad..59d6d23a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
// RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'true' , modernize-use-auto.MinTypeNameLength: '0'}}" \
// RUN: -- -frtti
@@ -108,7 +108,7 @@ typedef unsigned char xmlChar;
do { \
xmlChar *s = (xmlChar *)(x); \
} while (false);
-// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); {{\\}}
void f_cstyle_cast() {
auto *a = new A();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp
index 3946b97..7f687ab 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
// RUN: -config="{CheckOptions: {modernize-use-auto.MinTypeNameLength: '0'}}" \
// RUN: -- -I %S/Inputs/use-auto -frtti
@@ -108,7 +108,7 @@ typedef unsigned char xmlChar;
do { \
xmlChar *s = (xmlChar *)(x); \
} while (false);
-// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); {{\\}}
void f_cstyle_cast() {
auto *a = new A();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp
index 1fd4189..2cb0208 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp
@@ -1,20 +1,20 @@
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=REMOVE %s modernize-use-auto %t -- \
+// RUN: %check_clang_tidy -check-suffix=REMOVE %s modernize-use-auto %t -- \
// RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'true', modernize-use-auto.MinTypeNameLength: '0'}}"
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
// RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'false', modernize-use-auto.MinTypeNameLength: '0'}}"
void pointerToFunction() {
void (*(*(f1)))() = static_cast<void (**)()>(nullptr);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing
- // CHECK-FIXES-REMOVE: auto f1 =
- // CHECK-FIXES: auto *f1 =
+ // CHECK-FIXES-REMOVE: auto f1 = static_cast<void (**)()>(nullptr);
+ // CHECK-FIXES: auto *f1 = static_cast<void (**)()>(nullptr);
}
void pointerToArray() {
int(*a1)[2] = new int[10][2];
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing
- // CHECK-FIXES-REMOVE: auto a1 =
- // CHECK-FIXES: auto *a1 =
+ // CHECK-FIXES-REMOVE: auto a1 = new int[10][2];
+ // CHECK-FIXES: auto *a1 = new int[10][2];
}
void memberFunctionPointer() {
@@ -23,7 +23,7 @@ void memberFunctionPointer() {
};
void(A::* a1)() = static_cast<void(A::*)()>(nullptr);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing
- // CHECK-FIXES-REMOVE: auto a1 =
- // CHECK-FIXES: auto *a1 =
+ // CHECK-FIXES-REMOVE: auto a1 = static_cast<void(A::*)()>(nullptr);
+ // CHECK-FIXES: auto *a1 = static_cast<void(A::*)()>(nullptr);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp
index 02fb646..a928b33 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/use-auto
+// RUN: %check_clang_tidy -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/use-auto
// FIXME: Fix the checker to work in C++17 mode.
#include "containers.h"
@@ -277,18 +277,18 @@ void pointer_to_iterator() {
void loop() {
for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) {
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
- // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I)
+ // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I) {
}
for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) {
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
- // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I)
+ // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I) {
}
std::vector<std::vector<int>::iterator> IterVec;
for (std::vector<int>::iterator I : IterVec) {
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
- // CHECK-FIXES: for (auto I : IterVec)
+ // CHECK-FIXES: for (auto I : IterVec) {
}
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp
index 6cea26e..e954cee 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp
@@ -1,7 +1,7 @@
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti
template <class T> extern T foo();
template <class T> struct P { explicit P(T t) : t_(t) {} T t_;};
@@ -17,10 +17,10 @@ int bar() {
// CHECK-FIXES-1-0: auto i = {{.*}}
// CHECK-FIXES-1-8: long i = {{.*}}
const long ci = static_cast<long>(foo<const long>());
- // CHECK-FIXES-0-0: auto ci = {{.*}}
- // CHECK-FIXES-0-8: long ci = {{.*}}
- // CHECK-FIXES-1-0: auto ci = {{.*}}
- // CHECK-FIXES-1-8: long ci = {{.*}}
+ // CHECK-FIXES-0-0: const auto ci = {{.*}}
+ // CHECK-FIXES-0-8: const long ci = {{.*}}
+ // CHECK-FIXES-1-0: const auto ci = {{.*}}
+ // CHECK-FIXES-1-8: const long ci = {{.*}}
long *pi = static_cast<long *>(foo<long *>());
// CHECK-FIXES-0-0: auto *pi = {{.*}}
// CHECK-FIXES-0-8: long *pi = {{.*}}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
index 9639e0e..3afa4a4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-equals-default %t -- \
+// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- \
// RUN: -config="{CheckOptions: {modernize-use-equals-default.IgnoreMacros: false}}" \
// RUN: -- -fno-delayed-template-parsing -fexceptions -Wno-error=return-type
@@ -35,7 +35,7 @@ struct IL {
// Skip unions.
union NU {
NU(const NU &Other) : Field(Other.Field) {}
- // CHECK-FIXES: NU(const NU &Other) :
+ // CHECK-FIXES: NU(const NU &Other) : Field(Other.Field) {}
NU &operator=(const NU &Other) {
Field = Other.Field;
return *this;
@@ -47,7 +47,7 @@ union NU {
// Skip structs/classes containing anonymous unions.
struct SU {
SU(const SU &Other) : Field(Other.Field) {}
- // CHECK-FIXES: SU(const SU &Other) :
+ // CHECK-FIXES: SU(const SU &Other) : Field(Other.Field) {}
SU &operator=(const SU &Other) {
Field = Other.Field;
return *this;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
index a606b84..2eefdf9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
// Out of line definition.
class OL {
@@ -145,7 +145,7 @@ struct ST {
// CHECK-FIXES: ST() = default;
~ST() {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
- // CHECK-FIXES: ST() = default;
+ // CHECK-FIXES: ~ST() = default;
};
// Deleted constructor/destructor.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp
index 135ee27..1f26ff3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++17 %s modernize-use-integer-sign-comparison %t -- \
+// RUN: %check_clang_tidy -std=c++17 %s modernize-use-integer-sign-comparison %t -- \
// RUN: -config="{CheckOptions: {modernize-use-integer-sign-comparison.EnableQtSupport: true}}"
// CHECK-FIXES: #include <QtCore/q20utility.h>
@@ -92,7 +92,8 @@ int AllComparisons() {
if (static_cast<unsigned int>(uArray[2]) < static_cast<int>(sArray[2]))
return 0;
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison]
-// CHECK-FIXES: if (q20::cmp_less(uArray[2],sArray[2]))
+// CHECK-FIXES: if (q20::cmp_less(uArray[2],sArray[2])))
+// FIXME: There should only be 2 closing braces. The fix-it inserts an unbalanced one.
if ((unsigned int)uArray[3] < (int)sArray[3])
return 0;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp
index e0a84ef..628cee0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++20 %s modernize-use-integer-sign-comparison %t
+// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-integer-sign-comparison %t
// CHECK-FIXES: #include <utility>
@@ -91,7 +91,8 @@ int AllComparisons() {
if (static_cast<unsigned int>(uArray[2]) < static_cast<int>(sArray[2]))
return 0;
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison]
-// CHECK-FIXES: if (std::cmp_less(uArray[2],sArray[2]))
+// CHECK-FIXES: if (std::cmp_less(uArray[2],sArray[2])))
+// FIXME: There should only be 2 closing braces. The fix-it inserts an unbalanced one.
if ((unsigned int)uArray[3] < (int)sArray[3])
return 0;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp
index fe9d6de..27a9629 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-nullptr %t -- \
+// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- \
// RUN: -config="{CheckOptions: {modernize-use-nullptr.NullMacros: 'MY_NULL,NULL'}}"
#define NULL 0
@@ -91,7 +91,7 @@ template <typename T> struct pear {
// it is often defined as __null and the check will catch it.)
void f() { x = __null; }
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr [modernize-use-nullptr]
- // CHECK-FIXES: x = nullptr;
+ // CHECK-FIXES: void f() { x = nullptr; }
// But if you say 0, we allow the possibility that T can be used with integral
// and pointer types, and "0" is an acceptable initializer (even if "{}" might
@@ -118,11 +118,13 @@ void test_macro_args() {
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
// CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);
- IS_EQ(0, Ptr); // literal
+ // literal
+ IS_EQ(0, Ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
// CHECK-FIXES: IS_EQ(nullptr, Ptr);
- IS_EQ(NULL, Ptr); // macro
+ // macro
+ IS_EQ(NULL, Ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
// CHECK-FIXES: IS_EQ(nullptr, Ptr);
@@ -205,7 +207,7 @@ void test_macro_args() {
} a[2] = {ENTRY(0), {0}};
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
- // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
+ // CHECK-FIXES: } a[2] = {ENTRY(nullptr), {nullptr}};
#undef ENTRY
#define assert1(expr) (expr) ? 0 : 1
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp
index 809e435..8e19fdd 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions
+// RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions
#define ABSTRACT = 0
@@ -96,7 +96,8 @@ public:
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
// CHECK-FIXES: void j() const override;
- virtual MustUseResultObject k(); // Has an implicit attribute.
+ // Has an implicit attribute.
+ virtual MustUseResultObject k();
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
// CHECK-FIXES: MustUseResultObject k() override;
@@ -203,7 +204,8 @@ public:
// CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
// CHECK-FIXES: void j() const override
- virtual MustUseResultObject k(); // Has an implicit attribute.
+ // Has an implicit attribute.
+ virtual MustUseResultObject k();
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
// CHECK-FIXES: MustUseResultObject k() override;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp
index ea97d5b..6a6cb98 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp
@@ -1,11 +1,11 @@
-// RUN: %check_clang_tidy --match-partial-fixes \
-// RUN: -std=c++20 %s modernize-use-std-format %t -- \
+// RUN: %check_clang_tidy \
+// RUN: -std=c++20-or-later %s modernize-use-std-format %t -- \
// RUN: -config="{CheckOptions: {modernize-use-std-format.StrictMode: true}}" \
// RUN: -- -isystem %clang_tidy_headers \
// RUN: -DPRI_CMDLINE_MACRO="\"s\"" \
// RUN: -D__PRI_CMDLINE_MACRO="\"s\""
-// RUN: %check_clang_tidy --match-partial-fixes \
-// RUN: -std=c++20 %s modernize-use-std-format %t -- \
+// RUN: %check_clang_tidy \
+// RUN: -std=c++20-or-later %s modernize-use-std-format %t -- \
// RUN: -config="{CheckOptions: {modernize-use-std-format.StrictMode: false}}" \
// RUN: -- -isystem %clang_tidy_headers \
// RUN: -DPRI_CMDLINE_MACRO="\"s\"" \
@@ -70,32 +70,32 @@ std::string StrFormat_strict_conversion() {
std::string StrFormat_field_width_and_precision() {
auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
+ // CHECK-FIXES: auto s1 = std::format("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f after", 3.14159265358979323846, 4, 2);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
+ // CHECK-FIXES: auto s2 = std::format("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
const int width = 10, precision = 3;
const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
- // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5);
+ // CHECK-FIXES-NOTSTRICT: auto s3 = std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
+ // CHECK-FIXES-STRICT: auto s3 = std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5);
auto s4 = absl::StrFormat("c_str removal width only:%*s width and precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str());
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
+ // CHECK-FIXES: auto s4 = std::format("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3;
auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str());
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
+ // CHECK-FIXES: auto s5 = std::format("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
iterator<std::string> is1, is2, is3;
auto s6 = absl::StrFormat("c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str());
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
+ // CHECK-FIXES: auto s6 = std::format("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
return s1 + s2 + s3 + s4 + s5 + s6;
}
@@ -105,7 +105,7 @@ void StrFormat_macros() {
#define FORMAT absl::StrFormat
auto s1 = FORMAT("Hello %d", 42);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("Hello {}", 42);
+ // CHECK-FIXES: auto s1 = std::format("Hello {}", 42);
// Arguments that are macros aren't replaced with their value, even if they are rearranged.
#define VALUE 3.14159265358979323846
@@ -113,7 +113,7 @@ void StrFormat_macros() {
#define PRECISION 4
auto s3 = absl::StrFormat("Hello %*.*f", WIDTH, PRECISION, VALUE);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("Hello {:{}.{}f}", VALUE, WIDTH, PRECISION);
+ // CHECK-FIXES: auto s3 = std::format("Hello {:{}.{}f}", VALUE, WIDTH, PRECISION);
const uint64_t u64 = 42;
const uint32_t u32 = 32;
@@ -121,11 +121,11 @@ void StrFormat_macros() {
auto s4 = absl::StrFormat("Replaceable macro at end %" PRIu64, u64);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("Replaceable macro at end {}", u64);
+ // CHECK-FIXES: auto s4 = std::format("Replaceable macro at end {}", u64);
auto s5 = absl::StrFormat("Replaceable macros in middle %" PRIu64 " %" PRIu32 "\n", u64, u32);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format]
- // CHECK-FIXES: std::format("Replaceable macros in middle {} {}\n", u64, u32);
+ // CHECK-FIXES: auto s5 = std::format("Replaceable macros in middle {} {}\n", u64, u32);
// These need PRI and __PRI prefixes so that the check get as far as looking for
// where the macro comes from.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
index 9bf60e7..ec37f07 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
@@ -1,11 +1,11 @@
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffixes=,STRICT \
-// RUN: -std=c++23 %s modernize-use-std-print %t -- \
+// RUN: %check_clang_tidy -check-suffixes=,STRICT \
+// RUN: -std=c++23-or-later %s modernize-use-std-print %t -- \
// RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: true}}" \
// RUN: -- -isystem %clang_tidy_headers -fexceptions \
// RUN: -DPRI_CMDLINE_MACRO="\"s\"" \
// RUN: -D__PRI_CMDLINE_MACRO="\"s\""
-// RUN: %check_clang_tidy --match-partial-fixes -check-suffixes=,NOTSTRICT \
-// RUN: -std=c++23 %s modernize-use-std-print %t -- \
+// RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \
+// RUN: -std=c++23-or-later %s modernize-use-std-print %t -- \
// RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: false}}" \
// RUN: -- -isystem %clang_tidy_headers -fexceptions \
// RUN: -DPRI_CMDLINE_MACRO="\"s\"" \
@@ -113,7 +113,7 @@ int printf_uses_return_value(int choice) {
for (printf("for init statement %d\n", i);;)
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
- // CHECK-FIXES: std::println("for init statement {}", i);
+ // CHECK-FIXES: for (std::println("for init statement {}", i);;)
;;
for (int j = printf("for init statement %d\n", i);;)
@@ -124,7 +124,7 @@ int printf_uses_return_value(int choice) {
for (;; printf("for expression %d\n", i))
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
- // CHECK-FIXES: std::println("for expression {}", i)
+ // CHECK-FIXES: for (;; std::println("for expression {}", i))
;;
for (auto C : "foo")
@@ -228,7 +228,7 @@ int fprintf_uses_return_value(int choice) {
for (fprintf(stderr, "for init statement %d\n", i);;)
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
- // CHECK-FIXES: std::println(stderr, "for init statement {}", i);
+ // CHECK-FIXES: for (std::println(stderr, "for init statement {}", i);;)
;;
for (int j = fprintf(stderr, "for init statement %d\n", i);;)
@@ -239,7 +239,7 @@ int fprintf_uses_return_value(int choice) {
for (;; fprintf(stderr, "for expression %d\n", i))
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
- // CHECK-FIXES: std::println(stderr, "for expression {}", i)
+ // CHECK-FIXES: for (;; std::println(stderr, "for expression {}", i))
;;
for (auto C : "foo")
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp
index 53d66ec..967fd0f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp
@@ -1,33 +1,33 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s performance-noexcept-move-constructor %t -- -- -fexceptions
+// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions
struct C_1 {
~C_1() {}
C_1(int a) {}
C_1(C_1&& a) :C_1(5) {}
- // CHECK-FIXES: ){{.*}}noexcept{{.*}}:
+ // CHECK-FIXES: C_1(C_1&& a) noexcept :C_1(5) {}
C_1& operator=(C_1&&) { return *this; }
- // CHECK-FIXES: ){{.*}}noexcept{{.*}} {
+ // CHECK-FIXES: C_1& operator=(C_1&&) noexcept { return *this; }
};
struct C_2 {
~C_2() {}
C_2(C_2&& a);
-// CHECK-FIXES: ){{.*}}noexcept{{.*}};
+// CHECK-FIXES: C_2(C_2&& a) noexcept ;
C_2& operator=(C_2&&);
-// CHECK-FIXES: ){{.*}}noexcept{{.*}};
+// CHECK-FIXES: C_2& operator=(C_2&&) noexcept ;
};
C_2::C_2(C_2&& a) {}
-// CHECK-FIXES: ){{.*}}noexcept{{.*}} {}
+// CHECK-FIXES: C_2::C_2(C_2&& a) noexcept {}
C_2& C_2::operator=(C_2&&) { return *this; }
-// CHECK-FIXES: ){{.*}}noexcept{{.*}} {
+// CHECK-FIXES: C_2& C_2::operator=(C_2&&) noexcept { return *this; }
struct C_3 {
~C_3() {}
C_3(C_3&& a);
-// CHECK-FIXES: ){{.*}}noexcept{{.*}};
+// CHECK-FIXES: C_3(C_3&& a) noexcept ;
C_3& operator=(C_3&& a);
-// CHECK-FIXES: ){{.*}}noexcept{{.*}};
+// CHECK-FIXES: C_3& operator=(C_3&& a) noexcept ;
};
C_3::C_3(C_3&& a) = default;
@@ -36,7 +36,7 @@ C_3& C_3::operator=(C_3&& a) = default;
template <class T>
struct C_4 {
C_4(C_4<T>&&) {}
-// CHECK-FIXES: ){{.*}}noexcept{{.*}} {}
+// CHECK-FIXES: C_4(C_4<T>&&) noexcept {}
~C_4() {}
C_4& operator=(C_4&& a) = default;
};
@@ -44,7 +44,7 @@ struct C_4 {
template <class T>
struct C_5 {
C_5(C_5<T>&&) {}
-// CHECK-FIXES:){{.*}}noexcept{{.*}} {}
+// CHECK-FIXES: C_5(C_5<T>&&) noexcept {}
~C_5() {}
auto operator=(C_5&& a)->C_5<T> = default;
};
@@ -52,12 +52,12 @@ struct C_5 {
template <class T>
struct C_6 {
C_6(C_6<T>&&) {}
-// CHECK-FIXES:){{.*}}noexcept{{.*}} {}
+// CHECK-FIXES: C_6(C_6<T>&&) noexcept {}
~C_6() {}
auto operator=(C_6&& a)->C_6<T>;
-// CHECK-FIXES:){{.*}}noexcept{{.*}};
+// CHECK-FIXES: auto operator=(C_6&& a) noexcept ->C_6<T>;
};
template <class T>
auto C_6<T>::operator=(C_6<T>&& a) -> C_6<T> {}
-// CHECK-FIXES: ){{.*}}noexcept{{.*}} {}
+// CHECK-FIXES: auto C_6<T>::operator=(C_6<T>&& a) noexcept -> C_6<T> {}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp
index 0168aee..4818e9d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++17-or-later %s performance-unnecessary-copy-initialization %t
+// RUN: %check_clang_tidy -std=c++17-or-later %s performance-unnecessary-copy-initialization %t
template <typename T>
struct Iterator {
@@ -469,7 +469,7 @@ struct NegativeConstructor {
auto AssignedInMacro = T.reference(); \
} \
// Ensure fix is not applied.
-// CHECK-FIXES: auto AssignedInMacro = T.reference();
+// CHECK-FIXES: auto AssignedInMacro = T.reference(); {{\\}}
UNNECESSARY_COPY_INIT_IN_MACRO_BODY(ExpensiveToCopyType)
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the variable 'AssignedInMacro' of type 'ExpensiveToCopyType' is copy-constructed
@@ -480,7 +480,7 @@ void PositiveMacroArgument(const ExpensiveToCopyType &Obj) {
UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference());
// CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' of type 'ExpensiveToCopyType' is copy-constructed
// Ensure fix is not applied.
- // CHECK-FIXES: auto CopyInMacroArg = Obj.reference()
+ // CHECK-FIXES: UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference());
CopyInMacroArg.constMethod();
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp
index 9df1d6f..42d7699 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing
struct ExpensiveToCopyType {
const ExpensiveToCopyType & constReference() const {
@@ -152,7 +152,7 @@ void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference
void inMacro(const ExpensiveToCopyType T) { \
} \
// Ensure fix is not applied.
-// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) {
+// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { {{\\}}
UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'
@@ -162,7 +162,7 @@ UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
// CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'
-// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}
+// CHECK-FIXES: UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
struct VirtualMethod {
virtual ~VirtualMethod() {}
@@ -171,7 +171,7 @@ struct VirtualMethod {
struct NegativeOverriddenMethod : public VirtualMethod {
void handle(ExpensiveToCopyType Overridden) const {
- // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const {
+ // CHECK-FIXES: void handle(ExpensiveToCopyType Overridden) const {
}
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp
index f657ff5..8dc13d3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s performance-unnecessary-value-param %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fno-delayed-template-parsing
// CHECK-FIXES: #include <utility>
@@ -215,7 +215,7 @@ void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference
void inMacro(const ExpensiveToCopyType T) { \
} \
// Ensure fix is not applied.
-// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) {
+// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { {{\\}}
UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T'
@@ -225,7 +225,7 @@ UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY()
UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
// CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg'
-// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}
+// CHECK-FIXES: UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {})
struct VirtualMethod {
virtual ~VirtualMethod() {}
@@ -234,7 +234,7 @@ struct VirtualMethod {
struct NegativeOverriddenMethod : public VirtualMethod {
void handle(ExpensiveToCopyType Overridden) const {
- // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const {
+ // CHECK-FIXES: void handle(ExpensiveToCopyType Overridden) const {
}
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp
index b74c4cb..f1bb4ed 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-braces-around-statements %t
+// RUN: %check_clang_tidy %s readability-braces-around-statements %t
void do_something(const char *) {}
@@ -77,9 +77,6 @@ void test() {
// CHECK-FIXES-NEXT: do_something("for");
// CHECK-FIXES-NEXT: }
- for (;;) {
- do_something("for-ok");
- }
for (;;)
;
// CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces
@@ -87,6 +84,10 @@ void test() {
// CHECK-FIXES-NEXT: ;
// CHECK-FIXES-NEXT: }
+ for (;;) {
+ do_something("for-ok");
+ }
+
int arr[4] = {1, 2, 3, 4};
for (int a : arr)
do_something("for-range");
@@ -378,7 +379,7 @@ int test_macros(bool b) {
#define WRAP(X) { X; }
// This is to ensure no other CHECK-FIXES matches the macro definition:
- // CHECK-FIXES: WRAP
+ // CHECK-FIXES: #define WRAP(X) { X; }
// Use-case: LLVM_DEBUG({ for(...) do_something(); });
WRAP({
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp
index 43a7ddb..d78ea34 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s readability-const-return-type %t -- -- -Wno-error=return-type
+// RUN: %check_clang_tidy -std=c++14-or-later %s readability-const-return-type %t -- -- -Wno-error=return-type
// p# = positive test
// n# = negative test
@@ -66,7 +66,7 @@ class Clazz {
const Klazz<const int>* const p5() const;
// CHECK-FIXES: const Klazz<const int>* p5() const;
- const Clazz operator++(int x) { // p12
+ const Clazz operator++(int x) {
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const Clazz' is 'const
// CHECK-FIXES: Clazz operator++(int x) {
}
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 8950c72..7844275 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
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s readability-container-size-empty %t -- \
+// RUN: %check_clang_tidy -std=c++14-or-later %s readability-container-size-empty %t -- \
// RUN: -config="{CheckOptions: {readability-container-size-empty.ExcludedComparisonTypes: '::std::array;::IgnoredDummyType'}}" \
// RUN: -- -fno-delayed-template-parsing -isystem %clang_tidy_headers
#include <string>
@@ -807,7 +807,7 @@ bool testStringLiterals(const std::string& s)
using namespace std::string_literals;
return s == ""s;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
- // CHECK-FIXES: return s.empty()
+ // CHECK-FIXES: return s.empty();
}
bool testNotEmptyStringLiterals(const std::string& s)
@@ -951,7 +951,7 @@ public:
void doit() {
if (!size()) {
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size'
- // CHECK-FIXES: if (empty())
+ // CHECK-FIXES: if (empty()) {
}
}
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
index 5a4627a..7f82b95 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c23-or-later --match-partial-fixes %s readability-implicit-bool-conversion %t
+// RUN: %check_clang_tidy -std=c23-or-later %s readability-implicit-bool-conversion %t
// RUN: %check_clang_tidy -std=c23-or-later -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
// RUN: -config='{CheckOptions: { \
// RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
@@ -341,28 +341,28 @@ int implicitConversionReturnInt()
{
return true;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
- // CHECK-FIXES: return 1
+ // CHECK-FIXES: return 1;
}
int implicitConversionReturnIntWithParens()
{
return (true);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
- // CHECK-FIXES: return 1
+ // CHECK-FIXES: return 1;
}
bool implicitConversionReturnBool()
{
return 1;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
- // CHECK-FIXES: return true
+ // CHECK-FIXES: return true;
}
bool implicitConversionReturnBoolWithParens()
{
return (1);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
- // CHECK-FIXES: return true
+ // CHECK-FIXES: return true;
}
int keepCompactReturnInC_PR71848() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
index a0e1fd3..c3faf8a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-implicit-bool-conversion %t
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t
// RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
// RUN: -config='{CheckOptions: { \
// RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
@@ -490,14 +490,14 @@ int implicitConversionReturnInt()
{
return true;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
- // CHECK-FIXES: return 1
+ // CHECK-FIXES: return 1;
}
int implicitConversionReturnIntWithParens()
{
return (true);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int'
- // CHECK-FIXES: return 1
+ // CHECK-FIXES: return 1;
}
@@ -505,14 +505,14 @@ bool implicitConversionReturnBool()
{
return 1;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
- // CHECK-FIXES: return true
+ // CHECK-FIXES: return true;
}
bool implicitConversionReturnBoolWithParens()
{
return (1);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool'
- // CHECK-FIXES: return true
+ // CHECK-FIXES: return true;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp
index 947eda0..b9f9226 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-math-missing-parentheses %t
+// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t
#define MACRO_AND &
#define MACRO_ADD +
@@ -123,7 +123,7 @@ void f(){
//CHECK-MESSAGES: :[[@LINE+3]]:77: warning: '-' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
//CHECK-MESSAGES: :[[@LINE+2]]:94: warning: '/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
//CHECK-FIXES: int q = (1 MACRO_ADD (2 MACRO_MULTIPLY 3)) MACRO_OR ((4 MACRO_AND 5) MACRO_XOR (6 MACRO_SUBTRACT (7 MACRO_DIVIDE 8)));
- int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8; // No warning
+ int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8;
//CHECK-MESSAGES: :[[@LINE+1]]:21: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
int r = FUN(0 + 1 * 2);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp
index 83f2fa9..89208fb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-simplify-boolean-expr %t
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
class A {
public:
@@ -353,4 +353,4 @@ bool S::expr_with_cleanups() {
return true;
}
// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
-// CHECK-FIXES: m_ar == (A)m_ar;
+// CHECK-FIXES: return m_ar == (A)m_ar;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp
index ee5ff7b..0b99cb8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-simplify-boolean-expr %t
+// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
bool a1 = false;
@@ -1019,7 +1019,7 @@ bool expr_with_cleanups(A &S) {
return true;
}
// CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return
-// CHECK-FIXES: S == (A)S;{{$}}
+// CHECK-FIXES: return S == (A)S;{{$}}
template <bool B>
void ignoreInstantiations() {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp
index a4fcf3a..399afa5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: {readability-uppercase-literal-suffix.NewSuffixes: 'L;uL'}}" -- -I %clang_tidy_headers
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: {readability-uppercase-literal-suffix.NewSuffixes: 'L;uL'}}" -- -I %clang_tidy_headers
#include "integral_constant.h"
@@ -53,7 +53,7 @@ void integer_suffix() {
static_assert(is_same<decltype(v11), const unsigned long>::value, "");
static_assert(v11 == 1, "");
- static constexpr auto v12 = 1UL; // OK.
+ static constexpr auto v12 = 1UL;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'UL', which is not uppercase
// CHECK-FIXES: static constexpr auto v12 = 1uL;
static_assert(is_same<decltype(v12), const unsigned long>::value, "");
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp
index d40bb86..3659081 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t -- \
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t -- \
//// RUN: -config='{CheckOptions: { \
//// RUN: cppcoreguidelines-pro-type-member-init.UseAssignment: true, \
//// RUN: }}'
@@ -19,5 +19,5 @@ public:
private:
int _num1;
int _num2;
- // CHECK-FIXES: _num2;
+ // CHECK-FIXES: int _num2;
};
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp
index 94cfa1a..78a903a 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t
namespace std {
@@ -28,7 +28,7 @@ public:
private:
int _num1;
int _num2;
- // CHECK-FIXES: _num2{};
+ // CHECK-FIXES: int _num2{};
};
void should_use_emplace(std::vector<Foo> &v) {
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e387d3a..1a4ec40 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -286,6 +286,7 @@ Deprecated Compiler Flags
Modified Compiler Flags
-----------------------
- The `-gkey-instructions` compiler flag is now enabled by default when DWARF is emitted for plain C/C++ and optimizations are enabled. (#GH149509)
+- The `-fconstexpr-steps` compiler flag now accepts value `0` to opt out of this limit. (#GH160440)
Removed Compiler Flags
-------------------------
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 5745e4b..2d10489 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -4036,7 +4036,7 @@ Controlling implementation limits
Sets the limit for the number of full-expressions evaluated in a single
constant expression evaluation. This also controls the maximum size
of array and dynamic array allocation that can be constant evaluated.
- The default is 1048576.
+ The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`.
.. option:: -ftemplate-depth=N
diff --git a/clang/docs/analyzer/developer-docs/Statistics.rst b/clang/docs/analyzer/developer-docs/Statistics.rst
index 4f2484a..355759d 100644
--- a/clang/docs/analyzer/developer-docs/Statistics.rst
+++ b/clang/docs/analyzer/developer-docs/Statistics.rst
@@ -22,7 +22,7 @@ However, note that with ``LLVM_ENABLE_STATS`` disabled, only storage of the valu
If you want to define a statistic only for entry point, EntryPointStats.h has four classes at your disposal:
-- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry point. For example: "the number of source characters in an entry-point body".
+- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry point. For example: "the number of source characters in an entry-point body". If no value is assigned during analysis of an entry point, the corresponding CSV cell will be empty.
- ``CounterEPStat`` - an additive statistic. It starts with 0 and you can add to it as many times as needed. For example: "the number of bugs discovered".
- ``UnsignedMaxEPStat`` - a maximizing statistic. It starts with 0 and when you join it with a value, it picks the maximum of the previous value and the new one. For example, "the longest execution path of a bug".
diff --git a/clang/include/clang/AST/NestedNameSpecifierBase.h b/clang/include/clang/AST/NestedNameSpecifierBase.h
index 73c60ba..8f4bbe9 100644
--- a/clang/include/clang/AST/NestedNameSpecifierBase.h
+++ b/clang/include/clang/AST/NestedNameSpecifierBase.h
@@ -361,6 +361,9 @@ public:
/// Retrieve the source range covering just the last part of
/// this nested-name-specifier, not including the prefix.
///
+ /// Note that this is the source range of this NestedNameSpecifier chunk,
+ /// and for a type this includes the prefix of that type.
+ ///
/// For example, if this instance refers to a nested-name-specifier
/// \c \::std::vector<int>::, the returned source range would cover
/// from "vector" to the last '::'.
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 38e8fba..3f14ee8 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -199,11 +199,6 @@ public:
NestedNameSpecifierLoc getPrefix() const;
/// This returns the position of the type after any elaboration, such as the
- /// 'struct' keyword, and name qualifiers. This will the 'template' keyword if
- /// present, or the name location otherwise.
- SourceLocation getNonPrefixBeginLoc() const;
-
- /// This returns the position of the type after any elaboration, such as the
/// 'struct' keyword. This may be the position of the name qualifiers,
/// 'template' keyword, or the name location otherwise.
SourceLocation getNonElaboratedBeginLoc() const;
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 3cde249..22e60aa 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1599,8 +1599,15 @@ def CUDAShared : InheritableAttr {
}
def : MutualExclusions<[CUDAConstant, CUDAShared, HIPManaged]>;
+def SYCLKernel : InheritableAttr {
+ let Spellings = [Clang<"sycl_kernel">];
+ let Subjects = SubjectList<[FunctionTmpl]>;
+ let LangOpts = [SYCLDevice];
+ let Documentation = [SYCLKernelDocs];
+}
+
def DeviceKernel : DeclOrTypeAttr {
- let Spellings = [Clang<"device_kernel">, Clang<"sycl_kernel">,
+ let Spellings = [Clang<"device_kernel">,
Clang<"nvptx_kernel">, Clang<"amdgpu_kernel">,
CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
let Documentation = [DeviceKernelDocs];
@@ -1624,15 +1631,6 @@ def DeviceKernel : DeclOrTypeAttr {
if(!A) return false;
return isNVPTXSpelling(*A);
}
- static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
- return A.getAttributeSpellingListIndex() == GNU_sycl_kernel ||
- A.getAttributeSpellingListIndex() == CXX11_clang_sycl_kernel ||
- A.getAttributeSpellingListIndex() == C23_clang_sycl_kernel;
- }
- static inline bool isSYCLSpelling(const AttributeCommonInfo* A) {
- if(!A) return false;
- return isSYCLSpelling(*A);
- }
static inline bool isOpenCLSpelling(const AttributeCommonInfo& A) {
// Tablegen trips underscores from spellings to build the spelling
// list, but here we have the same spelling with unscores and without,
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 20a52b4..e0bbda0 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -396,13 +396,10 @@ any option of a multiversioned function is undefined.
}];
}
-def DeviceKernelDocs : Documentation {
+def SYCLKernelDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "device_kernel, sycl_kernel, nvptx_kernel, amdgpu_kernel, "
- "kernel, __kernel";
+ let Heading = "sycl_kernel";
let Content = [{
-These attributes specify that the function represents a kernel for device offloading.
-The specific semantics depend on the offloading language, target, and attribute spelling.
The ``sycl_kernel`` attribute specifies that a function template will be used
to outline device code and to generate an OpenCL kernel.
Here is a code example of the SYCL program, which demonstrates the compiler's
@@ -476,6 +473,21 @@ The SYCL kernel in the previous code sample meets these expectations.
}];
}
+def DeviceKernelDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "device_kernel, nvptx_kernel, amdgpu_kernel, "
+ "kernel, __kernel";
+ let Content = [{
+These attributes specify that the function represents a kernel for device offloading.
+The specific semantics depend on the offloading language, target, and attribute spelling.
+Here is a code example using the attribute to mark a function as a kernel:
+
+.. code-block:: c++
+
+ [[clang::device_kernel]] int foo(int x) { return ++x; }
+ }];
+}
+
def SYCLExternalDocs : Documentation {
let Category = DocCatFunction;
let Heading = "sycl_external";
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index a55a523..611b68e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2047,7 +2047,7 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>,
MarshallingInfoInt<LangOpts<"ConstexprCallDepth">, "512">;
def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
- HelpText<"Set the maximum number of steps in constexpr function evaluation">,
+ HelpText<"Set the maximum number of steps in constexpr function evaluation (0 = no limit)">,
MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">;
def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-constant-interpreter">, Group<f_Group>,
HelpText<"Enable the experimental new constant interpreter">,
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 46b088c..f9d3a4ea 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -215,7 +215,6 @@ public:
bool diagnosePositionType(QualType T, const ParsedAttr &AL);
bool CanPerformScalarCast(QualType SrcTy, QualType DestTy);
- bool ContainsBitField(QualType BaseTy);
bool CanPerformElementwiseCast(Expr *Src, QualType DestType);
bool CanPerformAggregateSplatCast(Expr *Src, QualType DestType);
ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
index 389f17d..f3c6a62 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
@@ -9,6 +9,7 @@
#ifndef CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H
#define CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H
+#include "clang/AST/ASTContext.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
@@ -25,7 +26,7 @@ class EntryPointStat {
public:
llvm::StringLiteral name() const { return Name; }
- static void lockRegistry(llvm::StringRef CPPFileName);
+ static void lockRegistry(llvm::StringRef CPPFileName, ASTContext &Ctx);
static void takeSnapshot(const Decl *EntryPoint);
static void dumpStatsAsCSV(llvm::raw_ostream &OS);
@@ -85,7 +86,7 @@ class UnsignedEPStat : public EntryPointStat {
public:
explicit UnsignedEPStat(llvm::StringLiteral Name);
- unsigned value() const { return Value.value_or(0); }
+ std::optional<unsigned> value() const { return Value; }
void reset() { Value.reset(); }
void set(unsigned V) {
assert(!Value.has_value());
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index a9c71c7..57cc705 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3699,7 +3699,7 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) {
inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) {
uint64_t Limit = S.getLangOpts().ConstexprStepLimit;
- if (NumElems > Limit) {
+ if (Limit != 0 && NumElems > Limit) {
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_new_exceeds_limits)
<< NumElems << Limit;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a3037c3f..dfdfef2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -990,7 +990,7 @@ namespace {
// of arrays to avoid exhausting the system resources, as initialization
// of each element is likely to take some number of steps anyway.
uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
- if (ElemCount > Limit) {
+ if (Limit != 0 && ElemCount > Limit) {
if (Diag)
FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
<< ElemCount << Limit;
@@ -1016,6 +1016,9 @@ namespace {
}
bool nextStep(const Stmt *S) {
+ if (Ctx.getLangOpts().ConstexprStepLimit == 0)
+ return true;
+
if (!StepsLeft) {
FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
return false;
@@ -1186,7 +1189,8 @@ namespace {
/// Should we continue evaluation as much as possible after encountering a
/// construct which can't be reduced to a value?
bool keepEvaluatingAfterFailure() const override {
- if (!StepsLeft)
+ uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
+ if (Limit != 0 && !StepsLeft)
return false;
switch (EvalMode) {
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 55476e2..e952e82 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -494,39 +494,6 @@ NestedNameSpecifierLoc TypeLoc::getPrefix() const {
}
}
-SourceLocation TypeLoc::getNonPrefixBeginLoc() const {
- switch (getTypeLocClass()) {
- case TypeLoc::TemplateSpecialization: {
- auto TL = castAs<TemplateSpecializationTypeLoc>();
- SourceLocation Loc = TL.getTemplateKeywordLoc();
- if (!Loc.isValid())
- Loc = TL.getTemplateNameLoc();
- return Loc;
- }
- case TypeLoc::DeducedTemplateSpecialization: {
- auto TL = castAs<DeducedTemplateSpecializationTypeLoc>();
- SourceLocation Loc = TL.getTemplateKeywordLoc();
- if (!Loc.isValid())
- Loc = TL.getTemplateNameLoc();
- return Loc;
- }
- case TypeLoc::DependentName:
- return castAs<DependentNameTypeLoc>().getNameLoc();
- case TypeLoc::Enum:
- case TypeLoc::Record:
- case TypeLoc::InjectedClassName:
- return castAs<TagTypeLoc>().getNameLoc();
- case TypeLoc::Typedef:
- return castAs<TypedefTypeLoc>().getNameLoc();
- case TypeLoc::UnresolvedUsing:
- return castAs<UnresolvedUsingTypeLoc>().getNameLoc();
- case TypeLoc::Using:
- return castAs<UsingTypeLoc>().getNameLoc();
- default:
- return getBeginLoc();
- }
-}
-
SourceLocation TypeLoc::getNonElaboratedBeginLoc() const {
// For elaborated types (e.g. `struct a::A`) we want the portion after the
// `struct` but including the namespace qualifier, `a::`.
diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h
index fb74aa0..a67cbad 100644
--- a/clang/lib/CIR/CodeGen/Address.h
+++ b/clang/lib/CIR/CodeGen/Address.h
@@ -17,6 +17,7 @@
#include "mlir/IR/Value.h"
#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/PointerIntPair.h"
namespace clang::CIRGen {
@@ -90,6 +91,13 @@ public:
return getPointer();
}
+ /// Return the pointer contained in this class after authenticating it and
+ /// adding offset to it if necessary.
+ mlir::Value emitRawPointer() const {
+ assert(!cir::MissingFeatures::addressPointerAuthInfo());
+ return getBasePointer();
+ }
+
mlir::Type getType() const {
assert(mlir::cast<cir::PointerType>(
pointerAndKnownNonNull.getPointer().getType())
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index 06f41cd..6d3741c4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -191,6 +191,15 @@ public:
virtual void emitVTableDefinitions(CIRGenVTables &cgvt,
const CXXRecordDecl *rd) = 0;
+ using DeleteOrMemberCallExpr =
+ llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>;
+
+ virtual mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
+ const CXXDestructorDecl *dtor,
+ CXXDtorType dtorType,
+ Address thisAddr,
+ DeleteOrMemberCallExpr e) = 0;
+
/// Emit any tables needed to implement virtual inheritance. For Itanium,
/// this emits virtual table tables.
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *rd) = 0;
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 485b2c8..dd357ce 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -895,6 +895,26 @@ void CIRGenFunction::destroyCXXObject(CIRGenFunction &cgf, Address addr,
}
namespace {
+mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf,
+ const CXXDestructorDecl *dd) {
+ if (Expr *thisArg = dd->getOperatorDeleteThisArg())
+ return cgf.emitScalarExpr(thisArg);
+ return cgf.loadCXXThis();
+}
+
+/// Call the operator delete associated with the current destructor.
+struct CallDtorDelete final : EHScopeStack::Cleanup {
+ CallDtorDelete() {}
+
+ void emit(CIRGenFunction &cgf) override {
+ const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(cgf.curFuncDecl);
+ const CXXRecordDecl *classDecl = dtor->getParent();
+ cgf.emitDeleteCall(dtor->getOperatorDelete(),
+ loadThisForDtorDelete(cgf, dtor),
+ cgf.getContext().getCanonicalTagType(classDecl));
+ }
+};
+
class DestroyField final : public EHScopeStack::Cleanup {
const FieldDecl *field;
CIRGenFunction::Destroyer *destroyer;
@@ -932,7 +952,18 @@ void CIRGenFunction::enterDtorCleanups(const CXXDestructorDecl *dd,
// The deleting-destructor phase just needs to call the appropriate
// operator delete that Sema picked up.
if (dtorType == Dtor_Deleting) {
- cgm.errorNYI(dd->getSourceRange(), "deleting destructor cleanups");
+ assert(dd->getOperatorDelete() &&
+ "operator delete missing - EnterDtorCleanups");
+ if (cxxStructorImplicitParamValue) {
+ cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt");
+ } else {
+ if (dd->getOperatorDelete()->isDestroyingOperatorDelete()) {
+ cgm.errorNYI(dd->getSourceRange(),
+ "deleting destructor with destroying operator delete");
+ } else {
+ ehStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
+ }
+ }
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 97c0944..b1e9e76 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -130,13 +130,11 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
const CXXMethodDecl *calleeDecl =
devirtualizedMethod ? devirtualizedMethod : md;
const CIRGenFunctionInfo *fInfo = nullptr;
- if (isa<CXXDestructorDecl>(calleeDecl)) {
- cgm.errorNYI(ce->getSourceRange(),
- "emitCXXMemberOrOperatorMemberCallExpr: destructor call");
- return RValue::get(nullptr);
- }
-
- fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl);
+ if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl))
+ fInfo = &cgm.getTypes().arrangeCXXStructorDeclaration(
+ GlobalDecl(dtor, Dtor_Complete));
+ else
+ fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl);
cir::FuncType ty = cgm.getTypes().getFunctionType(*fInfo);
@@ -151,9 +149,34 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
// because then we know what the type is.
bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod;
- if (isa<CXXDestructorDecl>(calleeDecl)) {
- cgm.errorNYI(ce->getSourceRange(),
- "emitCXXMemberOrOperatorMemberCallExpr: destructor call");
+ if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) {
+ assert(ce->arg_begin() == ce->arg_end() &&
+ "Destructor shouldn't have explicit parameters");
+ assert(returnValue.isNull() && "Destructor shouldn't have return value");
+ if (useVirtualCall) {
+ cgm.getCXXABI().emitVirtualDestructorCall(*this, dtor, Dtor_Complete,
+ thisPtr.getAddress(),
+ cast<CXXMemberCallExpr>(ce));
+ } else {
+ GlobalDecl globalDecl(dtor, Dtor_Complete);
+ CIRGenCallee callee;
+ assert(!cir::MissingFeatures::appleKext());
+ if (!devirtualizedMethod) {
+ callee = CIRGenCallee::forDirect(
+ cgm.getAddrOfCXXStructor(globalDecl, fInfo, ty), globalDecl);
+ } else {
+ cgm.errorNYI(ce->getSourceRange(), "devirtualized destructor call");
+ return RValue::get(nullptr);
+ }
+
+ QualType thisTy =
+ isArrow ? base->getType()->getPointeeType() : base->getType();
+ // CIRGen does not pass CallOrInvoke here (different from OG LLVM codegen)
+ // because in practice it always null even in OG.
+ emitCXXDestructorCall(globalDecl, callee, thisPtr.getPointer(), thisTy,
+ /*implicitParam=*/nullptr,
+ /*implicitParamTy=*/QualType(), ce);
+ }
return RValue::get(nullptr);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 7a774e0..01a43a99 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -678,7 +678,13 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) {
// possible to delegate the destructor body to the complete
// destructor. Do so.
if (dtorType == Dtor_Deleting) {
- cgm.errorNYI(dtor->getSourceRange(), "deleting destructor");
+ RunCleanupsScope dtorEpilogue(*this);
+ enterDtorCleanups(dtor, Dtor_Deleting);
+ if (haveInsertPoint()) {
+ QualType thisTy = dtor->getFunctionObjectParameterType();
+ emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase=*/false,
+ /*delegating=*/false, loadCXXThisAddress(), thisTy);
+ }
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 9e490c6d..d30c975 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -95,7 +95,10 @@ public:
clang::GlobalDecl gd, Address thisAddr,
mlir::Type ty,
SourceLocation loc) override;
-
+ mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
+ const CXXDestructorDecl *dtor,
+ CXXDtorType dtorType, Address thisAddr,
+ DeleteOrMemberCallExpr e) override;
mlir::Value getVTableAddressPoint(BaseSubobject base,
const CXXRecordDecl *vtableClass) override;
mlir::Value getVTableAddressPointInStructorWithVTT(
@@ -465,6 +468,29 @@ void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
}
}
+mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
+ CIRGenFunction &cgf, const CXXDestructorDecl *dtor, CXXDtorType dtorType,
+ Address thisAddr, DeleteOrMemberCallExpr expr) {
+ auto *callExpr = dyn_cast<const CXXMemberCallExpr *>(expr);
+ auto *delExpr = dyn_cast<const CXXDeleteExpr *>(expr);
+ assert((callExpr != nullptr) ^ (delExpr != nullptr));
+ assert(callExpr == nullptr || callExpr->arg_begin() == callExpr->arg_end());
+ assert(dtorType == Dtor_Deleting || dtorType == Dtor_Complete);
+
+ GlobalDecl globalDecl(dtor, dtorType);
+ const CIRGenFunctionInfo *fnInfo =
+ &cgm.getTypes().arrangeCXXStructorDeclaration(globalDecl);
+ const cir::FuncType &fnTy = cgm.getTypes().getFunctionType(*fnInfo);
+ auto callee = CIRGenCallee::forVirtual(callExpr, globalDecl, thisAddr, fnTy);
+
+ QualType thisTy =
+ callExpr ? callExpr->getObjectType() : delExpr->getDestroyedType();
+
+ cgf.emitCXXDestructorCall(globalDecl, callee, thisAddr.emitRawPointer(),
+ thisTy, nullptr, QualType(), nullptr);
+ return nullptr;
+}
+
void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *rd) {
CIRGenVTables &vtables = cgm.getVTables();
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index e65896a..2ab1ea0c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -619,10 +619,8 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeGlobalDeclaration(GlobalDecl gd) {
const auto *fd = cast<FunctionDecl>(gd.getDecl());
if (isa<CXXConstructorDecl>(gd.getDecl()) ||
- isa<CXXDestructorDecl>(gd.getDecl())) {
- cgm.errorNYI(SourceLocation(),
- "arrangeGlobalDeclaration for C++ constructor or destructor");
- }
+ isa<CXXDestructorDecl>(gd.getDecl()))
+ return arrangeCXXStructorDeclaration(gd);
return arrangeFunctionDeclaration(fd);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
index 84f5977..36bab62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
@@ -120,12 +120,6 @@ mlir::Attribute CIRGenVTables::getVTableComponent(
assert(!cir::MissingFeatures::vtableRelativeLayout());
switch (component.getKind()) {
- case VTableComponent::CK_CompleteDtorPointer:
- cgm.errorNYI("getVTableComponent: CompleteDtorPointer");
- return mlir::Attribute();
- case VTableComponent::CK_DeletingDtorPointer:
- cgm.errorNYI("getVTableComponent: DeletingDtorPointer");
- return mlir::Attribute();
case VTableComponent::CK_UnusedFunctionPointer:
cgm.errorNYI("getVTableComponent: UnusedFunctionPointer");
return mlir::Attribute();
@@ -148,7 +142,9 @@ mlir::Attribute CIRGenVTables::getVTableComponent(
"expected GlobalViewAttr or ConstPtrAttr");
return rtti;
- case VTableComponent::CK_FunctionPointer: {
+ case VTableComponent::CK_FunctionPointer:
+ case VTableComponent::CK_CompleteDtorPointer:
+ case VTableComponent::CK_DeletingDtorPointer: {
GlobalDecl gd = component.getGlobalDecl();
assert(!cir::MissingFeatures::cudaSupport());
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index fa94692..1ff2be7 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1762,8 +1762,11 @@ void CGOpenMPRuntime::emitDeclareTargetFunction(const FunctionDecl *FD,
// access its value.
llvm::GlobalValue *Addr = GV;
if (CGM.getLangOpts().OpenMPIsTargetDevice) {
+ llvm::PointerType *FnPtrTy = llvm::PointerType::get(
+ CGM.getLLVMContext(),
+ CGM.getModule().getDataLayout().getProgramAddressSpace());
Addr = new llvm::GlobalVariable(
- CGM.getModule(), CGM.VoidPtrTy,
+ CGM.getModule(), FnPtrTy,
/*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, GV, Name,
nullptr, llvm::GlobalValue::NotThreadLocal,
CGM.getModule().getDataLayout().getDefaultGlobalsAddressSpace());
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 3613b6a..fddeba9 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This provides a generalized class for OpenMP runtime code generation
-// specialized by GPU targets NVPTX and AMDGCN.
+// specialized by GPU targets NVPTX, AMDGCN and SPIR-V.
//
//===----------------------------------------------------------------------===//
@@ -1242,12 +1242,13 @@ void CGOpenMPRuntimeGPU::emitParallelCall(
CGBuilderTy &Bld = CGF.Builder;
llvm::Value *NumThreadsVal = NumThreads;
llvm::Function *WFn = WrapperFunctionsMap[OutlinedFn];
- llvm::Value *ID = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
- if (WFn)
- ID = Bld.CreateBitOrPointerCast(WFn, CGM.Int8PtrTy);
- llvm::Type *FnPtrTy = llvm::PointerType::get(
+ llvm::PointerType *FnPtrTy = llvm::PointerType::get(
CGF.getLLVMContext(), CGM.getDataLayout().getProgramAddressSpace());
+ llvm::Value *ID = llvm::ConstantPointerNull::get(FnPtrTy);
+ if (WFn)
+ ID = Bld.CreateBitOrPointerCast(WFn, FnPtrTy);
+
llvm::Value *FnPtr = Bld.CreateBitOrPointerCast(OutlinedFn, FnPtrTy);
// Create a private scope that will globalize the arguments
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0e83c20..8ac09c4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20797,7 +20797,7 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(const FunctionDecl *FD,
// SYCL functions can be template, so we check if they have appropriate
// attribute prior to checking if it is a template.
- if (LangOpts.SYCLIsDevice && FD->hasAttr<DeviceKernelAttr>())
+ if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLKernelAttr>())
return FunctionEmissionStatus::Emitted;
// Templates are emitted when they're instantiated.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 328ccf6..3107876 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5204,16 +5204,7 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
- if (S.getLangOpts().SYCLIsDevice) {
- if (!IsFunctionTemplate) {
- S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
- << AL << AL.isRegularKeywordAttribute() << "function templates";
- } else {
- S.SYCL().handleKernelAttr(D, AL);
- }
- } else if (DeviceKernelAttr::isSYCLSpelling(AL)) {
- S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
- } else if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) {
+ if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) {
handleGlobalAttr(S, D, AL);
} else {
// OpenCL C++ will throw a more specific error.
@@ -7100,6 +7091,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_EnumExtensibility:
handleEnumExtensibilityAttr(S, D, AL);
break;
+ case ParsedAttr::AT_SYCLKernel:
+ S.SYCL().handleKernelAttr(D, AL);
+ break;
case ParsedAttr::AT_SYCLExternal:
handleSimpleAttribute<SYCLExternalAttr>(S, D, AL);
break;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 17cb1e4..72b2ac9 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3544,40 +3544,6 @@ bool SemaHLSL::CanPerformScalarCast(QualType SrcTy, QualType DestTy) {
llvm_unreachable("Unhandled scalar cast");
}
-// Detect if a type contains a bitfield. Will be removed when
-// bitfield support is added to HLSLElementwiseCast and HLSLAggregateSplatCast
-bool SemaHLSL::ContainsBitField(QualType BaseTy) {
- llvm::SmallVector<QualType, 16> WorkList;
- WorkList.push_back(BaseTy);
- while (!WorkList.empty()) {
- QualType T = WorkList.pop_back_val();
- T = T.getCanonicalType().getUnqualifiedType();
- // only check aggregate types
- if (const auto *AT = dyn_cast<ConstantArrayType>(T)) {
- WorkList.push_back(AT->getElementType());
- continue;
- }
- if (const auto *RT = dyn_cast<RecordType>(T)) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
- if (RD->isUnion())
- continue;
-
- const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(RD);
-
- if (CXXD && CXXD->isStandardLayout())
- RD = CXXD->getStandardLayoutBaseWithFields();
-
- for (const auto *FD : RD->fields()) {
- if (FD->isBitField())
- return true;
- WorkList.push_back(FD->getType());
- }
- continue;
- }
- }
- return false;
-}
-
// Can perform an HLSL Aggregate splat cast if the Dest is an aggregate and the
// Src is a scalar or a vector of length 1
// Or if Dest is a vector and Src is a vector of length 1
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index 2f97f62..b981c35 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -199,7 +199,7 @@ void SemaSYCL::handleKernelAttr(Decl *D, const ParsedAttr &AL) {
return;
}
- handleSimpleAttribute<DeviceKernelAttr>(*this, D, AL);
+ handleSimpleAttribute<SYCLKernelAttr>(*this, D, AL);
}
void SemaSYCL::handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3819f77..85e3d20 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -710,9 +710,9 @@ static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr(
// This doesn't take any template parameters, but we have a custom action that
// needs to happen when the kernel itself is instantiated. We need to run the
// ItaniumMangler to mark the names required to name this kernel.
-static void instantiateDependentDeviceKernelAttr(
+static void instantiateDependentSYCLKernelAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
- const DeviceKernelAttr &Attr, Decl *New) {
+ const SYCLKernelAttr &Attr, Decl *New) {
New->addAttr(Attr.clone(S.getASTContext()));
}
@@ -966,8 +966,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
continue;
}
- if (auto *A = dyn_cast<DeviceKernelAttr>(TmplAttr)) {
- instantiateDependentDeviceKernelAttr(*this, TemplateArgs, *A, New);
+ if (auto *A = dyn_cast<SYCLKernelAttr>(TmplAttr)) {
+ instantiateDependentSYCLKernelAttr(*this, TemplateArgs, *A, New);
continue;
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index bee613a..a9e7c34 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -3780,12 +3780,10 @@ static CallingConv getCCForDeclaratorChunk(
}
}
}
- if (!S.getLangOpts().isSYCL()) {
- for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
- if (AL.getKind() == ParsedAttr::AT_DeviceKernel) {
- CC = CC_DeviceKernel;
- break;
- }
+ for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
+ if (AL.getKind() == ParsedAttr::AT_DeviceKernel) {
+ CC = CC_DeviceKernel;
+ break;
}
}
return CC;
diff --git a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
index abfb176..c207a7b 100644
--- a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
+++ b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
@@ -24,15 +24,21 @@ using namespace ento;
namespace {
struct Registry {
+ std::vector<UnsignedEPStat *> ExplicitlySetStats;
+ std::vector<UnsignedMaxEPStat *> MaxStats;
std::vector<CounterEPStat *> CounterStats;
- std::vector<UnsignedMaxEPStat *> UnsignedMaxStats;
- std::vector<UnsignedEPStat *> UnsignedStats;
bool IsLocked = false;
struct Snapshot {
const Decl *EntryPoint;
- std::vector<unsigned> UnsignedStatValues;
+ // Explicitly set statistics may not have a value set, so they are separate
+ // from other unsigned statistics
+ std::vector<std::optional<unsigned>> ExplicitlySetStatValues;
+ // These are counting and maximizing statistics that initialize to 0, which
+ // is meaningful even if they are never updated, so their value is always
+ // present.
+ std::vector<unsigned> MaxOrCountStatValues;
void dumpAsCSV(llvm::raw_ostream &OS) const;
};
@@ -46,10 +52,16 @@ static llvm::ManagedStatic<Registry> StatsRegistry;
namespace {
template <typename Callback> void enumerateStatVectors(const Callback &Fn) {
+ // This order is important, it matches the order of the Snapshot fields:
+ // - ExplicitlySetStatValues
+ Fn(StatsRegistry->ExplicitlySetStats);
+ // - MaxOrCountStatValues
+ Fn(StatsRegistry->MaxStats);
Fn(StatsRegistry->CounterStats);
- Fn(StatsRegistry->UnsignedMaxStats);
- Fn(StatsRegistry->UnsignedStats);
}
+
+void clearSnapshots(void *) { StatsRegistry->Snapshots.clear(); }
+
} // namespace
static void checkStatName(const EntryPointStat *M) {
@@ -69,7 +81,8 @@ static void checkStatName(const EntryPointStat *M) {
}
}
-void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName) {
+void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName,
+ ASTContext &Ctx) {
auto CmpByNames = [](const EntryPointStat *L, const EntryPointStat *R) {
return L->name() < R->name();
};
@@ -80,6 +93,10 @@ void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName) {
StatsRegistry->IsLocked = true;
llvm::raw_string_ostream OS(StatsRegistry->EscapedCPPFileName);
llvm::printEscapedString(CPPFileName, OS);
+ // Make sure snapshots (that reference function Decl's) do not persist after
+ // the AST is destroyed. This is especially relevant in the context of unit
+ // tests that construct and destruct multiple ASTs in the same process.
+ Ctx.AddDeallocation(clearSnapshots, nullptr);
}
[[maybe_unused]] static bool isRegistered(llvm::StringLiteral Name) {
@@ -101,30 +118,36 @@ UnsignedMaxEPStat::UnsignedMaxEPStat(llvm::StringLiteral Name)
: EntryPointStat(Name) {
assert(!StatsRegistry->IsLocked);
assert(!isRegistered(Name));
- StatsRegistry->UnsignedMaxStats.push_back(this);
+ StatsRegistry->MaxStats.push_back(this);
}
UnsignedEPStat::UnsignedEPStat(llvm::StringLiteral Name)
: EntryPointStat(Name) {
assert(!StatsRegistry->IsLocked);
assert(!isRegistered(Name));
- StatsRegistry->UnsignedStats.push_back(this);
+ StatsRegistry->ExplicitlySetStats.push_back(this);
}
-static std::vector<unsigned> consumeUnsignedStats() {
- std::vector<unsigned> Result;
- Result.reserve(StatsRegistry->CounterStats.size() +
- StatsRegistry->UnsignedMaxStats.size() +
- StatsRegistry->UnsignedStats.size());
- for (auto *M : StatsRegistry->CounterStats) {
+static std::vector<std::optional<unsigned>> consumeExplicitlySetStats() {
+ std::vector<std::optional<unsigned>> Result;
+ Result.reserve(StatsRegistry->ExplicitlySetStats.size());
+ for (auto *M : StatsRegistry->ExplicitlySetStats) {
Result.push_back(M->value());
M->reset();
}
- for (auto *M : StatsRegistry->UnsignedMaxStats) {
+ return Result;
+}
+
+static std::vector<unsigned> consumeMaxAndCounterStats() {
+ std::vector<unsigned> Result;
+ Result.reserve(StatsRegistry->CounterStats.size() +
+ StatsRegistry->MaxStats.size());
+ // Order is important, it must match the order in enumerateStatVectors
+ for (auto *M : StatsRegistry->MaxStats) {
Result.push_back(M->value());
M->reset();
}
- for (auto *M : StatsRegistry->UnsignedStats) {
+ for (auto *M : StatsRegistry->CounterStats) {
Result.push_back(M->value());
M->reset();
}
@@ -150,20 +173,33 @@ static std::string getUSR(const Decl *D) {
}
void Registry::Snapshot::dumpAsCSV(llvm::raw_ostream &OS) const {
+ auto PrintAsUnsignOpt = [&OS](std::optional<unsigned> U) {
+ OS << (U.has_value() ? std::to_string(*U) : "");
+ };
+ auto CommaIfNeeded = [&OS](const auto &Vec1, const auto &Vec2) {
+ if (!Vec1.empty() && !Vec2.empty())
+ OS << ",";
+ };
+ auto PrintAsUnsigned = [&OS](unsigned U) { OS << U; };
+
OS << '"';
llvm::printEscapedString(getUSR(EntryPoint), OS);
OS << "\",\"";
OS << StatsRegistry->EscapedCPPFileName << "\",\"";
llvm::printEscapedString(
clang::AnalysisDeclContext::getFunctionName(EntryPoint), OS);
- OS << "\"";
- OS << (UnsignedStatValues.empty() ? "" : ",");
- llvm::interleave(UnsignedStatValues, OS, [&OS](unsigned U) { OS << U; }, ",");
+ OS << "\",";
+ llvm::interleave(ExplicitlySetStatValues, OS, PrintAsUnsignOpt, ",");
+ CommaIfNeeded(ExplicitlySetStatValues, MaxOrCountStatValues);
+ llvm::interleave(MaxOrCountStatValues, OS, PrintAsUnsigned, ",");
}
void EntryPointStat::takeSnapshot(const Decl *EntryPoint) {
- auto UnsignedValues = consumeUnsignedStats();
- StatsRegistry->Snapshots.push_back({EntryPoint, std::move(UnsignedValues)});
+ auto ExplicitlySetValues = consumeExplicitlySetStats();
+ auto MaxOrCounterValues = consumeMaxAndCounterStats();
+ StatsRegistry->Snapshots.push_back({EntryPoint,
+ std::move(ExplicitlySetValues),
+ std::move(MaxOrCounterValues)});
}
void EntryPointStat::dumpStatsAsCSV(llvm::StringRef FileName) {
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index cf01e2f..4efde59 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -39,6 +39,7 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include <cmath>
#include <memory>
#include <utility>
@@ -125,6 +126,7 @@ public:
std::unique_ptr<llvm::Timer> SyntaxCheckTimer;
std::unique_ptr<llvm::Timer> ExprEngineTimer;
std::unique_ptr<llvm::Timer> BugReporterTimer;
+ bool ShouldClearTimersToPreventDisplayingThem;
/// The information about analyzed functions shared throughout the
/// translation unit.
@@ -138,11 +140,12 @@ public:
Injector(std::move(injector)), CTU(CI),
MacroExpansions(CI.getLangOpts()) {
- EntryPointStat::lockRegistry(getMainFileName(CI.getInvocation()));
+ EntryPointStat::lockRegistry(getMainFileName(CI.getInvocation()),
+ CI.getASTContext());
DigestAnalyzerOptions();
if (Opts.AnalyzerDisplayProgress || Opts.PrintStats ||
- Opts.ShouldSerializeStats) {
+ Opts.ShouldSerializeStats || !Opts.DumpEntryPointStatsToCSV.empty()) {
AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
"analyzer", "Analyzer timers");
SyntaxCheckTimer = std::make_unique<llvm::Timer>(
@@ -154,6 +157,12 @@ public:
*AnalyzerTimers);
}
+ // Avoid displaying the timers created above in case we only want to record
+ // per-entry-point stats.
+ ShouldClearTimersToPreventDisplayingThem = !Opts.AnalyzerDisplayProgress &&
+ !Opts.PrintStats &&
+ !Opts.ShouldSerializeStats;
+
if (Opts.PrintStats || Opts.ShouldSerializeStats) {
llvm::EnableStatistics(/* DoPrintOnExit= */ false);
}
@@ -276,6 +285,9 @@ public:
checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
if (SyntaxCheckTimer)
SyntaxCheckTimer->stopTimer();
+ if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) {
+ AnalyzerTimers->clear();
+ }
}
return true;
}
@@ -569,6 +581,9 @@ void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
if (SyntaxCheckTimer)
SyntaxCheckTimer->stopTimer();
+ if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) {
+ AnalyzerTimers->clear();
+ }
// Run the AST-only checks using the order in which functions are defined.
// If inlining is not turned on, use the simplest function order for path
@@ -745,6 +760,9 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
llvm::TimeRecord CheckerEndTime = SyntaxCheckTimer->getTotalTime();
CheckerEndTime -= CheckerStartTime;
DisplayTime(CheckerEndTime);
+ if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) {
+ AnalyzerTimers->clear();
+ }
}
}
@@ -788,7 +806,12 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
ExprEngineTimer->stopTimer();
llvm::TimeRecord ExprEngineEndTime = ExprEngineTimer->getTotalTime();
ExprEngineEndTime -= ExprEngineStartTime;
+ PathRunningTime.set(static_cast<unsigned>(
+ std::lround(ExprEngineEndTime.getWallTime() * 1000)));
DisplayTime(ExprEngineEndTime);
+ if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) {
+ AnalyzerTimers->clear();
+ }
}
if (!Mgr->options.DumpExplodedGraphTo.empty())
@@ -799,6 +822,9 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
Eng.ViewGraph(Mgr->options.TrimGraph);
flushReports(BugReporterTimer.get(), Eng.getBugReporter());
+ if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) {
+ AnalyzerTimers->clear();
+ }
}
//===----------------------------------------------------------------------===//
diff --git a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
index 9cbe045..2a0caad 100644
--- a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
+++ b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
@@ -8,6 +8,13 @@
// CHECK-NEXT: "c:@F@fib#i#": {
// CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp",
// CHECK-NEXT: "DebugName": "fib(unsigned int)",
+// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
+// CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}",
// CHECK-NEXT: "NumBlocks": "{{[0-9]+}}",
// CHECK-NEXT: "NumBlocksUnreachable": "{{[0-9]+}}",
// CHECK-NEXT: "NumCTUSteps": "{{[0-9]+}}",
@@ -33,18 +40,18 @@
// CHECK-NEXT: "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}",
// CHECK-NEXT: "NumTimesZ3TimedOut": "{{[0-9]+}}",
// CHECK-NEXT: "NumZ3QueriesDone": "{{[0-9]+}}",
-// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}",
+// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}"
+// CHECK-NEXT: },
+// CHECK-NEXT: "c:@F@main#I#**C#": {
+// CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp",
+// CHECK-NEXT: "DebugName": "main(int, char **)",
+// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}",
// CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}",
// CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}",
// CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}",
// CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}",
// CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
// CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}"
-// CHECK-NEXT: },
-// CHECK-NEXT: "c:@F@main#I#**C#": {
-// CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp",
-// CHECK-NEXT: "DebugName": "main(int, char **)",
// CHECK-NEXT: "NumBlocks": "{{[0-9]+}}",
// CHECK-NEXT: "NumBlocksUnreachable": "{{[0-9]+}}",
// CHECK-NEXT: "NumCTUSteps": "{{[0-9]+}}",
@@ -70,14 +77,7 @@
// CHECK-NEXT: "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}",
// CHECK-NEXT: "NumTimesZ3TimedOut": "{{[0-9]+}}",
// CHECK-NEXT: "NumZ3QueriesDone": "{{[0-9]+}}",
-// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
-// CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}"
+// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NOT: non_entry_point
diff --git a/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp
new file mode 100644
index 0000000..08a6b21
--- /dev/null
+++ b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+// TODO(cir): Try to emit base destructor as an alias at O1 or higher.
+
+// FIXME: LLVM IR dialect does not yet support function ptr globals, which precludes
+// a lot of the proper semantics for properly representing alias functions in LLVM
+// (see the note on LLVM_O1 below).
+
+struct Member {
+ ~Member();
+};
+
+struct A {
+ virtual ~A();
+};
+
+struct B : A {
+ Member m;
+ virtual ~B();
+};
+
+B::~B() { }
+
+// Aliases are inserted before the function definitions in LLVM IR
+// FIXME: These should have unnamed_addr set.
+// LLVM: @_ZN1BD1Ev = alias void (ptr), ptr @_ZN1BD2Ev
+// LLVM: @_ZN1CD1Ev = alias void (ptr), ptr @_ZN1CD2Ev
+
+// OGCG: @_ZN1BD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1BD2Ev
+// OGCG: @_ZN1CD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1CD2Ev
+
+
+// Base (D2) dtor for B: calls A's base dtor.
+
+// CIR: cir.func{{.*}} @_ZN1BD2Ev
+// CIR: cir.call @_ZN6MemberD1Ev
+// CIR: cir.call @_ZN1AD2Ev
+
+// LLVM: define{{.*}} void @_ZN1BD2Ev
+// LLVM: call void @_ZN6MemberD1Ev
+// LLVM: call void @_ZN1AD2Ev
+
+// OGCG: define{{.*}} @_ZN1BD2Ev
+// OGCG: call void @_ZN6MemberD1Ev
+// OGCG: call void @_ZN1AD2Ev
+
+// Complete (D1) dtor for B: just an alias because there are no virtual bases.
+
+// CIR: cir.func{{.*}} @_ZN1BD1Ev(!cir.ptr<!rec_B>) alias(@_ZN1BD2Ev)
+// This is defined above for LLVM and OGCG.
+
+// Deleting (D0) dtor for B: defers to the complete dtor but also calls operator delete.
+
+// CIR: cir.func{{.*}} @_ZN1BD0Ev
+// CIR: cir.call @_ZN1BD1Ev(%[[THIS:.*]]) nothrow : (!cir.ptr<!rec_B>) -> ()
+// CIR: %[[THIS_VOID:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_B> -> !cir.ptr<!void>
+// CIR: %[[SIZE:.*]] = cir.const #cir.int<16>
+// CIR: cir.call @_ZdlPvm(%[[THIS_VOID]], %[[SIZE]])
+
+// LLVM: define{{.*}} void @_ZN1BD0Ev
+// LLVM: call void @_ZN1BD1Ev(ptr %[[THIS:.*]])
+// LLVM: call void @_ZdlPvm(ptr %[[THIS]], i64 16)
+
+// OGCG: define{{.*}} @_ZN1BD0Ev
+// OGCG: call void @_ZN1BD1Ev(ptr{{.*}} %[[THIS:.*]])
+// OGCG: call void @_ZdlPvm(ptr{{.*}} %[[THIS]], i64{{.*}} 16)
+
+struct C : B {
+ ~C();
+};
+
+C::~C() { }
+
+// Base (D2) dtor for C: calls B's base dtor.
+
+// CIR: cir.func{{.*}} @_ZN1CD2Ev
+// CIR: %[[B:.*]] = cir.base_class_addr %[[THIS:.*]] : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_B>
+// CIR: cir.call @_ZN1BD2Ev(%[[B]])
+
+// LLVM: define{{.*}} void @_ZN1CD2Ev
+// LLVM: call void @_ZN1BD2Ev
+
+// OGCG: define{{.*}} @_ZN1CD2Ev
+// OGCG: call void @_ZN1BD2Ev
+
+// Complete (D1) dtor for C: just an alias because there are no virtual bases.
+
+// CIR: cir.func{{.*}} @_ZN1CD1Ev(!cir.ptr<!rec_C>) alias(@_ZN1CD2Ev)
+// This is defined above for LLVM and OGCG.
+
+
+// Deleting (D0) dtor for C: defers to the complete dtor but also calls operator delete.
+
+// CIR: cir.func{{.*}} @_ZN1CD0Ev
+// CIR: cir.call @_ZN1CD1Ev(%[[THIS:.*]]) nothrow : (!cir.ptr<!rec_C>) -> ()
+// CIR: %[[THIS_VOID:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_C> -> !cir.ptr<!void>
+// CIR: %[[SIZE:.*]] = cir.const #cir.int<16>
+// CIR: cir.call @_ZdlPvm(%[[THIS_VOID]], %[[SIZE]])
+
+// LLVM: define{{.*}} void @_ZN1CD0Ev
+// LLVM: call void @_ZN1CD1Ev(ptr %[[THIS:.*]])
+// LLVM: call void @_ZdlPvm(ptr %[[THIS]], i64 16)
+
+// OGCG: define{{.*}} @_ZN1CD0Ev
+// OGCG: call void @_ZN1CD1Ev(ptr{{.*}} %[[THIS:.*]])
+// OGCG: call void @_ZdlPvm(ptr{{.*}} %[[THIS]], i64{{.*}} 16)
+
+namespace PR12798 {
+ // A qualified call to a base class destructor should not undergo virtual
+ // dispatch. Template instantiation used to lose the qualifier.
+ struct A { virtual ~A(); };
+ template<typename T> void f(T *p) { p->A::~A(); }
+
+ // CIR: cir.func{{.*}} @_ZN7PR127981fINS_1AEEEvPT_
+ // CIR: cir.call @_ZN7PR127981AD1Ev
+
+ // LLVM: define{{.*}} @_ZN7PR127981fINS_1AEEEvPT_
+ // LLVM: call void @_ZN7PR127981AD1Ev
+
+ // OGCG: define{{.*}} @_ZN7PR127981fINS_1AEEEvPT_
+ // OGCG: call void @_ZN7PR127981AD1Ev
+
+ template void f(A*);
+}
diff --git a/clang/test/OpenMP/target_indirect_codegen.cpp b/clang/test/OpenMP/target_indirect_codegen.cpp
index 20a36c2..ec249dd 100644
--- a/clang/test/OpenMP/target_indirect_codegen.cpp
+++ b/clang/test/OpenMP/target_indirect_codegen.cpp
@@ -4,6 +4,12 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple amdgcn-amd-amdhsa %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - | FileCheck %s --check-prefix=DEVICE
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm %s -o - | FileCheck %s --check-prefix=HOST
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -o - | FileCheck %s --check-prefix=DEVICE
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -emit-pch -o %t
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -include-pch %t -o - | FileCheck %s --check-prefix=DEVICE
+
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -19,10 +25,10 @@
// HOST: @[[BAR_ENTRY_NAME:.+]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]]\00"
// HOST: @.offloading.entry.[[BAR_NAME]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 8, ptr @_ZL3barv, ptr @[[BAR_ENTRY_NAME]], i64 8, i64 0, ptr null }
//.
-// DEVICE: @[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3foov
-// DEVICE: @[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3bazv
+// DEVICE: @[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_Z3foov
+// DEVICE: @[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_Z3bazv
// DEVICE: @var = protected addrspace(1) global i8 0, align 1
-// DEVICE: @[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]] = protected addrspace(1) constant ptr @_ZL3barv
+// DEVICE: @[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_ZL3barv
//.
void foo() { }
#pragma omp declare target to(foo) indirect
diff --git a/clang/test/OpenMP/amdgcn_parallel_num_threads_strict_messages.cpp b/clang/test/OpenMP/target_parallel_num_threads_strict_messages.cpp
index 513754b..8ceff02 100644
--- a/clang/test/OpenMP/amdgcn_parallel_num_threads_strict_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_num_threads_strict_messages.cpp
@@ -5,6 +5,13 @@
// RUN: %clang_cc1 -DF3 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm-bc %s -o %t-ppc-host-ppc.bc
// RUN: %clang_cc1 -DF3 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host-ppc.bc -o /dev/null
+// RUN: %clang_cc1 -DF1 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc
+// RUN: %clang_cc1 -DF1 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null
+// RUN: %clang_cc1 -DF2 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc
+// RUN: %clang_cc1 -DF2 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null
+// RUN: %clang_cc1 -DF3 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc
+// RUN: %clang_cc1 -DF3 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null
+
#ifndef TARGET
// expected-no-diagnostics
#endif
diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt
index 9e10c4a..caf686e 100644
--- a/clang/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_unittest(StaticAnalysisTests
SValSimplifyerTest.cpp
SValTest.cpp
TestReturnValueUnderConstruction.cpp
+ UnsignedStatDemo.cpp
Z3CrosscheckOracleTest.cpp
CLANG_LIBS
clangBasic
diff --git a/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp b/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp
new file mode 100644
index 0000000..2d1323b
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp
@@ -0,0 +1,150 @@
+//=== UnsignedStatDemo.cpp --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker demonstrates the use of UnsignedEPStat for per-entry-point
+// statistics. It conditionally sets a statistic based on the entry point name.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+#include <optional>
+
+using namespace clang;
+using namespace ento;
+
+static UnsignedEPStat DemoStat("DemoStat");
+
+namespace {
+class UnsignedStatTesterChecker : public Checker<check::BeginFunction> {
+public:
+ void checkBeginFunction(CheckerContext &C) const {
+ StringRef Name;
+ if (const Decl *D = C.getLocationContext()->getDecl())
+ if (const FunctionDecl *F = D->getAsFunction())
+ Name = F->getName();
+
+ // Conditionally set the statistic based on the function name (leaving it
+ // undefined for all other functions)
+ if (Name == "func_one")
+ DemoStat.set(1);
+ else if (Name == "func_two")
+ DemoStat.set(2);
+ else
+ ; // For any other function (e.g., "func_none") don't set the statistic
+ }
+};
+
+void addUnsignedStatTesterChecker(AnalysisASTConsumer &AnalysisConsumer,
+ AnalyzerOptions &AnOpts) {
+ AnOpts.CheckersAndPackages = {{"test.DemoStatChecker", true}};
+ AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+ Registry.addChecker<UnsignedStatTesterChecker>(
+ "test.DemoStatChecker", "DescriptionOfDemoStatChecker");
+ });
+}
+
+// Find the index of a column in the CSV header.
+// Returns std::nullopt if the column is not found.
+static std::optional<unsigned>
+findColumnIndex(llvm::ArrayRef<llvm::StringRef> Header,
+ llvm::StringRef ColumnName) {
+ auto Iter = llvm::find(Header, ColumnName);
+ if (Iter != Header.end())
+ return std::distance(Header.begin(), Iter);
+ return std::nullopt;
+}
+
+// Parse CSV content and extract a mapping from one column to another.
+// KeyColumn is used as the map key (e.g., "DebugName").
+// ValueColumn is used as the map value (e.g., "DemoStat").
+// Returns a map from key column values to value column values.
+static llvm::StringMap<std::string>
+parseCSVColumnMapping(llvm::StringRef CSVContent, llvm::StringRef KeyColumn,
+ llvm::StringRef ValueColumn) {
+ llvm::StringMap<std::string> Result;
+
+ // Parse CSV: first line is header, subsequent lines are data
+ llvm::SmallVector<llvm::StringRef, 8> Lines;
+ CSVContent.split(Lines, '\n', -1, false);
+ if (Lines.size() < 2) // Need at least header + one data row
+ return Result;
+
+ // Parse header to find column indices
+ llvm::SmallVector<llvm::StringRef, 32> Header;
+ Lines[0].split(Header, ',');
+ std::optional<unsigned> KeyIdx = findColumnIndex(Header, KeyColumn);
+ std::optional<unsigned> ValueIdx = findColumnIndex(Header, ValueColumn);
+
+ if (!KeyIdx || !ValueIdx)
+ return Result;
+
+ // Parse data rows and extract mappings
+ for (auto Line : llvm::drop_begin(Lines)) {
+ llvm::SmallVector<llvm::StringRef, 32> Row;
+ Line.split(Row, ',');
+ if (Row.size() <= std::max(*KeyIdx, *ValueIdx))
+ continue;
+
+ llvm::StringRef KeyVal = Row[*KeyIdx].trim().trim('"');
+ llvm::StringRef ValueVal = Row[*ValueIdx].trim().trim('"');
+
+ if (!KeyVal.empty())
+ Result[KeyVal] = ValueVal.str();
+ }
+
+ return Result;
+}
+
+TEST(UnsignedStat, ExplicitlySetUnsignedStatistic) {
+ llvm::SmallString<128> TempMetricsCsvPath;
+ std::error_code EC =
+ llvm::sys::fs::createTemporaryFile("ep_stats", "csv", TempMetricsCsvPath);
+ ASSERT_FALSE(EC);
+ std::vector<std::string> Args = {
+ "-Xclang", "-analyzer-config", "-Xclang",
+ std::string("dump-entry-point-stats-to-csv=") +
+ TempMetricsCsvPath.str().str()};
+ // Clean up on exit
+ auto Cleanup = llvm::make_scope_exit(
+ [&]() { llvm::sys::fs::remove(TempMetricsCsvPath); });
+ EXPECT_TRUE(runCheckerOnCodeWithArgs<addUnsignedStatTesterChecker>(
+ R"cpp(
+ void func_one() {}
+ void func_two() {}
+ void func_none() {}
+ )cpp",
+ Args));
+
+ auto BufferOrError = llvm::MemoryBuffer::getFile(TempMetricsCsvPath);
+ ASSERT_TRUE(BufferOrError);
+ llvm::StringRef CSVContent = BufferOrError.get()->getBuffer();
+
+ // Parse the CSV and extract function statistics
+ llvm::StringMap<std::string> FunctionStats =
+ parseCSVColumnMapping(CSVContent, "DebugName", "DemoStat");
+
+ // Verify the expected values
+ ASSERT_TRUE(FunctionStats.count("func_one()"));
+ EXPECT_EQ(FunctionStats["func_one()"], "1");
+
+ ASSERT_TRUE(FunctionStats.count("func_two()"));
+ EXPECT_EQ(FunctionStats["func_two()"], "2");
+
+ ASSERT_TRUE(FunctionStats.count("func_none()"));
+ EXPECT_EQ(FunctionStats["func_none()"], ""); // Not set, should be empty
+}
+} // namespace
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 0040f79..b0a29db 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -105,9 +105,11 @@ extern "C" {
mach_msg_type_number_t *infoCnt);
}
+# if !SANITIZER_GO
// Weak symbol no-op when TSan is not linked
SANITIZER_WEAK_ATTRIBUTE extern void __tsan_set_in_internal_write_call(
bool value) {}
+# endif
namespace __sanitizer {
@@ -179,11 +181,15 @@ uptr internal_read(fd_t fd, void *buf, uptr count) {
}
uptr internal_write(fd_t fd, const void *buf, uptr count) {
+# if SANITIZER_GO
+ return write(fd, buf, count);
+# else
// We need to disable interceptors when writing in TSan
__tsan_set_in_internal_write_call(true);
uptr res = write(fd, buf, count);
__tsan_set_in_internal_write_call(false);
return res;
+# endif
}
uptr internal_stat(const char *path, void *buf) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp
index 50632d2..efaaef8 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp
@@ -20,7 +20,7 @@
#include "tsan_rtl.h"
#include "ubsan/ubsan_flags.h"
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
namespace __sanitizer {
template <>
@@ -55,7 +55,7 @@ inline bool FlagHandler<LockDuringWriteSetting>::Format(char *buffer,
}
} // namespace __sanitizer
-#endif
+#endif // SANITIZER_APPLE && !SANITIZER_GO
namespace __tsan {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.h b/compiler-rt/lib/tsan/rtl/tsan_flags.h
index 477d08d..e63d7c4 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_flags.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h
@@ -16,7 +16,7 @@
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
enum LockDuringWriteSetting {
kLockDuringAllWrites,
kNoLockDuringWritesCurrentProcess,
diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.inc b/compiler-rt/lib/tsan/rtl/tsan_flags.inc
index 64cc091..77ab910 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_flags.inc
+++ b/compiler-rt/lib/tsan/rtl/tsan_flags.inc
@@ -81,7 +81,7 @@ TSAN_FLAG(bool, print_full_thread_history, false,
"If set, prints thread creation stacks for the threads involved in "
"the report and their ancestors up to the main thread.")
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
TSAN_FLAG(LockDuringWriteSetting, lock_during_write, kLockDuringAllWrites,
"Determines whether to obtain a lock while writing logs or error "
"reports. "
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h
index d4b65ab..f8cc8ff 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h
@@ -1,7 +1,7 @@
#ifndef TSAN_INTERCEPTORS_H
#define TSAN_INTERCEPTORS_H
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
# include "sanitizer_common/sanitizer_mac.h"
#endif
#include "sanitizer_common/sanitizer_stacktrace.h"
@@ -47,7 +47,7 @@ inline bool in_symbolizer() {
inline bool MustIgnoreInterceptor(ThreadState *thr) {
return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
|| (flags()->lock_during_write != kLockDuringAllWrites &&
thr->in_internal_write_call)
#endif
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 0c35804..714220a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -31,7 +31,7 @@
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#include "sanitizer_common/sanitizer_vector.h"
#include "tsan_fd.h"
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
# include "tsan_flags.h"
#endif
#include "tsan_interceptors.h"
@@ -1668,7 +1668,7 @@ TSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) {
TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {
SCOPED_INTERCEPTOR_RAW(pthread_once, o, f);
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
if (flags()->lock_during_write != kLockDuringAllWrites &&
cur_thread_init()->in_internal_write_call) {
// This is needed to make it through process launch without hanging
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index b8041d7..feee566 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -40,7 +40,7 @@ SANITIZER_WEAK_DEFAULT_IMPL
void __tsan_test_only_on_fork() {}
#endif
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
// Override weak symbol from sanitizer_common
extern void __tsan_set_in_internal_write_call(bool value) {
__tsan::cur_thread_init()->in_internal_write_call = value;
@@ -901,7 +901,7 @@ void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) {
ThreadIgnoreSyncBegin(thr, pc);
}
-# if SANITIZER_APPLE
+# if SANITIZER_APPLE && !SANITIZER_GO
// This flag can have inheritance disabled - we are the child so act
// accordingly
if (flags()->lock_during_write == kNoLockDuringWritesCurrentProcess)
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index 77390f0..6356546 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -236,7 +236,7 @@ struct alignas(SANITIZER_CACHE_LINE_SIZE) ThreadState {
const ReportDesc *current_report;
-#if SANITIZER_APPLE
+#if SANITIZER_APPLE && !SANITIZER_GO
bool in_internal_write_call;
#endif
diff --git a/cross-project-tests/intrinsic-header-tests/wasm_simd128.c b/cross-project-tests/intrinsic-header-tests/wasm_simd128.c
index b601d90..0f9ef39 100644
--- a/cross-project-tests/intrinsic-header-tests/wasm_simd128.c
+++ b/cross-project-tests/intrinsic-header-tests/wasm_simd128.c
@@ -1511,13 +1511,13 @@ v128_t test_f16x8_convert_u16x8(v128_t a) {
}
// CHECK-LABEL: test_f16x8_relaxed_madd:
-// CHECK: f16x8.relaxed_madd{{$}}
+// CHECK: f16x8.madd{{$}}
v128_t test_f16x8_relaxed_madd(v128_t a, v128_t b, v128_t c) {
return wasm_f16x8_relaxed_madd(a, b, c);
}
// CHECK-LABEL: test_f16x8_relaxed_nmadd:
-// CHECK: f16x8.relaxed_nmadd{{$}}
+// CHECK: f16x8.nmadd{{$}}
v128_t test_f16x8_relaxed_nmadd(v128_t a, v128_t b, v128_t c) {
return wasm_f16x8_relaxed_nmadd(a, b, c);
}
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 2adfd6f2..c3cd119b 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -459,6 +459,7 @@ struct IntrinsicLibrary {
mlir::Value genTime(mlir::Type, llvm::ArrayRef<mlir::Value>);
void genTMABulkCommitGroup(llvm::ArrayRef<fir::ExtendedValue>);
void genTMABulkG2S(llvm::ArrayRef<fir::ExtendedValue>);
+ void genTMABulkS2G(llvm::ArrayRef<fir::ExtendedValue>);
void genTMABulkWaitGroup(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genTransfer(mlir::Type,
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 98dc78f..604b137 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -524,12 +524,18 @@ getNamelistGroup(Fortran::lower::AbstractConverter &converter,
descAddr =
builder.createConvert(loc, builder.getRefType(symType), varAddr);
} else {
+ fir::BaseBoxType boxType;
const auto expr = Fortran::evaluate::AsGenericExpr(s);
fir::ExtendedValue exv = converter.genExprAddr(*expr, stmtCtx);
mlir::Type type = fir::getBase(exv).getType();
+ bool isClassType = mlir::isa<fir::ClassType>(type);
if (mlir::Type baseTy = fir::dyn_cast_ptrOrBoxEleTy(type))
type = baseTy;
- fir::BoxType boxType = fir::BoxType::get(fir::PointerType::get(type));
+
+ if (isClassType)
+ boxType = fir::ClassType::get(fir::PointerType::get(type));
+ else
+ boxType = fir::BoxType::get(fir::PointerType::get(type));
descAddr = builder.createTemporary(loc, boxType);
fir::MutableBoxValue box = fir::MutableBoxValue(descAddr, {}, {});
fir::factory::associateMutableBox(builder, loc, box, exv,
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 5fe2a76..e07baaf 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1027,6 +1027,10 @@ static constexpr IntrinsicHandler handlers[]{
{"dst", asAddr},
{"nbytes", asValue}}},
/*isElemental=*/false},
+ {"tma_bulk_s2g",
+ &I::genTMABulkS2G,
+ {{{"src", asAddr}, {"dst", asAddr}, {"nbytes", asValue}}},
+ /*isElemental=*/false},
{"tma_bulk_wait_group",
&I::genTMABulkWaitGroup,
{{}},
@@ -9227,6 +9231,17 @@ void IntrinsicLibrary::genTMABulkG2S(llvm::ArrayRef<fir::ExtendedValue> args) {
builder, loc, dst, src, barrier, fir::getBase(args[3]), {}, {});
}
+// TMA_BULK_S2G (CUDA)
+void IntrinsicLibrary::genTMABulkS2G(llvm::ArrayRef<fir::ExtendedValue> args) {
+ assert(args.size() == 3);
+ mlir::Value src = convertPtrToNVVMSpace(builder, loc, fir::getBase(args[0]),
+ mlir::NVVM::NVVMMemorySpace::Shared);
+ mlir::Value dst = convertPtrToNVVMSpace(builder, loc, fir::getBase(args[1]),
+ mlir::NVVM::NVVMMemorySpace::Global);
+ mlir::NVVM::CpAsyncBulkSharedCTAToGlobalOp::create(
+ builder, loc, dst, src, fir::getBase(args[2]), {}, {});
+}
+
// TMA_BULK_WAIT_GROUP (CUDA)
void IntrinsicLibrary::genTMABulkWaitGroup(
llvm::ArrayRef<fir::ExtendedValue> args) {
diff --git a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
index 609a1fc..e5c5ba9 100644
--- a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
@@ -558,6 +558,7 @@ static mlir::Value emboxSrc(mlir::PatternRewriter &rewriter,
if (srcTy.isInteger(1)) {
// i1 is not a supported type in the descriptor and it is actually coming
// from a LOGICAL constant. Use the destination type to avoid mismatch.
+ assert(dstEleTy && "expect dst element type to be set");
srcTy = dstEleTy;
src = createConvertOp(rewriter, loc, srcTy, src);
addr = builder.createTemporary(loc, srcTy);
@@ -652,7 +653,8 @@ struct CUFDataTransferOpConversion
// Initialization of an array from a scalar value should be implemented
// via a kernel launch. Use the flang runtime via the Assign function
// until we have more infrastructure.
- mlir::Value src = emboxSrc(rewriter, op, symtab);
+ mlir::Type dstEleTy = fir::unwrapInnerType(fir::unwrapRefType(dstTy));
+ mlir::Value src = emboxSrc(rewriter, op, symtab, dstEleTy);
mlir::Value dst = emboxDst(rewriter, op, symtab);
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferCstDesc)>(
diff --git a/flang/module/cudadevice.f90 b/flang/module/cudadevice.f90
index a8b9aa8..22df9cd 100644
--- a/flang/module/cudadevice.f90
+++ b/flang/module/cudadevice.f90
@@ -2034,6 +2034,15 @@ implicit none
end subroutine
end interface
+ interface
+ attributes(device) subroutine tma_bulk_s2g(src, dst, nbytes)
+ !dir$ ignore_tkr src, dst
+ integer(4), shared :: src(*)
+ integer(4), device :: dst(*)
+ integer(4), value :: nbytes
+ end subroutine
+ end interface
+
contains
attributes(device) subroutine syncthreads()
diff --git a/flang/test/Fir/CUDA/cuda-data-transfer.fir b/flang/test/Fir/CUDA/cuda-data-transfer.fir
index 669300c..5d3215d 100644
--- a/flang/test/Fir/CUDA/cuda-data-transfer.fir
+++ b/flang/test/Fir/CUDA/cuda-data-transfer.fir
@@ -651,5 +651,45 @@ func.func @_QPsub28() {
// CHECK: %[[BOX_NONE:.*]] = fir.convert %[[DESC]] : (!fir.ref<!fir.box<!fir.logical<8>>>) -> !fir.ref<!fir.box<none>>
// CHECK: fir.call @_FortranACUFDataTransferCstDesc(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> ()
+func.func @_QPtesti4(%arg0: !fir.ref<i32> {fir.bindc_name = "n1"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n2"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n3"}, %arg3: !fir.ref<i32> {fir.bindc_name = "n4"}) {
+ %true = arith.constant true
+ %c0 = arith.constant 0 : index
+ %c2_i32 = arith.constant 2 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtesti4En1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtesti4En2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtesti4En3"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %4:2 = hlfir.declare %arg3 dummy_scope %0 {uniq_name = "_QFtesti4En4"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %5 = fir.load %1#0 : !fir.ref<i32>
+ %6 = arith.divsi %5, %c2_i32 : i32
+ %7 = fir.convert %6 : (i32) -> index
+ %8 = arith.cmpi sgt, %7, %c0 : index
+ %9 = arith.select %8, %7, %c0 : index
+ %10 = fir.load %2#0 : !fir.ref<i32>
+ %11 = arith.divsi %10, %c2_i32 : i32
+ %12 = fir.convert %11 : (i32) -> index
+ %13 = arith.cmpi sgt, %12, %c0 : index
+ %14 = arith.select %13, %12, %c0 : index
+ %15 = fir.load %3#0 : !fir.ref<i32>
+ %16 = arith.divsi %15, %c2_i32 : i32
+ %17 = fir.convert %16 : (i32) -> index
+ %18 = arith.cmpi sgt, %17, %c0 : index
+ %19 = arith.select %18, %17, %c0 : index
+ %20 = fir.load %4#0 : !fir.ref<i32>
+ %21 = arith.divsi %20, %c2_i32 : i32
+ %22 = fir.convert %21 : (i32) -> index
+ %23 = arith.cmpi sgt, %22, %c0 : index
+ %24 = arith.select %23, %22, %c0 : index
+ %25 = cuf.alloc !fir.array<?x?x?x?x!fir.logical<4>>, %9, %14, %19, %24 : index, index, index, index {bindc_name = "lma", data_attr = #cuf.cuda<managed>, uniq_name = "_QFtesti4Elma"} -> !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>
+ %26 = fir.shape %9, %14, %19, %24 : (index, index, index, index) -> !fir.shape<4>
+ %27:2 = hlfir.declare %25(%26) {data_attr = #cuf.cuda<managed>, uniq_name = "_QFtesti4Elma"} : (!fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>, !fir.shape<4>) -> (!fir.box<!fir.array<?x?x?x?x!fir.logical<4>>>, !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>)
+ cuf.data_transfer %true to %27#1, %26 : !fir.shape<4> {transfer_kind = #cuf.cuda_transfer<host_device>} : i1, !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>
+ cuf.free %27#1 : !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>> {data_attr = #cuf.cuda<managed>}
+ return
+}
+
+// CHECK-LABEL: func.func @_QPtesti4
+// CHECK: fir.call @_FortranACUFDataTransferCstDesc
+
} // end of module
diff --git a/flang/test/Lower/CUDA/cuda-device-proc.cuf b/flang/test/Lower/CUDA/cuda-device-proc.cuf
index 83ee011..29c348c 100644
--- a/flang/test/Lower/CUDA/cuda-device-proc.cuf
+++ b/flang/test/Lower/CUDA/cuda-device-proc.cuf
@@ -438,7 +438,7 @@ end subroutine
! CHECK: nvvm.cp.async.bulk.commit.group
! CHECK: nvvm.cp.async.bulk.wait_group 0
-attributes(global) subroutine test_bulk_g2s(c, a, b, n)
+attributes(global) subroutine test_bulk_g2s(a)
real(8), device :: a(*)
real(8), shared :: tmpa(1024)
integer(8), shared :: barrier1
@@ -448,3 +448,13 @@ end subroutine
! CHECK-LABEL: func.func @_QPtest_bulk_g2s
! CHECK: nvvm.cp.async.bulk.shared.cluster.global %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : <7>, <1>
+
+attributes(global) subroutine test_bulk_s2g(a)
+ real(8), device :: a(*)
+ real(8), shared :: tmpa(1024)
+ integer(4) :: tx_count
+ call tma_bulk_s2g(tmpa, a(j), tx_count)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_bulk_s2g
+! CHECL: nvvm.cp.async.bulk.global.shared.cta %{{.*}}, %{{.*}}, %{{.*}} : <1>, <3>
diff --git a/flang/test/Lower/namelist.f90 b/flang/test/Lower/namelist.f90
index 770af46..a258da1 100644
--- a/flang/test/Lower/namelist.f90
+++ b/flang/test/Lower/namelist.f90
@@ -123,6 +123,45 @@ subroutine global_pointer
write(10, nml=mygroup)
end
+module m
+ type base
+ real :: r1
+ end type
+ interface write(formatted)
+ subroutine writeformatted(dtv, unit, iotype, v_list, iostat, iomsg )
+ import base
+ class(base), intent(in) :: dtv
+ integer, intent(in) :: unit
+ character(*), intent(in) :: iotype
+ integer, intent(in) :: v_list(:)
+ integer, intent(out) :: iostat
+ character(*), intent(inout) :: iomsg
+ end subroutine
+ end interface
+end module
+
+! CHECK-LABEL: c.func @_QPlocal_poly_namelist
+subroutine local_poly_namelist
+ use m
+ class(base), allocatable :: b1
+! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>
+! CHECK: %[[V_2:[0-9]+]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>> {bindc_name = "b1", uniq_name = "_QFlocal_poly_namelistEb1"}
+! CHECK: %[[V_5:[0-9]+]] = fir.declare %[[V_2]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFlocal_poly_namelistEb1"} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>>
+! CHECK: %[[V_9:[0-9]+]] = fir.alloca !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>
+! CHECK: %[[V_10:[0-9]+]] = fir.undefined !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>
+! CHECK: %[[V_11:[0-9]+]] = fir.address_of(@_QQclX623100) : !fir.ref<!fir.char<1,3>>
+! CHECK: %[[V_12:[0-9]+]] = fir.convert %[[V_11]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<i8>
+! CHECK: %[[V_13:[0-9]+]] = fir.insert_value %[[V_10]], %[[V_12]], [0 : index, 0 : index] : (!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>, !fir.ref<i8>) -> !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>
+! CHECK: %[[V_14:[0-9]+]] = fir.load %[[V_5]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>>
+! CHECK: %[[V_15:[0-9]+]] = fir.rebox %[[V_14]] : (!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>) -> !fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>
+! CHECK: fir.store %[[V_15]] to %[[V_0]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>>
+! CHECK: %[[V_16:[0-9]+]] = fir.convert %[[V_0]] : (!fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[V_17:[0-9]+]] = fir.insert_value %[[V_13]], %[[V_16]], [0 : index, 1 : index] : (!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>, !fir.ref<!fir.box<none>>) -> !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>
+! CHECK: fir.store %[[V_17]] to %[[V_9]] : !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>>
+ namelist/mygroup/b1
+ write(10, nml=mygroup)
+end subroutine
+
module mmm
real rrr
namelist /aaa/ rrr
@@ -142,3 +181,4 @@ end
! CHECK-NOT: ggg
! CHECK: fir.string_lit "aaa\00"(4) : !fir.char<1,4>
+
diff --git a/libc/src/string/memory_utils/op_aarch64.h b/libc/src/string/memory_utils/op_aarch64.h
index e552601..b5c3bb7 100644
--- a/libc/src/string/memory_utils/op_aarch64.h
+++ b/libc/src/string/memory_utils/op_aarch64.h
@@ -84,8 +84,7 @@ template <size_t Size> struct Bcmp {
uint8x16_t a = vld1q_u8(_p1);
uint8x16_t n = vld1q_u8(_p2);
uint8x16_t an = veorq_u8(a, n);
- uint32x2_t an_reduced = vqmovn_u64(vreinterpretq_u64_u8(an));
- return vmaxv_u32(an_reduced);
+ return vmaxvq_u32(vreinterpretq_u32_u8(an));
} else if constexpr (Size == 32) {
auto _p1 = as_u8(p1);
auto _p2 = as_u8(p2);
@@ -97,12 +96,9 @@ template <size_t Size> struct Bcmp {
uint8x16_t bo = veorq_u8(b, o);
// anbo = (a ^ n) | (b ^ o). At least one byte is nonzero if there is
// a difference between the two buffers. We reduce this value down to 4
- // bytes in two steps. First, calculate the saturated move value when
- // going from 2x64b to 2x32b. Second, compute the max of the 2x32b to get
- // a single 32 bit nonzero value if a mismatch occurred.
+ // bytes using the UMAXV instruction to compute the max across the vector.
uint8x16_t anbo = vorrq_u8(an, bo);
- uint32x2_t anbo_reduced = vqmovn_u64(vreinterpretq_u64_u8(anbo));
- return vmaxv_u32(anbo_reduced);
+ return vmaxvq_u32(vreinterpretq_u32_u8(anbo));
} else if constexpr ((Size % BlockSize) == 0) {
for (size_t offset = 0; offset < Size; offset += BlockSize)
if (auto value = Bcmp<BlockSize>::block(p1 + offset, p2 + offset))
@@ -129,8 +125,7 @@ template <size_t Size> struct Bcmp {
uint8x16_t bo = veorq_u8(b, o);
// anbo = (a ^ n) | (b ^ o)
uint8x16_t anbo = vorrq_u8(an, bo);
- uint32x2_t anbo_reduced = vqmovn_u64(vreinterpretq_u64_u8(anbo));
- return vmaxv_u32(anbo_reduced);
+ return vmaxvq_u32(vreinterpretq_u32_u8(anbo));
} else if constexpr (Size == 32) {
auto _p1 = as_u8(p1);
auto _p2 = as_u8(p2);
@@ -150,9 +145,8 @@ template <size_t Size> struct Bcmp {
uint8x16_t cpdq = vorrq_u8(cp, dq);
// abnocpdq = ((a ^ n) | (b ^ o)) | ((c ^ p) | (d ^ q)). Reduce this to
// a nonzero 32 bit value if a mismatch occurred.
- uint64x2_t abnocpdq = vreinterpretq_u64_u8(anbo | cpdq);
- uint32x2_t abnocpdq_reduced = vqmovn_u64(abnocpdq);
- return vmaxv_u32(abnocpdq_reduced);
+ uint8x16_t abnocpdq = anbo | cpdq;
+ return vmaxvq_u32(vreinterpretq_u32_u8(abnocpdq));
} else {
static_assert(cpp::always_false<decltype(Size)>, "SIZE not implemented");
}
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index 88b6cd9..715914f 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -233,6 +233,11 @@ AND call SWIG_fail at the same time, because it will result in a double free.
}
+// For lldb::SBFileSpec::GetPath
+%typemap(in) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len);
+%typemap(argout) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len);
+
+
// typemap for an outgoing buffer
// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
index 606f951..e20dd31 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp
@@ -142,7 +142,13 @@ lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
SyntheticChildrenFrontEnd *
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- if (valobj_sp)
+ if (valobj_sp && IsLibCxxAtomic(*valobj_sp))
return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
return nullptr;
}
+
+bool lldb_private::formatters::IsLibCxxAtomic(ValueObject &valobj) {
+ if (auto valobj_sp = valobj.GetNonSyntheticValue())
+ return valobj_sp->GetChildMemberWithName("__a_") != nullptr;
+ return false;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
index 9327446..7005950 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h
@@ -18,6 +18,8 @@
namespace lldb_private {
namespace formatters {
+bool IsLibCxxAtomic(ValueObject &valobj);
+
lldb::ValueObjectSP GetLibCxxAtomicValue(ValueObject &valobj);
bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index 8a49181..e818b88 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -89,6 +89,7 @@ MsvcStlVariantSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP valobj_sp);
// MSVC STL std::atomic<>
+bool IsMsvcStlAtomic(ValueObject &valobj);
bool MsvcStlAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options);
SyntheticChildrenFrontEnd *
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp
index 3ec3245..c871861 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp
@@ -83,7 +83,9 @@ llvm::Expected<size_t> lldb_private::formatters::
lldb_private::SyntheticChildrenFrontEnd *
lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
+ if (valobj_sp && IsMsvcStlAtomic(*valobj_sp))
+ return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
+ return nullptr;
}
bool lldb_private::formatters::MsvcStlAtomicSummaryProvider(
@@ -100,3 +102,9 @@ bool lldb_private::formatters::MsvcStlAtomicSummaryProvider(
}
return false;
}
+
+bool lldb_private::formatters::IsMsvcStlAtomic(ValueObject &valobj) {
+ if (auto valobj_sp = valobj.GetNonSyntheticValue())
+ return valobj_sp->GetChildMemberWithName("_Storage") != nullptr;
+ return false;
+}
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
index f538fc6..57d88f6 100644
--- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -9,6 +9,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/UriParser.h"
diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp
index b468171..2e02076 100644
--- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp
+++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp
@@ -22,7 +22,7 @@ using namespace lldb_private::process_gdb_remote;
using namespace lldb_private::wasm;
RegisterContextWasm::RegisterContextWasm(
- wasm::ThreadWasm &thread, uint32_t concrete_frame_idx,
+ ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
GDBRemoteDynamicRegisterInfoSP reg_info_sp)
: GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
false) {}
diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h
index 7e63eb8..6ca31e5 100644
--- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h
+++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_REGISTERCONTEXTWASM_H
#include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"
+#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
#include "ThreadWasm.h"
#include "Utility/WasmVirtualRegisters.h"
#include "lldb/lldb-private-types.h"
@@ -34,7 +35,7 @@ class RegisterContextWasm
: public process_gdb_remote::GDBRemoteRegisterContext {
public:
RegisterContextWasm(
- wasm::ThreadWasm &thread, uint32_t concrete_frame_idx,
+ process_gdb_remote::ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
process_gdb_remote::GDBRemoteDynamicRegisterInfoSP reg_info_sp);
~RegisterContextWasm() override;
diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
index 99845dd..319c5e2 100644
--- a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
+++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
@@ -9,6 +9,7 @@
#include "UnwindWasm.h"
#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h"
#include "ProcessWasm.h"
+#include "RegisterContextWasm.h"
#include "ThreadWasm.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
@@ -18,21 +19,6 @@ using namespace lldb_private;
using namespace process_gdb_remote;
using namespace wasm;
-class WasmGDBRemoteRegisterContext : public GDBRemoteRegisterContext {
-public:
- WasmGDBRemoteRegisterContext(ThreadGDBRemote &thread,
- uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfoSP &reg_info_sp,
- uint64_t pc)
- : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
- false) {
- // Wasm does not have a fixed set of registers but relies on a mechanism
- // named local and global variables to store information such as the stack
- // pointer. The only actual register is the PC.
- PrivateSetRegisterValue(0, pc);
- }
-};
-
lldb::RegisterContextSP
UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
if (m_frames.size() <= frame->GetFrameIndex())
@@ -43,9 +29,9 @@ UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
ProcessWasm *wasm_process =
static_cast<ProcessWasm *>(thread->GetProcess().get());
- return std::make_shared<WasmGDBRemoteRegisterContext>(
- *gdb_thread, frame->GetConcreteFrameIndex(),
- wasm_process->GetRegisterInfo(), m_frames[frame->GetFrameIndex()]);
+ return std::make_shared<RegisterContextWasm>(*gdb_thread,
+ frame->GetConcreteFrameIndex(),
+ wasm_process->GetRegisterInfo());
}
uint32_t UnwindWasm::DoGetFrameCount() {
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index c6d15fc..252bee2 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -52,6 +52,14 @@ static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
return ConstString();
}
+static bool CallFrameAddressIsValid(ABISP abi_sp, lldb::addr_t cfa) {
+ if (cfa == LLDB_INVALID_ADDRESS)
+ return false;
+ if (abi_sp)
+ return abi_sp->CallFrameAddressIsValid(cfa);
+ return cfa != 0 && cfa != 1;
+}
+
RegisterContextUnwind::RegisterContextUnwind(Thread &thread,
const SharedPtr &next_frame,
SymbolContext &sym_ctx,
@@ -448,7 +456,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa);
// A couple of sanity checks..
- if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) {
+ if (!CallFrameAddressIsValid(abi_sp, m_cfa)) {
UnwindLogMsg("could not find a valid cfa address");
m_frame_type = eNotAValidFrame;
return;
@@ -1847,9 +1855,11 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
active_row->GetCFAValue().GetValueType() !=
UnwindPlan::Row::FAValue::unspecified) {
addr_t new_cfa;
+ ProcessSP process_sp = m_thread.GetProcess();
+ ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr;
if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetCFAValue(), new_cfa) ||
- new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
+ active_row->GetCFAValue(), new_cfa) ||
+ !CallFrameAddressIsValid(abi_sp, new_cfa)) {
UnwindLogMsg("failed to get cfa with fallback unwindplan");
m_fallback_unwind_plan_sp.reset();
m_full_unwind_plan_sp = original_full_unwind_plan_sp;
@@ -1870,10 +1880,9 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
reg_value)) {
new_caller_pc_value = reg_value.GetAsUInt64();
- if (ProcessSP process_sp = m_thread.GetProcess()) {
- if (ABISP abi_sp = process_sp->GetABI())
- new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value);
- }
+ if (process_sp)
+ new_caller_pc_value =
+ process_sp->FixCodeAddress(new_caller_pc_value);
}
}
}
@@ -1932,9 +1941,11 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
active_row->GetCFAValue().GetValueType() !=
UnwindPlan::Row::FAValue::unspecified) {
addr_t new_cfa;
+ ProcessSP process_sp = m_thread.GetProcess();
+ ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr;
if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row->GetCFAValue(), new_cfa) ||
- new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
+ active_row->GetCFAValue(), new_cfa) ||
+ !CallFrameAddressIsValid(abi_sp, new_cfa)) {
UnwindLogMsg("failed to get cfa with fallback unwindplan");
m_fallback_unwind_plan_sp.reset();
return false;
@@ -2055,8 +2066,7 @@ bool RegisterContextUnwind::ReadFrameAddress(
RegisterNumber cfa_reg(m_thread, row_register_kind,
fa.GetRegisterNumber());
if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
- if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
- cfa_reg_contents == 1) {
+ if (!CallFrameAddressIsValid(abi_sp, cfa_reg_contents)) {
UnwindLogMsg(
"Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile
new file mode 100644
index 0000000..99998b2
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py
new file mode 100644
index 0000000..76b8e7b
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py
@@ -0,0 +1,45 @@
+"""
+Test formatting of `std::atomic`s not from any STL
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class InvalidAtomicDataFormatterTestCase(TestBase):
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.expect_expr(
+ "a",
+ result_children=[
+ ValueCheck(name="foo", value="1"),
+ ValueCheck(name="bar", value="2"),
+ ],
+ )
+ self.expect_expr(
+ "b",
+ result_children=[
+ ValueCheck(name="foo", value="3"),
+ ValueCheck(name="bar", value="4"),
+ ],
+ )
+
+ self.expect_expr(
+ "c",
+ result_children=[
+ ValueCheck(name="foo", value="5"),
+ ValueCheck(name="bar", value="6"),
+ ],
+ )
+ self.expect_expr(
+ "d",
+ result_children=[
+ ValueCheck(name="foo", value="7"),
+ ValueCheck(name="bar", value="8"),
+ ],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp
new file mode 100644
index 0000000..7b4c51c
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp
@@ -0,0 +1,23 @@
+namespace std {
+template <typename T> struct atomic {
+ int foo;
+ int bar;
+};
+
+namespace __1 {
+template <typename T> struct atomic {
+ int foo;
+ int bar;
+};
+} // namespace __1
+} // namespace std
+
+int main() {
+ std::atomic<int> a{1, 2};
+ std::atomic<void> b{3, 4};
+
+ std::__1::atomic<int> c{5, 6};
+ std::__1::atomic<void> d{7, 8};
+
+ return 0; // Set break point at this line.
+}
diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
index 10cbd26..fc7bfe4 100644
--- a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
+++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py
@@ -12,7 +12,7 @@ from lldbsuite.test import lldbutil
class TestCortexMExceptionUnwind(TestBase):
NO_DEBUG_INFO_TESTCASE = True
- @skipIfRemote
+ @skipIfLLVMTargetMissing("ARM")
def test_no_fpu(self):
"""Test that we can backtrace correctly through an ARM Cortex-M Exception return stack"""
diff --git a/lldb/test/API/macosx/mte/TestDarwinMTE.py b/lldb/test/API/macosx/mte/TestDarwinMTE.py
index ef858b1..489e24a 100644
--- a/lldb/test/API/macosx/mte/TestDarwinMTE.py
+++ b/lldb/test/API/macosx/mte/TestDarwinMTE.py
@@ -47,7 +47,7 @@ class TestDarwinMTE(TestBase):
self.expect("memory region ptr", substrs=["memory tagging: enabled"])
@skipUnlessFeature(cpu_feature.AArch64.MTE)
- def test_memory_read_with_tags(self):
+ def test_memory_read_show_tags(self):
self.build()
lldbutil.run_to_source_breakpoint(
self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
diff --git a/lldb/test/API/python_api/default-constructor/sb_filespec.py b/lldb/test/API/python_api/default-constructor/sb_filespec.py
index 4ab5c49..5dd78b1 100644
--- a/lldb/test/API/python_api/default-constructor/sb_filespec.py
+++ b/lldb/test/API/python_api/default-constructor/sb_filespec.py
@@ -10,5 +10,5 @@ def fuzz_obj(obj):
obj.ResolveExecutableLocation()
obj.GetFilename()
obj.GetDirectory()
- obj.GetPath(None, 0)
+ obj.GetPath(1)
obj.GetDescription(lldb.SBStream())
diff --git a/lldb/test/Shell/Expr/TestExprLanguageNote.test b/lldb/test/Shell/Expr/TestExprLanguageNote.test
index 7d8c702..e8e4e13 100644
--- a/lldb/test/Shell/Expr/TestExprLanguageNote.test
+++ b/lldb/test/Shell/Expr/TestExprLanguageNote.test
@@ -1,5 +1,3 @@
-# REQUIRES: (system-windows && lld) || !system-windows
-
# RUN: split-file %s %t
# RUN: %clang_host -g %t/main.cpp -o %t.out
#
@@ -29,7 +27,7 @@ run
expr blah
# CHECK-TARGET: (lldb) expr
-# CHECK-TARGET: note: Ran expression as 'C++{{.*}}'
+# CHECK-TARGET: note: Ran expression as '{{(ISO )?}}C++{{.*}}'
expr -l objc -- blah
diff --git a/lldb/utils/lui/lui.py b/lldb/utils/lui/lui.py
index 42ea3c6..27ed8f3 100755
--- a/lldb/utils/lui/lui.py
+++ b/lldb/utils/lui/lui.py
@@ -17,11 +17,7 @@ from optparse import OptionParser
import os
import signal
import sys
-
-try:
- import queue
-except ImportError:
- import Queue as queue
+import queue
import debuggerdriver
import cui
diff --git a/lldb/utils/lui/sandbox.py b/lldb/utils/lui/sandbox.py
index 3bcf3d5..d05c268 100755
--- a/lldb/utils/lui/sandbox.py
+++ b/lldb/utils/lui/sandbox.py
@@ -14,10 +14,7 @@ import os
import signal
import sys
-try:
- import queue
-except ImportError:
- import Queue as queue
+import queue
import cui
diff --git a/llvm/include/llvm/ADT/Bitfields.h b/llvm/include/llvm/ADT/Bitfields.h
index 4064d71..1af2761 100644
--- a/llvm/include/llvm/ADT/Bitfields.h
+++ b/llvm/include/llvm/ADT/Bitfields.h
@@ -86,89 +86,43 @@
#include <limits> // numeric_limits
#include <type_traits>
+#include "llvm/Support/MathExtras.h"
+
namespace llvm {
namespace bitfields_details {
-/// A struct defining useful bit patterns for n-bits integer types.
-template <typename T, unsigned Bits> struct BitPatterns {
- /// Bit patterns are forged using the equivalent `Unsigned` type because of
- /// undefined operations over signed types (e.g. Bitwise shift operators).
- /// Moreover same size casting from unsigned to signed is well defined but not
- /// the other way around.
- using Unsigned = std::make_unsigned_t<T>;
- static_assert(sizeof(Unsigned) == sizeof(T), "Types must have same size");
-
- static constexpr unsigned TypeBits = sizeof(Unsigned) * CHAR_BIT;
- static_assert(TypeBits >= Bits, "n-bit must fit in T");
-
- /// e.g. with TypeBits == 8 and Bits == 6.
- static constexpr Unsigned AllZeros = Unsigned(0); // 00000000
- static constexpr Unsigned AllOnes = ~Unsigned(0); // 11111111
- static constexpr Unsigned Umin = AllZeros; // 00000000
- static constexpr Unsigned Umax = AllOnes >> (TypeBits - Bits); // 00111111
- static constexpr Unsigned SignBitMask = Unsigned(1) << (Bits - 1); // 00100000
- static constexpr Unsigned Smax = Umax >> 1U; // 00011111
- static constexpr Unsigned Smin = ~Smax; // 11100000
- static constexpr Unsigned SignExtend = Unsigned(Smin << 1U); // 11000000
-};
-
-/// `Compressor` is used to manipulate the bits of a (possibly signed) integer
-/// type so it can be packed and unpacked into a `bits` sized integer,
-/// `Compressor` is specialized on signed-ness so no runtime cost is incurred.
-/// The `pack` method also checks that the passed in `UserValue` is valid.
-template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value>
-struct Compressor {
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- using BP = BitPatterns<T, Bits>;
-
- static T pack(T UserValue, T UserMaxValue) {
- assert(UserValue <= UserMaxValue && "value is too big");
- assert(UserValue <= BP::Umax && "value is too big");
- return UserValue;
- }
-
- static T unpack(T StorageValue) { return StorageValue; }
-};
-
-template <typename T, unsigned Bits> struct Compressor<T, Bits, false> {
- static_assert(std::is_signed<T>::value, "T must be signed");
- using BP = BitPatterns<T, Bits>;
-
- static T pack(T UserValue, T UserMaxValue) {
- assert(UserValue <= UserMaxValue && "value is too big");
- assert(UserValue <= T(BP::Smax) && "value is too big");
- assert(UserValue >= T(BP::Smin) && "value is too small");
- if (UserValue < 0)
- UserValue &= ~BP::SignExtend;
- return UserValue;
- }
-
- static T unpack(T StorageValue) {
- if (StorageValue >= T(BP::SignBitMask))
- StorageValue |= BP::SignExtend;
- return StorageValue;
- }
-};
-
/// Impl is where Bifield description and Storage are put together to interact
/// with values.
template <typename Bitfield, typename StorageType> struct Impl {
static_assert(std::is_unsigned<StorageType>::value,
"Storage must be unsigned");
using IntegerType = typename Bitfield::IntegerType;
- using C = Compressor<IntegerType, Bitfield::Bits>;
- using BP = BitPatterns<StorageType, Bitfield::Bits>;
static constexpr size_t StorageBits = sizeof(StorageType) * CHAR_BIT;
static_assert(Bitfield::FirstBit <= StorageBits, "Data must fit in mask");
static_assert(Bitfield::LastBit <= StorageBits, "Data must fit in mask");
- static constexpr StorageType Mask = BP::Umax << Bitfield::Shift;
+ static constexpr StorageType LowMask =
+ maskTrailingOnes<StorageType>(Bitfield::Bits);
+ static constexpr StorageType Mask = LowMask << Bitfield::Shift;
+
+ /// Validates that `UserValue` fits within the bitfield's range.
+ static void checkValue(IntegerType UserValue, IntegerType UserMaxValue) {
+ assert(UserValue <= UserMaxValue && "value is too big");
+ if constexpr (std::is_unsigned_v<IntegerType>) {
+ assert(isUInt<Bitfield::Bits>(UserValue) && "value is too big");
+ } else {
+ static_assert(std::is_signed_v<IntegerType>,
+ "IntegerType must be signed");
+ assert(isInt<Bitfield::Bits>(UserValue) && "value is out of range");
+ }
+ }
/// Checks `UserValue` is within bounds and packs it between `FirstBit` and
/// `LastBit` of `Packed` leaving the rest unchanged.
static void update(StorageType &Packed, IntegerType UserValue) {
- const StorageType StorageValue = C::pack(UserValue, Bitfield::UserMaxValue);
+ checkValue(UserValue, Bitfield::UserMaxValue);
+ const StorageType StorageValue = UserValue & LowMask;
Packed &= ~Mask;
Packed |= StorageValue << Bitfield::Shift;
}
@@ -177,7 +131,9 @@ template <typename Bitfield, typename StorageType> struct Impl {
/// an`IntegerType`.
static IntegerType extract(StorageType Packed) {
const StorageType StorageValue = (Packed & Mask) >> Bitfield::Shift;
- return C::unpack(StorageValue);
+ if constexpr (std::is_signed_v<IntegerType>)
+ return SignExtend64<Bitfield::Bits>(StorageValue);
+ return StorageValue;
}
/// Interprets bits between `FirstBit` and `LastBit` of `Packed` as
diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
index 164b46b..07a482d 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -182,6 +182,12 @@ m_scev_PtrToInt(const Op0_t &Op0) {
return SCEVUnaryExpr_match<SCEVPtrToIntExpr, Op0_t>(Op0);
}
+template <typename Op0_t>
+inline SCEVUnaryExpr_match<SCEVTruncateExpr, Op0_t>
+m_scev_Trunc(const Op0_t &Op0) {
+ return m_scev_Unary<SCEVTruncateExpr>(Op0);
+}
+
/// Match a binary SCEV.
template <typename SCEVTy, typename Op0_t, typename Op1_t,
SCEV::NoWrapFlags WrapFlags = SCEV::FlagAnyWrap,
diff --git a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
index fa21eba..f06e7ce 100644
--- a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
+++ b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
@@ -10,6 +10,24 @@
namespace llvm {
+namespace memprof {
+// Represents the eligibility status of a global variable for section prefix
+// annotation. Other than AnnotationOk, each enum value indicates a specific
+// reason for ineligibility.
+enum class AnnotationKind : uint8_t {
+ AnnotationOK,
+ DeclForLinker,
+ ExplicitSection,
+ ReservedName,
+};
+/// Returns the annotation kind of the global variable \p GV.
+AnnotationKind getAnnotationKind(const GlobalVariable &GV);
+
+/// Returns true if the annotation kind of the global variable \p GV is
+/// AnnotationOK.
+bool IsAnnotationOK(const GlobalVariable &GV);
+} // namespace memprof
+
/// A class that holds the constants that represent static data and their
/// profile information and provides methods to operate on them.
class StaticDataProfileInfo {
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index c76c83d..ff3dd0d 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -514,6 +514,12 @@ enum NodeType {
/// separately rounded operations.
FMAD,
+ /// FMULADD - Performs a * b + c, with, or without, intermediate rounding.
+ /// It is expected that this will be illegal for most targets, as it usually
+ /// makes sense to split this or use an FMA. But some targets, such as
+ /// WebAssembly, can directly support these semantics.
+ FMULADD,
+
/// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
/// DAG node does not require that X and Y have the same type, just that
/// they are both floating point. X and the result must have the same type.
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index 1694a33..46b3d53 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -472,7 +472,7 @@ __OMP_RTL(__kmpc_target_init, false, Int32, KernelEnvironmentPtr, KernelLaunchEn
__OMP_RTL(__kmpc_target_deinit, false, Void,)
__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
__OMP_RTL(__kmpc_parallel_51, false, Void, IdentPtr, Int32, Int32, Int32, Int32,
- FuncPtrTy, VoidPtr, VoidPtrPtr, SizeTy)
+ FuncPtrTy, FuncPtrTy, VoidPtrPtr, SizeTy)
__OMP_RTL(__kmpc_for_static_loop_4, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8)
__OMP_RTL(__kmpc_for_static_loop_4u, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8)
__OMP_RTL(__kmpc_for_static_loop_8, false, Void, IdentPtr, VoidPtr, VoidPtr, Int64, Int64, Int64, Int8)
diff --git a/llvm/include/llvm/IR/ConstantFPRange.h b/llvm/include/llvm/IR/ConstantFPRange.h
index 10467cc..e772095 100644
--- a/llvm/include/llvm/IR/ConstantFPRange.h
+++ b/llvm/include/llvm/IR/ConstantFPRange.h
@@ -231,6 +231,15 @@ public:
/// from a subtraction of a value in this range and a value in \p Other.
LLVM_ABI ConstantFPRange sub(const ConstantFPRange &Other) const;
+ /// Return a new range representing the possible values resulting
+ /// from a multiplication of a value in this range and a value in \p Other.
+ LLVM_ABI ConstantFPRange mul(const ConstantFPRange &Other) const;
+
+ /// Return a new range representing the possible values resulting
+ /// from a division of a value in this range and a value in
+ /// \p Other.
+ LLVM_ABI ConstantFPRange div(const ConstantFPRange &Other) const;
+
/// Flush denormal values to zero according to the specified mode.
/// For dynamic mode, we return the union of all possible results.
LLVM_ABI void flushDenormals(DenormalMode::DenormalModeKind Mode);
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 041a4ce..dacda0a 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -2548,6 +2548,11 @@ public:
std::optional<RoundingMode> Rounding = std::nullopt,
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
+ LLVM_ABI Value *CreateSelectWithUnknownProfile(Value *C, Value *True,
+ Value *False,
+ StringRef PassName,
+ const Twine &Name = "");
+
LLVM_ABI Value *CreateSelect(Value *C, Value *True, Value *False,
const Twine &Name = "",
Instruction *MDFrom = nullptr);
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 632be7a..07a858f 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -535,6 +535,7 @@ def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp, [SDNPCommutative]>;
def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp, [SDNPCommutative]>;
+def fmuladd : SDNode<"ISD::FMULADD" , SDTFPTernaryOp, [SDNPCommutative]>;
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp,
[SDNPCommutative, SDNPAssociative]>;
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index b1fca55..2ac58a5 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -161,6 +161,8 @@ inline static bool isAltFmt(unsigned VType) { return VType & 0x100; }
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS);
+LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS);
+
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul);
LLVM_ABI std::optional<VLMUL> getSameRatioLMUL(unsigned SEW, VLMUL VLMUL,
diff --git a/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h b/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h
index 558984f..eb2b34d 100644
--- a/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h
+++ b/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h
@@ -12,9 +12,7 @@
#ifndef LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H
#define LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H
-namespace llvm {
-
-namespace coro {
+namespace llvm::coro {
// True if I is trivially rematerialzable, e.g. InsertElementInst
LLVM_ABI bool isTriviallyMaterializable(Instruction &I);
@@ -24,8 +22,6 @@ LLVM_ABI void
doRematerializations(Function &F, SuspendCrossingInfo &Checker,
std::function<bool(Instruction &)> IsMaterializable);
-} // namespace coro
-
-} // namespace llvm
+} // namespace llvm::coro
#endif // LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H
diff --git a/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h b/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h
index 6cdf83c0..356f9ca 100644
--- a/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h
+++ b/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h
@@ -13,9 +13,7 @@
#ifndef LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H
#define LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H
-namespace llvm {
-
-namespace coro {
+namespace llvm::coro {
using SpillInfo = SmallMapVector<Value *, SmallVector<Instruction *, 2>, 8>;
@@ -38,6 +36,7 @@ void collectSpillsAndAllocasFromInsts(
SmallVector<CoroAllocaAllocInst *, 4> &LocalAllocas, Function &F,
const SuspendCrossingInfo &Checker, const DominatorTree &DT,
const coro::Shape &Shape);
+
void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F,
const SuspendCrossingInfo &Checker);
@@ -52,8 +51,6 @@ void sinkSpillUsesAfterCoroBegin(const DominatorTree &DT,
BasicBlock::iterator getSpillInsertionPt(const coro::Shape &, Value *Def,
const DominatorTree &DT);
-} // namespace coro
-
-} // namespace llvm
+} // namespace llvm::coro
#endif // LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H
diff --git a/llvm/include/llvm/XRay/BlockIndexer.h b/llvm/include/llvm/XRay/BlockIndexer.h
index e9782da..155e6bd 100644
--- a/llvm/include/llvm/XRay/BlockIndexer.h
+++ b/llvm/include/llvm/XRay/BlockIndexer.h
@@ -19,8 +19,7 @@
#include <cstdint>
#include <vector>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
// The BlockIndexer will gather all related records associated with a
// process+thread and group them by 'Block'.
@@ -63,7 +62,6 @@ public:
Error flush();
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_BLOCKINDEXER_H
diff --git a/llvm/include/llvm/XRay/BlockPrinter.h b/llvm/include/llvm/XRay/BlockPrinter.h
index caf78c5..81944a5 100644
--- a/llvm/include/llvm/XRay/BlockPrinter.h
+++ b/llvm/include/llvm/XRay/BlockPrinter.h
@@ -18,8 +18,7 @@
#include "llvm/XRay/FDRRecords.h"
#include "llvm/XRay/RecordPrinter.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class LLVM_ABI BlockPrinter : public RecordVisitor {
enum class State {
@@ -55,7 +54,6 @@ public:
void reset() { CurrentState = State::Start; }
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_BLOCKPRINTER_H
diff --git a/llvm/include/llvm/XRay/BlockVerifier.h b/llvm/include/llvm/XRay/BlockVerifier.h
index b88785c..5e7b25c 100644
--- a/llvm/include/llvm/XRay/BlockVerifier.h
+++ b/llvm/include/llvm/XRay/BlockVerifier.h
@@ -16,8 +16,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/XRay/FDRRecords.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class LLVM_ABI BlockVerifier : public RecordVisitor {
public:
@@ -64,7 +63,6 @@ public:
void reset();
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_BLOCKVERIFIER_H
diff --git a/llvm/include/llvm/XRay/FDRLogBuilder.h b/llvm/include/llvm/XRay/FDRLogBuilder.h
index f07c446..5f7b815 100644
--- a/llvm/include/llvm/XRay/FDRLogBuilder.h
+++ b/llvm/include/llvm/XRay/FDRLogBuilder.h
@@ -10,8 +10,7 @@
#include "llvm/XRay/FDRRecords.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// The LogBuilder class allows for creating ad-hoc collections of records
/// through the `add<...>(...)` function. An example use of this API is in
@@ -34,7 +33,6 @@ public:
std::vector<std::unique_ptr<Record>> consume() { return std::move(Records); }
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRLOGBUILDER_H
diff --git a/llvm/include/llvm/XRay/FDRRecordConsumer.h b/llvm/include/llvm/XRay/FDRRecordConsumer.h
index 473777f..13bb711 100644
--- a/llvm/include/llvm/XRay/FDRRecordConsumer.h
+++ b/llvm/include/llvm/XRay/FDRRecordConsumer.h
@@ -15,8 +15,7 @@
#include <memory>
#include <vector>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class RecordConsumer {
public:
@@ -48,7 +47,6 @@ public:
Error consume(std::unique_ptr<Record> R) override;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRRECORDCONSUMER_H
diff --git a/llvm/include/llvm/XRay/FDRRecordProducer.h b/llvm/include/llvm/XRay/FDRRecordProducer.h
index 083b571..b953f62 100644
--- a/llvm/include/llvm/XRay/FDRRecordProducer.h
+++ b/llvm/include/llvm/XRay/FDRRecordProducer.h
@@ -14,8 +14,7 @@
#include "llvm/XRay/XRayRecord.h"
#include <memory>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class RecordProducer {
public:
@@ -45,7 +44,6 @@ public:
Expected<std::unique_ptr<Record>> produce() override;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRRECORDPRODUCER_H
diff --git a/llvm/include/llvm/XRay/FDRRecords.h b/llvm/include/llvm/XRay/FDRRecords.h
index 7ee8db6..91689cae 100644
--- a/llvm/include/llvm/XRay/FDRRecords.h
+++ b/llvm/include/llvm/XRay/FDRRecords.h
@@ -23,8 +23,7 @@
#include "llvm/Support/Error.h"
#include "llvm/XRay/XRayRecord.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class RecordVisitor;
class RecordInitializer;
@@ -444,7 +443,6 @@ public:
Error visit(TypedEventRecord &) override;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRRECORDS_H
diff --git a/llvm/include/llvm/XRay/FDRTraceExpander.h b/llvm/include/llvm/XRay/FDRTraceExpander.h
index 197c123..ca400c9 100644
--- a/llvm/include/llvm/XRay/FDRTraceExpander.h
+++ b/llvm/include/llvm/XRay/FDRTraceExpander.h
@@ -17,8 +17,7 @@
#include "llvm/XRay/FDRRecords.h"
#include "llvm/XRay/XRayRecord.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class TraceExpander : public RecordVisitor {
// Type-erased callback for handling individual XRayRecord instances.
@@ -56,7 +55,6 @@ public:
Error flush();
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRTRACEEXPANDER_H
diff --git a/llvm/include/llvm/XRay/FDRTraceWriter.h b/llvm/include/llvm/XRay/FDRTraceWriter.h
index a3dc58e..957039d 100644
--- a/llvm/include/llvm/XRay/FDRTraceWriter.h
+++ b/llvm/include/llvm/XRay/FDRTraceWriter.h
@@ -18,8 +18,7 @@
#include "llvm/XRay/FDRRecords.h"
#include "llvm/XRay/XRayRecord.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// The FDRTraceWriter allows us to hand-craft an XRay Flight Data Recorder
/// (FDR) mode log file. This is used primarily for testing, generating
@@ -50,7 +49,6 @@ private:
support::endian::Writer OS;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FDRTRACEWRITER_H
diff --git a/llvm/include/llvm/XRay/FileHeaderReader.h b/llvm/include/llvm/XRay/FileHeaderReader.h
index ecdb975..758ca29 100644
--- a/llvm/include/llvm/XRay/FileHeaderReader.h
+++ b/llvm/include/llvm/XRay/FileHeaderReader.h
@@ -19,15 +19,13 @@
#include "llvm/XRay/XRayRecord.h"
#include <cstdint>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// Convenience function for loading the file header given a data extractor at a
/// specified offset.
LLVM_ABI Expected<XRayFileHeader>
readBinaryFormatHeader(DataExtractor &HeaderExtractor, uint64_t &OffsetPtr);
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_FILEHEADERREADER_H
diff --git a/llvm/include/llvm/XRay/Graph.h b/llvm/include/llvm/XRay/Graph.h
index 07b418b..8521e09 100644
--- a/llvm/include/llvm/XRay/Graph.h
+++ b/llvm/include/llvm/XRay/Graph.h
@@ -23,8 +23,7 @@
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Error.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// A Graph object represents a Directed Graph and is used in XRay to compute
/// and store function call graphs and associated statistical information.
@@ -485,6 +484,6 @@ public:
return p;
}
};
-}
-}
+} // namespace llvm::xray
+
#endif
diff --git a/llvm/include/llvm/XRay/InstrumentationMap.h b/llvm/include/llvm/XRay/InstrumentationMap.h
index b5371478..c5e7ebf 100644
--- a/llvm/include/llvm/XRay/InstrumentationMap.h
+++ b/llvm/include/llvm/XRay/InstrumentationMap.h
@@ -23,9 +23,7 @@
#include <unordered_map>
#include <vector>
-namespace llvm {
-
-namespace xray {
+namespace llvm::xray {
// Forward declare to make a friend.
class InstrumentationMap;
@@ -102,11 +100,11 @@ public:
const SledContainer &sleds() const { return Sleds; };
};
-} // end namespace xray
-
-namespace yaml {
+} // end namespace llvm::xray
-template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> {
+namespace llvm {
+template <>
+struct yaml::ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> {
static void enumeration(IO &IO, xray::SledEntry::FunctionKinds &Kind) {
IO.enumCase(Kind, "function-enter", xray::SledEntry::FunctionKinds::ENTRY);
IO.enumCase(Kind, "function-exit", xray::SledEntry::FunctionKinds::EXIT);
@@ -118,7 +116,7 @@ template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> {
}
};
-template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
+template <> struct yaml::MappingTraits<xray::YAMLXRaySledEntry> {
static void mapping(IO &IO, xray::YAMLXRaySledEntry &Entry) {
IO.mapRequired("id", Entry.FuncId);
IO.mapRequired("address", Entry.Address);
@@ -131,10 +129,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
static constexpr bool flow = true;
};
-
-} // end namespace yaml
-
-} // end namespace llvm
+} // namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRaySledEntry)
diff --git a/llvm/include/llvm/XRay/Profile.h b/llvm/include/llvm/XRay/Profile.h
index e30c01e..b5b8dd2 100644
--- a/llvm/include/llvm/XRay/Profile.h
+++ b/llvm/include/llvm/XRay/Profile.h
@@ -22,8 +22,7 @@
#include <utility>
#include <vector>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class Profile;
@@ -144,7 +143,6 @@ public:
bool empty() const { return Blocks.empty(); }
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif
diff --git a/llvm/include/llvm/XRay/RecordPrinter.h b/llvm/include/llvm/XRay/RecordPrinter.h
index 5d2c277..3281221 100644
--- a/llvm/include/llvm/XRay/RecordPrinter.h
+++ b/llvm/include/llvm/XRay/RecordPrinter.h
@@ -17,8 +17,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/XRay/FDRRecords.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
class LLVM_ABI RecordPrinter : public RecordVisitor {
raw_ostream &OS;
@@ -44,7 +43,6 @@ public:
Error visit(TypedEventRecord &) override;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_RECORDPRINTER_H
diff --git a/llvm/include/llvm/XRay/Trace.h b/llvm/include/llvm/XRay/Trace.h
index 5e4e40a..13ada22 100644
--- a/llvm/include/llvm/XRay/Trace.h
+++ b/llvm/include/llvm/XRay/Trace.h
@@ -21,8 +21,7 @@
#include "llvm/Support/Error.h"
#include "llvm/XRay/XRayRecord.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// A Trace object represents the records that have been loaded from XRay
/// log files generated by instrumented binaries. We encapsulate the logic of
@@ -76,7 +75,6 @@ LLVM_ABI Expected<Trace> loadTraceFile(StringRef Filename, bool Sort = false);
LLVM_ABI Expected<Trace> loadTrace(const DataExtractor &Extractor,
bool Sort = false);
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_TRACE_H
diff --git a/llvm/include/llvm/XRay/XRayRecord.h b/llvm/include/llvm/XRay/XRayRecord.h
index 238bf3d..8f3440c 100644
--- a/llvm/include/llvm/XRay/XRayRecord.h
+++ b/llvm/include/llvm/XRay/XRayRecord.h
@@ -18,8 +18,7 @@
#include <vector>
#include <string>
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
/// XRay traces all have a header providing some top-matter information useful
/// to help tools determine how to interpret the information available in the
@@ -98,7 +97,6 @@ struct XRayRecord {
std::string Data;
};
-} // namespace xray
-} // namespace llvm
+} // namespace llvm::xray
#endif // LLVM_XRAY_XRAYRECORD_H
diff --git a/llvm/include/llvm/XRay/YAMLXRayRecord.h b/llvm/include/llvm/XRay/YAMLXRayRecord.h
index 6062606..6bf4f1d 100644
--- a/llvm/include/llvm/XRay/YAMLXRayRecord.h
+++ b/llvm/include/llvm/XRay/YAMLXRayRecord.h
@@ -17,8 +17,7 @@
#include "llvm/Support/YAMLTraits.h"
#include "llvm/XRay/XRayRecord.h"
-namespace llvm {
-namespace xray {
+namespace llvm::xray {
struct YAMLXRayFileHeader {
uint16_t Version;
@@ -46,13 +45,12 @@ struct YAMLXRayTrace {
std::vector<YAMLXRayRecord> Records;
};
-} // namespace xray
-
-namespace yaml {
+} // namespace llvm::xray
+namespace llvm {
// YAML Traits
// -----------
-template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
+template <> struct yaml::ScalarEnumerationTraits<xray::RecordTypes> {
static void enumeration(IO &IO, xray::RecordTypes &Type) {
IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER);
IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT);
@@ -63,7 +61,7 @@ template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
}
};
-template <> struct MappingTraits<xray::YAMLXRayFileHeader> {
+template <> struct yaml::MappingTraits<xray::YAMLXRayFileHeader> {
static void mapping(IO &IO, xray::YAMLXRayFileHeader &Header) {
IO.mapRequired("version", Header.Version);
IO.mapRequired("type", Header.Type);
@@ -73,7 +71,7 @@ template <> struct MappingTraits<xray::YAMLXRayFileHeader> {
}
};
-template <> struct MappingTraits<xray::YAMLXRayRecord> {
+template <> struct yaml::MappingTraits<xray::YAMLXRayRecord> {
static void mapping(IO &IO, xray::YAMLXRayRecord &Record) {
IO.mapRequired("type", Record.RecordType);
IO.mapOptional("func-id", Record.FuncId);
@@ -90,7 +88,7 @@ template <> struct MappingTraits<xray::YAMLXRayRecord> {
static constexpr bool flow = true;
};
-template <> struct MappingTraits<xray::YAMLXRayTrace> {
+template <> struct yaml::MappingTraits<llvm::xray::YAMLXRayTrace> {
static void mapping(IO &IO, xray::YAMLXRayTrace &Trace) {
// A trace file contains two parts, the header and the list of all the
// trace records.
@@ -98,8 +96,6 @@ template <> struct MappingTraits<xray::YAMLXRayTrace> {
IO.mapRequired("records", Trace.Records);
}
};
-
-} // namespace yaml
} // namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRayRecord)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b5b4cd9..00c3dbb 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5419,20 +5419,15 @@ static Type *isSimpleCastedPHI(const SCEV *Op, const SCEVUnknown *SymbolicPHI,
if (SourceBits != NewBits)
return nullptr;
- const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(Op);
- const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(Op);
- if (!SExt && !ZExt)
- return nullptr;
- const SCEVTruncateExpr *Trunc =
- SExt ? dyn_cast<SCEVTruncateExpr>(SExt->getOperand())
- : dyn_cast<SCEVTruncateExpr>(ZExt->getOperand());
- if (!Trunc)
- return nullptr;
- const SCEV *X = Trunc->getOperand();
- if (X != SymbolicPHI)
- return nullptr;
- Signed = SExt != nullptr;
- return Trunc->getType();
+ if (match(Op, m_scev_SExt(m_scev_Trunc(m_scev_Specific(SymbolicPHI))))) {
+ Signed = true;
+ return cast<SCEVCastExpr>(Op)->getOperand()->getType();
+ }
+ if (match(Op, m_scev_ZExt(m_scev_Trunc(m_scev_Specific(SymbolicPHI))))) {
+ Signed = false;
+ return cast<SCEVCastExpr>(Op)->getOperand()->getType();
+ }
+ return nullptr;
}
static const Loop *isIntegerLoopHeaderPHI(const PHINode *PN, LoopInfo &LI) {
@@ -15428,20 +15423,18 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
// Try to match 'zext (trunc A to iB) to iY', which is used
// for URem with constant power-of-2 second operands. Make sure the size of
// the operand A matches the size of the whole expressions.
- if (const auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(Expr))
- if (const auto *Trunc = dyn_cast<SCEVTruncateExpr>(ZExt->getOperand(0))) {
- LHS = Trunc->getOperand();
- // Bail out if the type of the LHS is larger than the type of the
- // expression for now.
- if (getTypeSizeInBits(LHS->getType()) >
- getTypeSizeInBits(Expr->getType()))
- return false;
- if (LHS->getType() != Expr->getType())
- LHS = getZeroExtendExpr(LHS, Expr->getType());
- RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1)
- << getTypeSizeInBits(Trunc->getType()));
- return true;
- }
+ if (match(Expr, m_scev_ZExt(m_scev_Trunc(m_SCEV(LHS))))) {
+ Type *TruncTy = cast<SCEVZeroExtendExpr>(Expr)->getOperand()->getType();
+ // Bail out if the type of the LHS is larger than the type of the
+ // expression for now.
+ if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(Expr->getType()))
+ return false;
+ if (LHS->getType() != Expr->getType())
+ LHS = getZeroExtendExpr(LHS, Expr->getType());
+ RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1)
+ << getTypeSizeInBits(TruncTy));
+ return true;
+ }
const auto *Add = dyn_cast<SCEVAddExpr>(Expr);
if (Add == nullptr || Add->getNumOperands() != 2)
return false;
diff --git a/llvm/lib/Analysis/StaticDataProfileInfo.cpp b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
index b036b2d..1f751ee 100644
--- a/llvm/lib/Analysis/StaticDataProfileInfo.cpp
+++ b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
@@ -6,6 +6,46 @@
#include "llvm/ProfileData/InstrProf.h"
using namespace llvm;
+
+namespace llvm {
+namespace memprof {
+// Returns true iff the global variable has custom section either by
+// __attribute__((section("name")))
+// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
+// or #pragma clang section directives
+// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
+static bool hasExplicitSectionName(const GlobalVariable &GVar) {
+ if (GVar.hasSection())
+ return true;
+
+ auto Attrs = GVar.getAttributes();
+ if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
+ Attrs.hasAttribute("relro-section") ||
+ Attrs.hasAttribute("rodata-section"))
+ return true;
+ return false;
+}
+
+AnnotationKind getAnnotationKind(const GlobalVariable &GV) {
+ if (GV.isDeclarationForLinker())
+ return AnnotationKind::DeclForLinker;
+ // Skip 'llvm.'-prefixed global variables conservatively because they are
+ // often handled specially,
+ StringRef Name = GV.getName();
+ if (Name.starts_with("llvm."))
+ return AnnotationKind::ReservedName;
+ // Respect user-specified custom data sections.
+ if (hasExplicitSectionName(GV))
+ return AnnotationKind::ExplicitSection;
+ return AnnotationKind::AnnotationOK;
+}
+
+bool IsAnnotationOK(const GlobalVariable &GV) {
+ return getAnnotationKind(GV) == AnnotationKind::AnnotationOK;
+}
+} // namespace memprof
+} // namespace llvm
+
void StaticDataProfileInfo::addConstantProfileCount(
const Constant *C, std::optional<uint64_t> Count) {
if (!Count) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
index 6356d71..873ac8f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
@@ -20,7 +20,7 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
-namespace llvm {
+using namespace llvm;
AIXException::AIXException(AsmPrinter *A) : EHStreamer(A) {}
@@ -90,5 +90,3 @@ void AIXException::endFunction(const MachineFunction *MF) {
emitExceptionInfoTable(LSDALabel, PerSym);
}
-
-} // End of namespace llvm
diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index 260ce8f..93ae548 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -85,8 +85,7 @@ template <> struct llvm::DenseMapInfo<VariableID> {
using VarLocInsertPt = PointerUnion<const Instruction *, const DbgRecord *>;
-namespace std {
-template <> struct hash<VarLocInsertPt> {
+template <> struct std::hash<VarLocInsertPt> {
using argument_type = VarLocInsertPt;
using result_type = std::size_t;
@@ -94,7 +93,6 @@ template <> struct hash<VarLocInsertPt> {
return std::hash<void *>()(Arg.getOpaqueValue());
}
};
-} // namespace std
/// Helper class to build FunctionVarLocs, since that class isn't easy to
/// modify. TODO: There's not a great deal of value in the split, it could be
diff --git a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp
index fd7df6b..47b7a88 100644
--- a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp
+++ b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp
@@ -207,9 +207,7 @@ bool ApplyCloning(MachineFunction &MF,
}
return AnyPathsCloned;
}
-} // end anonymous namespace
-namespace llvm {
class BasicBlockPathCloning : public MachineFunctionPass {
public:
static char ID;
@@ -229,7 +227,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
};
-} // namespace llvm
+} // namespace
char BasicBlockPathCloning::ID = 0;
INITIALIZE_PASS_BEGIN(
diff --git a/llvm/lib/CodeGen/BreakFalseDeps.cpp b/llvm/lib/CodeGen/BreakFalseDeps.cpp
index 28e6728..1846880 100644
--- a/llvm/lib/CodeGen/BreakFalseDeps.cpp
+++ b/llvm/lib/CodeGen/BreakFalseDeps.cpp
@@ -31,7 +31,7 @@
using namespace llvm;
-namespace llvm {
+namespace {
class BreakFalseDeps : public MachineFunctionPass {
private:
@@ -95,7 +95,7 @@ private:
void processUndefReads(MachineBasicBlock *);
};
-} // namespace llvm
+} // namespace
#define DEBUG_TYPE "break-false-deps"
diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
index 6c2a5a7..87ada87 100644
--- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
+++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
@@ -126,8 +126,7 @@ hash_code hash_value(const ComplexValue &Arg) {
} // end namespace
typedef SmallVector<struct ComplexValue, 2> ComplexValues;
-namespace llvm {
-template <> struct DenseMapInfo<ComplexValue> {
+template <> struct llvm::DenseMapInfo<ComplexValue> {
static inline ComplexValue getEmptyKey() {
return {DenseMapInfo<Value *>::getEmptyKey(),
DenseMapInfo<Value *>::getEmptyKey()};
@@ -144,7 +143,6 @@ template <> struct DenseMapInfo<ComplexValue> {
return LHS.Real == RHS.Real && LHS.Imag == RHS.Imag;
}
};
-} // end namespace llvm
namespace {
template <typename T, typename IterT>
diff --git a/llvm/lib/CodeGen/EdgeBundles.cpp b/llvm/lib/CodeGen/EdgeBundles.cpp
index f4335396..50dd66f 100644
--- a/llvm/lib/CodeGen/EdgeBundles.cpp
+++ b/llvm/lib/CodeGen/EdgeBundles.cpp
@@ -81,13 +81,10 @@ void EdgeBundles::init() {
}
}
-namespace llvm {
-
/// Specialize WriteGraph, the standard implementation won't work.
-template<>
-raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
- bool ShortNames,
- const Twine &Title) {
+template <>
+raw_ostream &llvm::WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
+ bool ShortNames, const Twine &Title) {
const MachineFunction *MF = G.getMachineFunction();
O << "digraph {\n";
@@ -107,8 +104,6 @@ raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
return O;
}
-} // end namespace llvm
-
/// view - Visualize the annotated bipartite CFG with Graphviz.
void EdgeBundles::view() const {
ViewGraph(*this, "EdgeBundles");
diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp
index c500357..04c7008 100644
--- a/llvm/lib/CodeGen/ExpandFp.cpp
+++ b/llvm/lib/CodeGen/ExpandFp.cpp
@@ -1036,6 +1036,7 @@ static bool runImpl(Function &F, const TargetLowering &TLI,
continue;
addToWorklist(I, Worklist);
+ Modified = true;
break;
}
default:
diff --git a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
index 47640c4a..81ab317 100644
--- a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
+++ b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp
@@ -587,16 +587,12 @@ public:
} // namespace
char GlobalMergeFuncPassWrapper::ID = 0;
-INITIALIZE_PASS_BEGIN(GlobalMergeFuncPassWrapper, "global-merge-func",
- "Global merge function pass", false, false)
-INITIALIZE_PASS_END(GlobalMergeFuncPassWrapper, "global-merge-func",
- "Global merge function pass", false, false)
+INITIALIZE_PASS(GlobalMergeFuncPassWrapper, "global-merge-func",
+ "Global merge function pass", false, false)
-namespace llvm {
-ModulePass *createGlobalMergeFuncPass() {
+ModulePass *llvm::createGlobalMergeFuncPass() {
return new GlobalMergeFuncPassWrapper();
}
-} // namespace llvm
GlobalMergeFuncPassWrapper::GlobalMergeFuncPassWrapper() : ModulePass(ID) {
initializeGlobalMergeFuncPassWrapperPass(
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index 3485a27..0e38017 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -101,15 +101,11 @@ static cl::opt<bool> EnablePrecomputePhysRegs(
static bool EnablePrecomputePhysRegs = false;
#endif // NDEBUG
-namespace llvm {
-
-cl::opt<bool> UseSegmentSetForPhysRegs(
+cl::opt<bool> llvm::UseSegmentSetForPhysRegs(
"use-segment-set-for-physregs", cl::Hidden, cl::init(true),
cl::desc(
"Use segment set for the computation of the live ranges of physregs."));
-} // end namespace llvm
-
void LiveIntervalsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addPreserved<LiveVariablesWrapperPass>();
diff --git a/llvm/lib/CodeGen/MIR2Vec.cpp b/llvm/lib/CodeGen/MIR2Vec.cpp
index e859765..5c78d98 100644
--- a/llvm/lib/CodeGen/MIR2Vec.cpp
+++ b/llvm/lib/CodeGen/MIR2Vec.cpp
@@ -29,20 +29,17 @@ using namespace mir2vec;
STATISTIC(MIRVocabMissCounter,
"Number of lookups to MIR entities not present in the vocabulary");
-namespace llvm {
-namespace mir2vec {
-cl::OptionCategory MIR2VecCategory("MIR2Vec Options");
+cl::OptionCategory llvm::mir2vec::MIR2VecCategory("MIR2Vec Options");
// FIXME: Use a default vocab when not specified
static cl::opt<std::string>
VocabFile("mir2vec-vocab-path", cl::Optional,
cl::desc("Path to the vocabulary file for MIR2Vec"), cl::init(""),
cl::cat(MIR2VecCategory));
-cl::opt<float> OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0),
- cl::desc("Weight for machine opcode embeddings"),
- cl::cat(MIR2VecCategory));
-} // namespace mir2vec
-} // namespace llvm
+cl::opt<float>
+ llvm::mir2vec::OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0),
+ cl::desc("Weight for machine opcode embeddings"),
+ cl::cat(MIR2VecCategory));
//===----------------------------------------------------------------------===//
// Vocabulary Implementation
diff --git a/llvm/lib/CodeGen/MIRFSDiscriminator.cpp b/llvm/lib/CodeGen/MIRFSDiscriminator.cpp
index f5146f5..d988a2a 100644
--- a/llvm/lib/CodeGen/MIRFSDiscriminator.cpp
+++ b/llvm/lib/CodeGen/MIRFSDiscriminator.cpp
@@ -40,7 +40,7 @@ cl::opt<bool> ImprovedFSDiscriminator(
"improved-fs-discriminator", cl::Hidden, cl::init(false),
cl::desc("New FS discriminators encoding (incompatible with the original "
"encoding)"));
-}
+} // namespace llvm
char MIRAddFSDiscriminators::ID = 0;
diff --git a/llvm/lib/CodeGen/MIRNamerPass.cpp b/llvm/lib/CodeGen/MIRNamerPass.cpp
index bc65700..cbf8867 100644
--- a/llvm/lib/CodeGen/MIRNamerPass.cpp
+++ b/llvm/lib/CodeGen/MIRNamerPass.cpp
@@ -23,10 +23,6 @@
using namespace llvm;
-namespace llvm {
-extern char &MIRNamerID;
-} // namespace llvm
-
#define DEBUG_TYPE "mir-namer"
namespace {
@@ -53,10 +49,9 @@ public:
VRegRenamer Renamer(MF.getRegInfo());
- unsigned BBIndex = 0;
ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
- for (auto &MBB : RPOT)
- Changed |= Renamer.renameVRegs(MBB, BBIndex++);
+ for (const auto &[BBIndex, MBB] : enumerate(RPOT))
+ Changed |= Renamer.renameVRegs(MBB, BBIndex);
return Changed;
}
@@ -66,10 +61,4 @@ public:
char MIRNamer::ID;
-char &llvm::MIRNamerID = MIRNamer::ID;
-
-INITIALIZE_PASS_BEGIN(MIRNamer, "mir-namer", "Rename Register Operands", false,
- false)
-
-INITIALIZE_PASS_END(MIRNamer, "mir-namer", "Rename Register Operands", false,
- false)
+INITIALIZE_PASS(MIRNamer, "mir-namer", "Rename Register Operands", false, false)
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index bf8a6cd..96428cd 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -107,10 +107,8 @@ struct MFPrintState {
} // end anonymous namespace
-namespace llvm::yaml {
-
/// This struct serializes the LLVM IR module.
-template <> struct BlockScalarTraits<Module> {
+template <> struct yaml::BlockScalarTraits<Module> {
static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
Mod.print(OS, nullptr);
}
@@ -121,8 +119,6 @@ template <> struct BlockScalarTraits<Module> {
}
};
-} // end namespace llvm::yaml
-
static void printRegMIR(Register Reg, yaml::StringValue &Dest,
const TargetRegisterInfo *TRI) {
raw_string_ostream OS(Dest.Value);
diff --git a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
index b2731b69..a72c2c4 100644
--- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
+++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp
@@ -97,7 +97,9 @@ static const bool EnableDevelopmentFeatures = false;
/// this happens only in development mode. It's a no-op otherwise.
namespace llvm {
extern cl::opt<unsigned> EvictInterferenceCutoff;
+} // namespace llvm
+namespace {
class RegAllocScoring : public MachineFunctionPass {
public:
static char ID;
@@ -124,11 +126,12 @@ public:
/// Performs this pass
bool runOnMachineFunction(MachineFunction &) override;
};
+} // namespace
char RegAllocScoring::ID = 0;
-FunctionPass *createRegAllocScoringPass() { return new RegAllocScoring(); }
-
-} // namespace llvm
+FunctionPass *llvm::createRegAllocScoringPass() {
+ return new RegAllocScoring();
+}
INITIALIZE_PASS(RegAllocScoring, "regallocscoringpass",
"Register Allocation Scoring Pass", false, false)
diff --git a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp
index e7fa082..26eb10f 100644
--- a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp
@@ -29,7 +29,6 @@ using namespace llvm;
#define DEBUG_TYPE "machine-block-freq"
-namespace llvm {
static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
"view-machine-block-freq-propagation-dags", cl::Hidden,
cl::desc("Pop up a window to show a dag displaying how machine block "
@@ -44,6 +43,7 @@ static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
clEnumValN(GVDT_Count, "count", "display a graph using the real "
"profile count if available.")));
+namespace llvm {
// Similar option above, but used to control BFI display only after MBP pass
cl::opt<GVDAGType> ViewBlockLayoutWithBFI(
"view-block-layout-with-bfi", cl::Hidden,
@@ -69,15 +69,15 @@ extern cl::opt<std::string> ViewBlockFreqFuncName;
// Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc=
extern cl::opt<unsigned> ViewHotFreqPercent;
-static cl::opt<bool> PrintMachineBlockFreq(
- "print-machine-bfi", cl::init(false), cl::Hidden,
- cl::desc("Print the machine block frequency info."));
-
// Command line option to specify the name of the function for block frequency
// dump. Defined in Analysis/BlockFrequencyInfo.cpp.
extern cl::opt<std::string> PrintBFIFuncName;
} // namespace llvm
+static cl::opt<bool>
+ PrintMachineBlockFreq("print-machine-bfi", cl::init(false), cl::Hidden,
+ cl::desc("Print the machine block frequency info."));
+
static GVDAGType getGVDT() {
if (ViewBlockLayoutWithBFI != GVDT_None)
return ViewBlockLayoutWithBFI;
@@ -85,9 +85,7 @@ static GVDAGType getGVDT() {
return ViewMachineBlockFreqPropagationDAG;
}
-namespace llvm {
-
-template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
+template <> struct llvm::GraphTraits<MachineBlockFrequencyInfo *> {
using NodeRef = const MachineBasicBlock *;
using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
@@ -116,7 +114,7 @@ using MBFIDOTGraphTraitsBase =
MachineBranchProbabilityInfo>;
template <>
-struct DOTGraphTraits<MachineBlockFrequencyInfo *>
+struct llvm::DOTGraphTraits<MachineBlockFrequencyInfo *>
: public MBFIDOTGraphTraitsBase {
const MachineFunction *CurFunc = nullptr;
DenseMap<const MachineBasicBlock *, int> LayoutOrderMap;
@@ -159,8 +157,6 @@ struct DOTGraphTraits<MachineBlockFrequencyInfo *>
}
};
-} // end namespace llvm
-
AnalysisKey MachineBlockFrequencyAnalysis::Key;
MachineBlockFrequencyAnalysis::Result
diff --git a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp
index 2e92dd8..7ca4582 100644
--- a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp
@@ -18,13 +18,8 @@
using namespace llvm;
-INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfoWrapperPass,
- "machine-branch-prob",
- "Machine Branch Probability Analysis", false, true)
-INITIALIZE_PASS_END(MachineBranchProbabilityInfoWrapperPass,
- "machine-branch-prob",
- "Machine Branch Probability Analysis", false, true)
-
+INITIALIZE_PASS(MachineBranchProbabilityInfoWrapperPass, "machine-branch-prob",
+ "Machine Branch Probability Analysis", false, true)
namespace llvm {
cl::opt<unsigned>
StaticLikelyProb("static-likely-prob",
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 224231c..bfa5ab2 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -719,43 +719,41 @@ MachineFunction::CallSiteInfo::CallSiteInfo(const CallBase &CB) {
}
}
-namespace llvm {
+template <>
+struct llvm::DOTGraphTraits<const MachineFunction *>
+ : public DefaultDOTGraphTraits {
+ DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
- template<>
- struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
- DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+ static std::string getGraphName(const MachineFunction *F) {
+ return ("CFG for '" + F->getName() + "' function").str();
+ }
- static std::string getGraphName(const MachineFunction *F) {
- return ("CFG for '" + F->getName() + "' function").str();
+ std::string getNodeLabel(const MachineBasicBlock *Node,
+ const MachineFunction *Graph) {
+ std::string OutStr;
+ {
+ raw_string_ostream OSS(OutStr);
+
+ if (isSimple()) {
+ OSS << printMBBReference(*Node);
+ if (const BasicBlock *BB = Node->getBasicBlock())
+ OSS << ": " << BB->getName();
+ } else
+ Node->print(OSS);
}
- std::string getNodeLabel(const MachineBasicBlock *Node,
- const MachineFunction *Graph) {
- std::string OutStr;
- {
- raw_string_ostream OSS(OutStr);
-
- if (isSimple()) {
- OSS << printMBBReference(*Node);
- if (const BasicBlock *BB = Node->getBasicBlock())
- OSS << ": " << BB->getName();
- } else
- Node->print(OSS);
- }
-
- if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
-
- // Process string output to make it nicer...
- for (unsigned i = 0; i != OutStr.length(); ++i)
- if (OutStr[i] == '\n') { // Left justify
- OutStr[i] = '\\';
- OutStr.insert(OutStr.begin()+i+1, 'l');
- }
- return OutStr;
- }
- };
+ if (OutStr[0] == '\n')
+ OutStr.erase(OutStr.begin());
-} // end namespace llvm
+ // Process string output to make it nicer...
+ for (unsigned i = 0; i != OutStr.length(); ++i)
+ if (OutStr[i] == '\n') { // Left justify
+ OutStr[i] = '\\';
+ OutStr.insert(OutStr.begin() + i + 1, 'l');
+ }
+ return OutStr;
+ }
+};
void MachineFunction::viewCFG() const
{
diff --git a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
index 0f88a7b..5111322 100644
--- a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
+++ b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
@@ -60,13 +60,11 @@ char &llvm::MachineFunctionPrinterPassID = MachineFunctionPrinterPass::ID;
INITIALIZE_PASS(MachineFunctionPrinterPass, "machineinstr-printer",
"Machine Function Printer", false, false)
-namespace llvm {
/// Returns a newly-created MachineFunction Printer pass. The
/// default banner is empty.
///
-MachineFunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS,
- const std::string &Banner){
+MachineFunctionPass *
+llvm::createMachineFunctionPrinterPass(raw_ostream &OS,
+ const std::string &Banner) {
return new MachineFunctionPrinterPass(OS, Banner);
}
-
-}
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index fdae3b4..9feb974 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -593,15 +593,12 @@ struct MachineOutliner : public ModulePass {
char MachineOutliner::ID = 0;
-namespace llvm {
-ModulePass *createMachineOutlinerPass(RunOutliner RunOutlinerMode) {
+ModulePass *llvm::createMachineOutlinerPass(RunOutliner RunOutlinerMode) {
MachineOutliner *OL = new MachineOutliner();
OL->RunOutlinerMode = RunOutlinerMode;
return OL;
}
-} // namespace llvm
-
INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false,
false)
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 89ed4da..a717d9e 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -201,16 +201,15 @@ static cl::opt<unsigned> SwpMaxNumStores(
cl::desc("Maximum number of stores allwed in the target loop."), cl::Hidden,
cl::init(200));
-namespace llvm {
-
// A command line option to enable the CopyToPhi DAG mutation.
-cl::opt<bool> SwpEnableCopyToPhi("pipeliner-enable-copytophi", cl::ReallyHidden,
- cl::init(true),
- cl::desc("Enable CopyToPhi DAG Mutation"));
+cl::opt<bool>
+ llvm::SwpEnableCopyToPhi("pipeliner-enable-copytophi", cl::ReallyHidden,
+ cl::init(true),
+ cl::desc("Enable CopyToPhi DAG Mutation"));
/// A command line argument to force pipeliner to use specified issue
/// width.
-cl::opt<int> SwpForceIssueWidth(
+cl::opt<int> llvm::SwpForceIssueWidth(
"pipeliner-force-issue-width",
cl::desc("Force pipeliner to use specified issue width."), cl::Hidden,
cl::init(-1));
@@ -226,8 +225,6 @@ static cl::opt<WindowSchedulingFlag> WindowSchedulingOption(
clEnumValN(WindowSchedulingFlag::WS_Force, "force",
"Use window algorithm instead of SMS algorithm.")));
-} // end namespace llvm
-
unsigned SwingSchedulerDAG::Circuits::MaxPaths = 5;
char MachinePipeliner::ID = 0;
#ifndef NDEBUG
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index 299bcc4..3ed1045 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -176,9 +176,7 @@ STATISTIC(NumNodeOrderPostRA,
STATISTIC(NumFirstValidPostRA,
"Number of scheduling units chosen for FirstValid heuristic post-RA");
-namespace llvm {
-
-cl::opt<MISched::Direction> PreRADirection(
+cl::opt<MISched::Direction> llvm::PreRADirection(
"misched-prera-direction", cl::Hidden,
cl::desc("Pre reg-alloc list scheduling direction"),
cl::init(MISched::Unspecified),
@@ -206,33 +204,31 @@ static cl::opt<bool>
DumpCriticalPathLength("misched-dcpl", cl::Hidden,
cl::desc("Print critical path length to stdout"));
-cl::opt<bool> VerifyScheduling(
+cl::opt<bool> llvm::VerifyScheduling(
"verify-misched", cl::Hidden,
cl::desc("Verify machine instrs before and after machine scheduling"));
#ifndef NDEBUG
-cl::opt<bool> ViewMISchedDAGs(
+cl::opt<bool> llvm::ViewMISchedDAGs(
"view-misched-dags", cl::Hidden,
cl::desc("Pop up a window to show MISched dags after they are processed"));
-cl::opt<bool> PrintDAGs("misched-print-dags", cl::Hidden,
- cl::desc("Print schedule DAGs"));
-cl::opt<bool> MISchedDumpReservedCycles(
+cl::opt<bool> llvm::PrintDAGs("misched-print-dags", cl::Hidden,
+ cl::desc("Print schedule DAGs"));
+static cl::opt<bool> MISchedDumpReservedCycles(
"misched-dump-reserved-cycles", cl::Hidden, cl::init(false),
cl::desc("Dump resource usage at schedule boundary."));
-cl::opt<bool> MischedDetailResourceBooking(
+static cl::opt<bool> MischedDetailResourceBooking(
"misched-detail-resource-booking", cl::Hidden, cl::init(false),
cl::desc("Show details of invoking getNextResoufceCycle."));
#else
-const bool ViewMISchedDAGs = false;
-const bool PrintDAGs = false;
-const bool MischedDetailResourceBooking = false;
+const bool llvm::ViewMISchedDAGs = false;
+const bool llvm::PrintDAGs = false;
+static const bool MischedDetailResourceBooking = false;
#ifdef LLVM_ENABLE_DUMP
-const bool MISchedDumpReservedCycles = false;
+static const bool MISchedDumpReservedCycles = false;
#endif // LLVM_ENABLE_DUMP
#endif // NDEBUG
-} // end namespace llvm
-
#ifndef NDEBUG
/// In some situations a few uninteresting nodes depend on nearly all other
/// nodes in the graph, provide a cutoff to hide them.
@@ -2053,28 +2049,24 @@ public:
} // end anonymous namespace
-namespace llvm {
-
std::unique_ptr<ScheduleDAGMutation>
-createLoadClusterDAGMutation(const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI,
- bool ReorderWhileClustering) {
+llvm::createLoadClusterDAGMutation(const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI,
+ bool ReorderWhileClustering) {
return EnableMemOpCluster ? std::make_unique<LoadClusterMutation>(
TII, TRI, ReorderWhileClustering)
: nullptr;
}
std::unique_ptr<ScheduleDAGMutation>
-createStoreClusterDAGMutation(const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI,
- bool ReorderWhileClustering) {
+llvm::createStoreClusterDAGMutation(const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI,
+ bool ReorderWhileClustering) {
return EnableMemOpCluster ? std::make_unique<StoreClusterMutation>(
TII, TRI, ReorderWhileClustering)
: nullptr;
}
-} // end namespace llvm
-
// Sorting all the loads/stores first, then for each load/store, checking the
// following load/store one by one, until reach the first non-dependent one and
// call target hook to see if they can cluster.
@@ -2304,16 +2296,12 @@ protected:
} // end anonymous namespace
-namespace llvm {
-
std::unique_ptr<ScheduleDAGMutation>
-createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI) {
+llvm::createCopyConstrainDAGMutation(const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI) {
return std::make_unique<CopyConstrain>(TII, TRI);
}
-} // end namespace llvm
-
/// constrainLocalCopy handles two possibilities:
/// 1) Local src:
/// I0: = dst
@@ -3445,14 +3433,13 @@ void GenericSchedulerBase::traceCandidate(const SchedCandidate &Cand) {
}
#endif
-namespace llvm {
/// Return true if this heuristic determines order.
/// TODO: Consider refactor return type of these functions as integer or enum,
/// as we may need to differentiate whether TryCand is better than Cand.
-bool tryLess(int TryVal, int CandVal,
- GenericSchedulerBase::SchedCandidate &TryCand,
- GenericSchedulerBase::SchedCandidate &Cand,
- GenericSchedulerBase::CandReason Reason) {
+bool llvm::tryLess(int TryVal, int CandVal,
+ GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ GenericSchedulerBase::CandReason Reason) {
if (TryVal < CandVal) {
TryCand.Reason = Reason;
return true;
@@ -3465,10 +3452,10 @@ bool tryLess(int TryVal, int CandVal,
return false;
}
-bool tryGreater(int TryVal, int CandVal,
- GenericSchedulerBase::SchedCandidate &TryCand,
- GenericSchedulerBase::SchedCandidate &Cand,
- GenericSchedulerBase::CandReason Reason) {
+bool llvm::tryGreater(int TryVal, int CandVal,
+ GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ GenericSchedulerBase::CandReason Reason) {
if (TryVal > CandVal) {
TryCand.Reason = Reason;
return true;
@@ -3481,9 +3468,9 @@ bool tryGreater(int TryVal, int CandVal,
return false;
}
-bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
- GenericSchedulerBase::SchedCandidate &Cand,
- SchedBoundary &Zone) {
+bool llvm::tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ SchedBoundary &Zone) {
if (Zone.isTop()) {
// Prefer the candidate with the lesser depth, but only if one of them has
// depth greater than the total latency scheduled so far, otherwise either
@@ -3513,7 +3500,6 @@ bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand,
}
return false;
}
-} // end namespace llvm
static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
bool IsPostRA = false) {
@@ -3798,14 +3784,12 @@ void GenericScheduler::registerRoots() {
}
}
-namespace llvm {
-bool tryPressure(const PressureChange &TryP,
- const PressureChange &CandP,
- GenericSchedulerBase::SchedCandidate &TryCand,
- GenericSchedulerBase::SchedCandidate &Cand,
- GenericSchedulerBase::CandReason Reason,
- const TargetRegisterInfo *TRI,
- const MachineFunction &MF) {
+bool llvm::tryPressure(const PressureChange &TryP, const PressureChange &CandP,
+ GenericSchedulerBase::SchedCandidate &TryCand,
+ GenericSchedulerBase::SchedCandidate &Cand,
+ GenericSchedulerBase::CandReason Reason,
+ const TargetRegisterInfo *TRI,
+ const MachineFunction &MF) {
// If one candidate decreases and the other increases, go with it.
// Invalid candidates have UnitInc==0.
if (tryGreater(TryP.getUnitInc() < 0, CandP.getUnitInc() < 0, TryCand, Cand,
@@ -3838,7 +3822,7 @@ bool tryPressure(const PressureChange &TryP,
return tryGreater(TryRank, CandRank, TryCand, Cand, Reason);
}
-unsigned getWeakLeft(const SUnit *SU, bool isTop) {
+unsigned llvm::getWeakLeft(const SUnit *SU, bool isTop) {
return (isTop) ? SU->WeakPredsLeft : SU->WeakSuccsLeft;
}
@@ -3849,7 +3833,7 @@ unsigned getWeakLeft(const SUnit *SU, bool isTop) {
/// copies which can be prescheduled. The rest (e.g. x86 MUL) could be bundled
/// with the operation that produces or consumes the physreg. We'll do this when
/// regalloc has support for parallel copies.
-int biasPhysReg(const SUnit *SU, bool isTop) {
+int llvm::biasPhysReg(const SUnit *SU, bool isTop) {
const MachineInstr *MI = SU->getInstr();
if (MI->isCopy()) {
@@ -3884,7 +3868,6 @@ int biasPhysReg(const SUnit *SU, bool isTop) {
return 0;
}
-} // end namespace llvm
void GenericScheduler::initCandidate(SchedCandidate &Cand, SUnit *SU,
bool AtTop,
@@ -4812,13 +4795,13 @@ static MachineSchedRegistry ShufflerRegistry(
//===----------------------------------------------------------------------===//
#ifndef NDEBUG
-namespace llvm {
-template<> struct GraphTraits<
- ScheduleDAGMI*> : public GraphTraits<ScheduleDAG*> {};
+template <>
+struct llvm::GraphTraits<ScheduleDAGMI *> : public GraphTraits<ScheduleDAG *> {
+};
-template<>
-struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits {
+template <>
+struct llvm::DOTGraphTraits<ScheduleDAGMI *> : public DefaultDOTGraphTraits {
DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
static std::string getGraphName(const ScheduleDAG *G) {
@@ -4878,7 +4861,6 @@ struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits {
}
};
-} // end namespace llvm
#endif // NDEBUG
/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
diff --git a/llvm/lib/CodeGen/MachineTraceMetrics.cpp b/llvm/lib/CodeGen/MachineTraceMetrics.cpp
index c2d4aa0..9ac3f741 100644
--- a/llvm/lib/CodeGen/MachineTraceMetrics.cpp
+++ b/llvm/lib/CodeGen/MachineTraceMetrics.cpp
@@ -485,10 +485,7 @@ struct LoopBounds {
// Specialize po_iterator_storage in order to prune the post-order traversal so
// it is limited to the current loop and doesn't traverse the loop back edges.
-namespace llvm {
-
-template<>
-class po_iterator_storage<LoopBounds, true> {
+template <> class llvm::po_iterator_storage<LoopBounds, true> {
LoopBounds &LB;
public:
@@ -519,8 +516,6 @@ public:
}
};
-} // end namespace llvm
-
/// Compute the trace through MBB.
void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
LLVM_DEBUG(dbgs() << "Computing " << getName() << " trace through "
diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
index 087ac62..59c587c 100644
--- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
+++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
@@ -9,7 +9,7 @@
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/ADT/STLExtras.h"
-namespace llvm {
+using namespace llvm;
DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) {
auto I = Strings.try_emplace(S);
@@ -43,5 +43,3 @@ NonRelocatableStringpool::getEntriesForEmission() const {
});
return Result;
}
-
-} // namespace llvm
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index 6f373a5..e9ffa85 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -76,8 +76,6 @@ using namespace llvm::safestack;
#define DEBUG_TYPE "safe-stack"
-namespace llvm {
-
STATISTIC(NumFunctions, "Total number of functions");
STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack");
STATISTIC(NumUnsafeStackRestorePointsFunctions,
@@ -89,8 +87,6 @@ STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas");
STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments");
STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads");
-} // namespace llvm
-
/// Use __safestack_pointer_address even if the platform has a faster way of
/// access safe stack pointer.
static cl::opt<bool>
diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
index eae2e8c..3268c26 100644
--- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -1551,14 +1551,10 @@ LLVM_DUMP_METHOD void ILPValue::dump() const {
dbgs() << *this << '\n';
}
-namespace llvm {
-
LLVM_ATTRIBUTE_UNUSED
-raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val) {
+raw_ostream &llvm::operator<<(raw_ostream &OS, const ILPValue &Val) {
Val.print(OS);
return OS;
}
-} // end namespace llvm
-
#endif
diff --git a/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp b/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
index e7b1494..c80eade 100644
--- a/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
+++ b/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
@@ -16,57 +16,51 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-namespace llvm {
- template<>
- struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
+template <>
+struct llvm::DOTGraphTraits<ScheduleDAG *> : public DefaultDOTGraphTraits {
- DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+ DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
- static std::string getGraphName(const ScheduleDAG *G) {
- return std::string(G->MF.getName());
- }
+ static std::string getGraphName(const ScheduleDAG *G) {
+ return std::string(G->MF.getName());
+ }
- static bool renderGraphFromBottomUp() {
- return true;
- }
+ static bool renderGraphFromBottomUp() { return true; }
- static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
- return (Node->NumPreds > 10 || Node->NumSuccs > 10);
- }
+ static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) {
+ return (Node->NumPreds > 10 || Node->NumSuccs > 10);
+ }
- static std::string getNodeIdentifierLabel(const SUnit *Node,
- const ScheduleDAG *Graph) {
- std::string R;
- raw_string_ostream OS(R);
- OS << static_cast<const void *>(Node);
- return R;
- }
+ static std::string getNodeIdentifierLabel(const SUnit *Node,
+ const ScheduleDAG *Graph) {
+ std::string R;
+ raw_string_ostream OS(R);
+ OS << static_cast<const void *>(Node);
+ return R;
+ }
- /// If you want to override the dot attributes printed for a particular
- /// edge, override this method.
- static std::string getEdgeAttributes(const SUnit *Node,
- SUnitIterator EI,
- const ScheduleDAG *Graph) {
- if (EI.isArtificialDep())
- return "color=cyan,style=dashed";
- if (EI.isCtrlDep())
- return "color=blue,style=dashed";
- return "";
- }
+ /// If you want to override the dot attributes printed for a particular
+ /// edge, override this method.
+ static std::string getEdgeAttributes(const SUnit *Node, SUnitIterator EI,
+ const ScheduleDAG *Graph) {
+ if (EI.isArtificialDep())
+ return "color=cyan,style=dashed";
+ if (EI.isCtrlDep())
+ return "color=blue,style=dashed";
+ return "";
+ }
+ std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *Graph);
+ static std::string getNodeAttributes(const SUnit *N,
+ const ScheduleDAG *Graph) {
+ return "shape=Mrecord";
+ }
- std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *Graph);
- static std::string getNodeAttributes(const SUnit *N,
- const ScheduleDAG *Graph) {
- return "shape=Mrecord";
- }
-
- static void addCustomGraphFeatures(ScheduleDAG *G,
- GraphWriter<ScheduleDAG*> &GW) {
- return G->addCustomGraphFeatures(GW);
- }
- };
-}
+ static void addCustomGraphFeatures(ScheduleDAG *G,
+ GraphWriter<ScheduleDAG *> &GW) {
+ return G->addCustomGraphFeatures(GW);
+ }
+};
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b1accdd..e153842 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -509,6 +509,7 @@ namespace {
SDValue visitFMUL(SDNode *N);
template <class MatchContextClass> SDValue visitFMA(SDNode *N);
SDValue visitFMAD(SDNode *N);
+ SDValue visitFMULADD(SDNode *N);
SDValue visitFDIV(SDNode *N);
SDValue visitFREM(SDNode *N);
SDValue visitFSQRT(SDNode *N);
@@ -1991,6 +1992,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::FMUL: return visitFMUL(N);
case ISD::FMA: return visitFMA<EmptyMatchContext>(N);
case ISD::FMAD: return visitFMAD(N);
+ case ISD::FMULADD: return visitFMULADD(N);
case ISD::FDIV: return visitFDIV(N);
case ISD::FREM: return visitFREM(N);
case ISD::FSQRT: return visitFSQRT(N);
@@ -18444,6 +18446,21 @@ SDValue DAGCombiner::visitFMAD(SDNode *N) {
return SDValue();
}
+SDValue DAGCombiner::visitFMULADD(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ EVT VT = N->getValueType(0);
+ SDLoc DL(N);
+
+ // Constant fold FMULADD.
+ if (SDValue C =
+ DAG.FoldConstantArithmetic(ISD::FMULADD, DL, VT, {N0, N1, N2}))
+ return C;
+
+ return SDValue();
+}
+
// Combine multiple FDIVs with the same divisor into multiple FMULs by the
// reciprocal.
// E.g., (a / D; b / D;) -> (recip = 1.0 / D; a * recip; b * recip)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2b8dd60..4512c5c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5786,6 +5786,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::FCOPYSIGN:
case ISD::FMA:
case ISD::FMAD:
+ case ISD::FMULADD:
case ISD::FP_EXTEND:
case ISD::FP_TO_SINT_SAT:
case ISD::FP_TO_UINT_SAT:
@@ -5904,6 +5905,7 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts,
case ISD::FCOSH:
case ISD::FTANH:
case ISD::FMA:
+ case ISD::FMULADD:
case ISD::FMAD: {
if (SNaN)
return true;
@@ -7231,7 +7233,7 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
}
// Handle fma/fmad special cases.
- if (Opcode == ISD::FMA || Opcode == ISD::FMAD) {
+ if (Opcode == ISD::FMA || Opcode == ISD::FMAD || Opcode == ISD::FMULADD) {
assert(VT.isFloatingPoint() && "This operator only applies to FP types!");
assert(Ops[0].getValueType() == VT && Ops[1].getValueType() == VT &&
Ops[2].getValueType() == VT && "FMA types must match!");
@@ -7242,7 +7244,7 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
APFloat V1 = C1->getValueAPF();
const APFloat &V2 = C2->getValueAPF();
const APFloat &V3 = C3->getValueAPF();
- if (Opcode == ISD::FMAD) {
+ if (Opcode == ISD::FMAD || Opcode == ISD::FMULADD) {
V1.multiply(V2, APFloat::rmNearestTiesToEven);
V1.add(V3, APFloat::rmNearestTiesToEven);
} else
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index c21890a..0f2b518 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6996,6 +6996,13 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
getValue(I.getArgOperand(0)),
getValue(I.getArgOperand(1)),
getValue(I.getArgOperand(2)), Flags));
+ } else if (TLI.isOperationLegalOrCustom(ISD::FMULADD, VT)) {
+ // TODO: Support splitting the vector.
+ setValue(&I, DAG.getNode(ISD::FMULADD, sdl,
+ getValue(I.getArgOperand(0)).getValueType(),
+ getValue(I.getArgOperand(0)),
+ getValue(I.getArgOperand(1)),
+ getValue(I.getArgOperand(2)), Flags));
} else {
// TODO: Intrinsic calls should have fast-math-flags.
SDValue Mul = DAG.getNode(
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index fcfbfe6..39cbfad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -310,6 +310,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::FMA: return "fma";
case ISD::STRICT_FMA: return "strict_fma";
case ISD::FMAD: return "fmad";
+ case ISD::FMULADD: return "fmuladd";
case ISD::FREM: return "frem";
case ISD::STRICT_FREM: return "strict_frem";
case ISD::FCOPYSIGN: return "fcopysign";
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index cc503d3..920dff9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7676,6 +7676,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
break;
}
case ISD::FMA:
+ case ISD::FMULADD:
case ISD::FMAD: {
if (!Flags.hasNoSignedZeros())
break;
diff --git a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp
index 64e5cd5..95a9c3f 100644
--- a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp
+++ b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp
@@ -306,10 +306,7 @@ char &llvm::StackFrameLayoutAnalysisPassID = StackFrameLayoutAnalysisLegacy::ID;
INITIALIZE_PASS(StackFrameLayoutAnalysisLegacy, "stack-frame-layout",
"Stack Frame Layout", false, false)
-namespace llvm {
/// Returns a newly-created StackFrameLayout pass.
-MachineFunctionPass *createStackFrameLayoutAnalysisPass() {
+MachineFunctionPass *llvm::createStackFrameLayoutAnalysisPass() {
return new StackFrameLayoutAnalysisLegacy();
}
-
-} // namespace llvm
diff --git a/llvm/lib/CodeGen/StaticDataAnnotator.cpp b/llvm/lib/CodeGen/StaticDataAnnotator.cpp
index 53a9ab4..eac20120 100644
--- a/llvm/lib/CodeGen/StaticDataAnnotator.cpp
+++ b/llvm/lib/CodeGen/StaticDataAnnotator.cpp
@@ -75,22 +75,11 @@ bool StaticDataAnnotator::runOnModule(Module &M) {
bool Changed = false;
for (auto &GV : M.globals()) {
- if (GV.isDeclarationForLinker())
+ if (!llvm::memprof::IsAnnotationOK(GV))
continue;
- // The implementation below assumes prior passes don't set section prefixes,
- // and specifically do 'assign' rather than 'update'. So report error if a
- // section prefix is already set.
- if (auto maybeSectionPrefix = GV.getSectionPrefix();
- maybeSectionPrefix && !maybeSectionPrefix->empty())
- llvm::report_fatal_error("Global variable " + GV.getName() +
- " already has a section prefix " +
- *maybeSectionPrefix);
-
StringRef SectionPrefix = SDPI->getConstantSectionPrefix(&GV, PSI);
- if (SectionPrefix.empty())
- continue;
-
+ // setSectionPrefix returns true if the section prefix is updated.
Changed |= GV.setSectionPrefix(SectionPrefix);
}
diff --git a/llvm/lib/CodeGen/StaticDataSplitter.cpp b/llvm/lib/CodeGen/StaticDataSplitter.cpp
index e22dc25..1593a40 100644
--- a/llvm/lib/CodeGen/StaticDataSplitter.cpp
+++ b/llvm/lib/CodeGen/StaticDataSplitter.cpp
@@ -130,10 +130,8 @@ StaticDataSplitter::getConstant(const MachineOperand &Op,
if (Op.isGlobal()) {
// Find global variables with local linkage.
const GlobalVariable *GV = getLocalLinkageGlobalVariable(Op.getGlobal());
- // Skip 'llvm.'-prefixed global variables conservatively because they are
- // often handled specially, and skip those not in static data
- // sections.
- if (!GV || GV->getName().starts_with("llvm.") ||
+ // Skip those not eligible for annotation or not in static data sections.
+ if (!GV || !llvm::memprof::IsAnnotationOK(*GV) ||
!inStaticDataSection(*GV, TM))
return nullptr;
return GV;
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index c23281a..060b1dd 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -815,7 +815,8 @@ void TargetLoweringBase::initActions() {
ISD::FTAN, ISD::FACOS,
ISD::FASIN, ISD::FATAN,
ISD::FCOSH, ISD::FSINH,
- ISD::FTANH, ISD::FATAN2},
+ ISD::FTANH, ISD::FATAN2,
+ ISD::FMULADD},
VT, Expand);
// Overflow operations default to expand
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index c9e4618..971f822 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -102,10 +102,8 @@ bool TargetRegisterInfo::checkAllSuperRegsMarked(const BitVector &RegisterSet,
return true;
}
-namespace llvm {
-
-Printable printReg(Register Reg, const TargetRegisterInfo *TRI,
- unsigned SubIdx, const MachineRegisterInfo *MRI) {
+Printable llvm::printReg(Register Reg, const TargetRegisterInfo *TRI,
+ unsigned SubIdx, const MachineRegisterInfo *MRI) {
return Printable([Reg, TRI, SubIdx, MRI](raw_ostream &OS) {
if (!Reg)
OS << "$noreg";
@@ -135,7 +133,7 @@ Printable printReg(Register Reg, const TargetRegisterInfo *TRI,
});
}
-Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
+Printable llvm::printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
return Printable([Unit, TRI](raw_ostream &OS) {
// Generic printout when TRI is missing.
if (!TRI) {
@@ -158,7 +156,7 @@ Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
});
}
-Printable printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
+Printable llvm::printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
return Printable([Unit, TRI](raw_ostream &OS) {
if (Register::isVirtualRegister(Unit)) {
OS << '%' << Register(Unit).virtRegIndex();
@@ -168,8 +166,9 @@ Printable printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
});
}
-Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo,
- const TargetRegisterInfo *TRI) {
+Printable llvm::printRegClassOrBank(Register Reg,
+ const MachineRegisterInfo &RegInfo,
+ const TargetRegisterInfo *TRI) {
return Printable([Reg, &RegInfo, TRI](raw_ostream &OS) {
if (RegInfo.getRegClassOrNull(Reg))
OS << StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
@@ -183,8 +182,6 @@ Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo,
});
}
-} // end namespace llvm
-
/// getAllocatableClass - Return the maximal subclass of the given register
/// class that is alloctable, or NULL.
const TargetRegisterClass *
diff --git a/llvm/lib/IR/ConstantFPRange.cpp b/llvm/lib/IR/ConstantFPRange.cpp
index e9c058e..5b87686 100644
--- a/llvm/lib/IR/ConstantFPRange.cpp
+++ b/llvm/lib/IR/ConstantFPRange.cpp
@@ -528,3 +528,147 @@ void ConstantFPRange::flushDenormals(DenormalMode::DenormalModeKind Mode) {
Lower = minnum(Lower, APFloat::getZero(Sem, ZeroLowerNegative));
Upper = maxnum(Upper, APFloat::getZero(Sem, ZeroUpperNegative));
}
+
+/// Represent a contiguous range of values sharing the same sign.
+struct SameSignRange {
+ bool HasZero;
+ bool HasNonZero;
+ bool HasInf;
+ // The lower and upper bounds of the range (inclusive).
+ // The sign is dropped and infinities are excluded.
+ std::optional<std::pair<APFloat, APFloat>> FinitePart;
+
+ explicit SameSignRange(const APFloat &Lower, const APFloat &Upper)
+ : HasZero(Lower.isZero()), HasNonZero(!Upper.isZero()),
+ HasInf(Upper.isInfinity()) {
+ assert(!Lower.isNegative() && !Upper.isNegative() &&
+ "The sign should be dropped.");
+ assert(strictCompare(Lower, Upper) != APFloat::cmpGreaterThan &&
+ "Empty set.");
+ if (!Lower.isInfinity())
+ FinitePart = {Lower,
+ HasInf ? APFloat::getLargest(Lower.getSemantics()) : Upper};
+ }
+};
+
+/// Split the range into positive and negative components.
+static void splitPosNeg(const APFloat &Lower, const APFloat &Upper,
+ std::optional<SameSignRange> &NegPart,
+ std::optional<SameSignRange> &PosPart) {
+ assert(strictCompare(Lower, Upper) != APFloat::cmpGreaterThan &&
+ "Non-NaN part is empty.");
+ if (Lower.isNegative() == Upper.isNegative()) {
+ if (Lower.isNegative())
+ NegPart = SameSignRange{abs(Upper), abs(Lower)};
+ else
+ PosPart = SameSignRange{Lower, Upper};
+ return;
+ }
+ auto &Sem = Lower.getSemantics();
+ NegPart = SameSignRange{APFloat::getZero(Sem), abs(Lower)};
+ PosPart = SameSignRange{APFloat::getZero(Sem), Upper};
+}
+
+ConstantFPRange ConstantFPRange::mul(const ConstantFPRange &Other) const {
+ auto &Sem = getSemantics();
+ bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !Other.isEmptySet()) ||
+ ((Other.MayBeQNaN || Other.MayBeSNaN) && !isEmptySet());
+ if (isNaNOnly() || Other.isNaNOnly())
+ return getNaNOnly(Sem, /*MayBeQNaN=*/ResMayBeQNaN,
+ /*MayBeSNaN=*/false);
+ std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos;
+ splitPosNeg(Lower, Upper, LHSNeg, LHSPos);
+ splitPosNeg(Other.Lower, Other.Upper, RHSNeg, RHSPos);
+ APFloat ResLower = APFloat::getInf(Sem, /*Negative=*/false);
+ APFloat ResUpper = APFloat::getInf(Sem, /*Negative=*/true);
+ auto Update = [&](std::optional<SameSignRange> &LHS,
+ std::optional<SameSignRange> &RHS, bool Negative) {
+ if (!LHS || !RHS)
+ return;
+ // 0 * inf = QNaN
+ ResMayBeQNaN |= LHS->HasZero && RHS->HasInf;
+ ResMayBeQNaN |= RHS->HasZero && LHS->HasInf;
+ // NonZero * inf = inf
+ if ((LHS->HasInf && RHS->HasNonZero) || (RHS->HasInf && LHS->HasNonZero))
+ (Negative ? ResLower : ResUpper) = APFloat::getInf(Sem, Negative);
+ // Finite * Finite
+ if (LHS->FinitePart && RHS->FinitePart) {
+ APFloat NewLower = LHS->FinitePart->first * RHS->FinitePart->first;
+ APFloat NewUpper = LHS->FinitePart->second * RHS->FinitePart->second;
+ if (Negative) {
+ ResLower = minnum(ResLower, -NewUpper);
+ ResUpper = maxnum(ResUpper, -NewLower);
+ } else {
+ ResLower = minnum(ResLower, NewLower);
+ ResUpper = maxnum(ResUpper, NewUpper);
+ }
+ }
+ };
+ Update(LHSNeg, RHSNeg, /*Negative=*/false);
+ Update(LHSNeg, RHSPos, /*Negative=*/true);
+ Update(LHSPos, RHSNeg, /*Negative=*/true);
+ Update(LHSPos, RHSPos, /*Negative=*/false);
+ return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, /*MayBeSNaN=*/false);
+}
+
+ConstantFPRange ConstantFPRange::div(const ConstantFPRange &Other) const {
+ auto &Sem = getSemantics();
+ bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !Other.isEmptySet()) ||
+ ((Other.MayBeQNaN || Other.MayBeSNaN) && !isEmptySet());
+ if (isNaNOnly() || Other.isNaNOnly())
+ return getNaNOnly(Sem, /*MayBeQNaN=*/ResMayBeQNaN,
+ /*MayBeSNaN=*/false);
+ std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos;
+ splitPosNeg(Lower, Upper, LHSNeg, LHSPos);
+ splitPosNeg(Other.Lower, Other.Upper, RHSNeg, RHSPos);
+ APFloat ResLower = APFloat::getInf(Sem, /*Negative=*/false);
+ APFloat ResUpper = APFloat::getInf(Sem, /*Negative=*/true);
+ auto Update = [&](std::optional<SameSignRange> &LHS,
+ std::optional<SameSignRange> &RHS, bool Negative) {
+ if (!LHS || !RHS)
+ return;
+ // inf / inf = QNaN 0 / 0 = QNaN
+ ResMayBeQNaN |= LHS->HasInf && RHS->HasInf;
+ ResMayBeQNaN |= LHS->HasZero && RHS->HasZero;
+ // It is not straightforward to infer HasNonZeroFinite = HasFinite &&
+ // HasNonZero. By definitions we have:
+ // HasFinite = HasNonZeroFinite || HasZero
+ // HasNonZero = HasNonZeroFinite || HasInf
+ // Since the range is contiguous, if both HasFinite and HasNonZero are true,
+ // HasNonZeroFinite must be true.
+ bool LHSHasNonZeroFinite = LHS->FinitePart && LHS->HasNonZero;
+ bool RHSHasNonZeroFinite = RHS->FinitePart && RHS->HasNonZero;
+ // inf / Finite = inf FiniteNonZero / 0 = inf
+ if ((LHS->HasInf && RHS->FinitePart) ||
+ (LHSHasNonZeroFinite && RHS->HasZero))
+ (Negative ? ResLower : ResUpper) = APFloat::getInf(Sem, Negative);
+ // Finite / inf = 0
+ if (LHS->FinitePart && RHS->HasInf) {
+ APFloat Zero = APFloat::getZero(Sem, /*Negative=*/Negative);
+ ResLower = minnum(ResLower, Zero);
+ ResUpper = maxnum(ResUpper, Zero);
+ }
+ // Finite / FiniteNonZero
+ if (LHS->FinitePart && RHSHasNonZeroFinite) {
+ assert(!RHS->FinitePart->second.isZero() &&
+ "Divisor should be non-zero.");
+ APFloat NewLower = LHS->FinitePart->first / RHS->FinitePart->second;
+ APFloat NewUpper = LHS->FinitePart->second /
+ (RHS->FinitePart->first.isZero()
+ ? APFloat::getSmallest(Sem, /*Negative=*/false)
+ : RHS->FinitePart->first);
+ if (Negative) {
+ ResLower = minnum(ResLower, -NewUpper);
+ ResUpper = maxnum(ResUpper, -NewLower);
+ } else {
+ ResLower = minnum(ResLower, NewLower);
+ ResUpper = maxnum(ResUpper, NewUpper);
+ }
+ }
+ };
+ Update(LHSNeg, RHSNeg, /*Negative=*/false);
+ Update(LHSNeg, RHSPos, /*Negative=*/true);
+ Update(LHSPos, RHSNeg, /*Negative=*/true);
+ Update(LHSPos, RHSPos, /*Negative=*/false);
+ return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, /*MayBeSNaN=*/false);
+}
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 614c3a9..15c0198 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -25,6 +25,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
@@ -1002,6 +1003,18 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall(
return C;
}
+Value *IRBuilderBase::CreateSelectWithUnknownProfile(Value *C, Value *True,
+ Value *False,
+ StringRef PassName,
+ const Twine &Name) {
+ Value *Ret = CreateSelectFMF(C, True, False, {}, Name);
+ if (auto *SI = dyn_cast<SelectInst>(Ret)) {
+ setExplicitlyUnknownBranchWeightsIfProfiled(
+ *SI, *SI->getParent()->getParent(), PassName);
+ }
+ return Ret;
+}
+
Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
const Twine &Name, Instruction *MDFrom) {
return CreateSelectFMF(C, True, False, {}, Name, MDFrom);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 2ea3a24..afce803 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1363,9 +1363,12 @@ const Init *BinOpInit::Fold(const Record *CurRec) const {
}
case LISTSPLAT: {
const auto *Value = dyn_cast<TypedInit>(LHS);
- const auto *Size = dyn_cast<IntInit>(RHS);
- if (Value && Size) {
- SmallVector<const Init *, 8> Args(Size->getValue(), Value);
+ const auto *Count = dyn_cast<IntInit>(RHS);
+ if (Value && Count) {
+ if (Count->getValue() < 0)
+ PrintFatalError(Twine("!listsplat count ") + Count->getAsString() +
+ " is negative");
+ SmallVector<const Init *, 8> Args(Count->getValue(), Value);
return ListInit::get(Args, Value->getType());
}
break;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
index dbe74b1..5700468 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
@@ -2394,15 +2394,19 @@ bool SchedGroup::canAddMI(const MachineInstr &MI) const {
else if (((SGMask & SchedGroupMask::ALU) != SchedGroupMask::NONE) &&
(TII->isVALU(MI) || TII->isMFMAorWMMA(MI) || TII->isSALU(MI) ||
TII->isTRANS(MI)))
- Result = true;
+ Result = !MI.mayLoadOrStore();
else if (((SGMask & SchedGroupMask::VALU) != SchedGroupMask::NONE) &&
- TII->isVALU(MI) && !TII->isMFMAorWMMA(MI) && !TII->isTRANS(MI))
- Result = true;
+ TII->isVALU(MI) && !TII->isMFMAorWMMA(MI) && !TII->isTRANS(MI)) {
+ // Some memory instructions may be marked as VALU (e.g. BUFFER_LOAD_*_LDS).
+ // For our purposes, these shall not be classified as VALU as this results
+ // in unexpected behavior.
+ Result = !MI.mayLoadOrStore();
+ }
else if (((SGMask & SchedGroupMask::SALU) != SchedGroupMask::NONE) &&
TII->isSALU(MI))
- Result = true;
+ Result = !MI.mayLoadOrStore();
else if (((SGMask & SchedGroupMask::MFMA) != SchedGroupMask::NONE) &&
TII->isMFMAorWMMA(MI))
diff --git a/llvm/lib/Target/AMDGPU/MIMGInstructions.td b/llvm/lib/Target/AMDGPU/MIMGInstructions.td
index 64e34db..5f6d742 100644
--- a/llvm/lib/Target/AMDGPU/MIMGInstructions.td
+++ b/llvm/lib/Target/AMDGPU/MIMGInstructions.td
@@ -260,8 +260,12 @@ class NSAHelper {
}
class MIMGNSAHelper<int num_addrs,
- list<RegisterClass> addr_types=!listsplat(VGPR_32, num_addrs)>
- : NSAHelper<> {
+ list<RegisterOperand> addr_types_in=[]>
+ : NSAHelper<> {
+ list<RegisterOperand> addr_types =
+ !if(!empty(addr_types_in), !listsplat(VGPROp_32, num_addrs),
+ addr_types_in);
+
list<string> AddrAsmNames = !foreach(i, !range(num_addrs), "vaddr" # i);
let AddrIns = !dag(ins, addr_types, AddrAsmNames);
let AddrAsm = "[$" # !interleave(AddrAsmNames, ", $") # "]";
@@ -358,7 +362,7 @@ class MIMG_gfx11<int op, dag outs, string dns = "">
// Base class for all NSA MIMG instructions.
// Note that 1-dword addresses always use non-NSA variants.
class MIMG_nsa_gfx11<int op, dag outs, int num_addrs, string dns="",
- list<RegisterClass> addr_types=[],
+ list<RegisterOperand> addr_types=[],
RegisterOperand LastAddrRC = VGPROp_32>
: MIMG<outs, dns>, MIMGe_gfx11<op> {
let SubtargetPredicate = isGFX11Only;
@@ -378,7 +382,7 @@ class MIMG_nsa_gfx11<int op, dag outs, int num_addrs, string dns="",
}
class VIMAGE_gfx12<int op, dag outs, int num_addrs, string dns="",
- list<RegisterClass> addr_types=[]>
+ list<RegisterOperand> addr_types=[]>
: VIMAGE<outs, dns>, VIMAGEe<op> {
let SubtargetPredicate = isGFX12Plus;
let AssemblerPredicate = isGFX12Plus;
@@ -1521,12 +1525,12 @@ class MIMG_IntersectRay_Helper<bit Is64, bit IsA16, bit isDual, bit isBVH8> {
int VAddrDwords = !srl(Size, 5);
int GFX11PlusNSAAddrs = !if(IsA16, 4, 5);
- RegisterClass node_ptr_type = !if(Is64, VReg_64, VGPR_32);
- list<RegisterClass> GFX11PlusAddrTypes =
- !cond(isBVH8 : [node_ptr_type, VReg_64, VReg_96, VReg_96, VGPR_32],
- isDual : [node_ptr_type, VReg_64, VReg_96, VReg_96, VReg_64],
- IsA16 : [node_ptr_type, VGPR_32, VReg_96, VReg_96],
- true : [node_ptr_type, VGPR_32, VReg_96, VReg_96, VReg_96]);
+ RegisterOperand node_ptr_type = !if(Is64, VGPROp_64, VGPROp_32);
+ list<RegisterOperand> GFX11PlusAddrTypes =
+ !cond(isBVH8 : [node_ptr_type, VGPROp_64, VGPROp_96, VGPROp_96, VGPROp_32],
+ isDual : [node_ptr_type, VGPROp_64, VGPROp_96, VGPROp_96, VGPROp_64],
+ IsA16 : [node_ptr_type, VGPROp_32, VGPROp_96, VGPROp_96],
+ true : [node_ptr_type, VGPROp_32, VGPROp_96, VGPROp_96, VGPROp_96]);
}
class MIMG_IntersectRay_gfx10<mimgopc op, string opcode, RegisterOperand AddrRC>
@@ -1552,7 +1556,7 @@ class MIMG_IntersectRay_gfx11<mimgopc op, string opcode, RegisterOperand AddrRC>
}
class MIMG_IntersectRay_nsa_gfx11<mimgopc op, string opcode, int num_addrs,
- list<RegisterClass> addr_types>
+ list<RegisterOperand> addr_types>
: MIMG_nsa_gfx11<op.GFX11, (outs VReg_128:$vdata), num_addrs, "GFX11",
addr_types> {
let InOperandList = !con(nsah.AddrIns, (ins SReg_128_XNULL:$srsrc, A16:$a16));
@@ -1561,7 +1565,7 @@ class MIMG_IntersectRay_nsa_gfx11<mimgopc op, string opcode, int num_addrs,
class VIMAGE_IntersectRay_gfx12<mimgopc op, string opcode, int num_addrs,
bit isDual, bit isBVH8,
- list<RegisterClass> addr_types>
+ list<RegisterOperand> addr_types>
: VIMAGE_gfx12<op.GFX12, !if(!or(isDual, isBVH8),
(outs VReg_320:$vdata, VReg_96:$ray_origin_out,
VReg_96:$ray_dir_out),
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 4b54231..8851a0f 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1659,6 +1659,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -1, (1 << 5) - 1,
"immediate must be non-zero in the range");
+ case Match_InvalidXSfmmVType: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return generateXSfmmVTypeError(ErrorLoc);
+ }
case Match_InvalidVTypeI: {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
return generateVTypeError(ErrorLoc);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 70b7c43..e75dfe3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -142,6 +142,22 @@ enum {
ReadsPastVLShift = DestEEWShift + 2,
ReadsPastVLMask = 1ULL << ReadsPastVLShift,
+
+ // 0 -> Don't care about altfmt bit in VTYPE.
+ // 1 -> Is not altfmt.
+ // 2 -> Is altfmt(BF16).
+ AltFmtTypeShift = ReadsPastVLShift + 1,
+ AltFmtTypeMask = 3ULL << AltFmtTypeShift,
+
+ // XSfmmbase
+ HasTWidenOpShift = AltFmtTypeShift + 2,
+ HasTWidenOpMask = 1ULL << HasTWidenOpShift,
+
+ HasTMOpShift = HasTWidenOpShift + 1,
+ HasTMOpMask = 1ULL << HasTMOpShift,
+
+ HasTKOpShift = HasTMOpShift + 1,
+ HasTKOpMask = 1ULL << HasTKOpShift,
};
// Helper functions to read TSFlags.
@@ -183,6 +199,11 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) {
return TSFlags & HasRoundModeOpMask;
}
+enum class AltFmtType { DontCare, NotAltFmt, AltFmt };
+static inline AltFmtType getAltFmtType(uint64_t TSFlags) {
+ return static_cast<AltFmtType>((TSFlags & AltFmtTypeMask) >> AltFmtTypeShift);
+}
+
/// \returns true if this instruction uses vxrm
static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; }
@@ -204,11 +225,47 @@ static inline bool readsPastVL(uint64_t TSFlags) {
return TSFlags & ReadsPastVLMask;
}
+// XSfmmbase
+static inline bool hasTWidenOp(uint64_t TSFlags) {
+ return TSFlags & HasTWidenOpMask;
+}
+
+static inline bool hasTMOp(uint64_t TSFlags) { return TSFlags & HasTMOpMask; }
+
+static inline bool hasTKOp(uint64_t TSFlags) { return TSFlags & HasTKOpMask; }
+
+static inline unsigned getTNOpNum(const MCInstrDesc &Desc) {
+ const uint64_t TSFlags = Desc.TSFlags;
+ assert(hasTWidenOp(TSFlags) && hasVLOp(TSFlags));
+ unsigned Offset = 3;
+ if (hasTKOp(TSFlags))
+ Offset = 4;
+ return Desc.getNumOperands() - Offset;
+}
+
+static inline unsigned getTMOpNum(const MCInstrDesc &Desc) {
+ const uint64_t TSFlags = Desc.TSFlags;
+ assert(hasTWidenOp(TSFlags) && hasTMOp(TSFlags));
+ if (hasTKOp(TSFlags))
+ return Desc.getNumOperands() - 5;
+ // vtzero.t
+ return Desc.getNumOperands() - 4;
+}
+
+static inline unsigned getTKOpNum(const MCInstrDesc &Desc) {
+ [[maybe_unused]] const uint64_t TSFlags = Desc.TSFlags;
+ assert(hasTWidenOp(TSFlags) && hasTKOp(TSFlags));
+ return Desc.getNumOperands() - 3;
+}
+
static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
const uint64_t TSFlags = Desc.TSFlags;
// This method is only called if we expect to have a VL operand, and all
// instructions with VL also have SEW.
assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags));
+ // In Xsfmmbase, TN is an alias for VL, so here we use the same TSFlags bit.
+ if (hasTWidenOp(TSFlags))
+ return getTNOpNum(Desc);
unsigned Offset = 2;
if (hasVecPolicyOp(TSFlags))
Offset = 3;
@@ -226,7 +283,7 @@ static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
const uint64_t TSFlags = Desc.TSFlags;
assert(hasSEWOp(TSFlags));
unsigned Offset = 1;
- if (hasVecPolicyOp(TSFlags))
+ if (hasVecPolicyOp(TSFlags) || hasTWidenOp(TSFlags))
Offset = 2;
return Desc.getNumOperands() - Offset;
}
@@ -243,6 +300,9 @@ static inline int getFRMOpNum(const MCInstrDesc &Desc) {
if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags))
return -1;
+ if (hasTWidenOp(TSFlags) && hasTMOp(TSFlags))
+ return getTMOpNum(Desc) - 1;
+
// The operand order
// --------------------------------------
// | n-1 (if any) | n-2 | n-3 | n-4 |
@@ -385,7 +445,9 @@ enum OperandType : unsigned {
OPERAND_SEW_MASK,
// Vector rounding mode for VXRM or FRM.
OPERAND_VEC_RM,
- OPERAND_LAST_RISCV_IMM = OPERAND_VEC_RM,
+ // Vtype operand for XSfmm extension.
+ OPERAND_XSFMM_VTYPE,
+ OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_VTYPE,
// Operand is either a register or uimm5, this is used by V extension pseudo
// instructions to represent a value that be passed as AVL to either vsetvli
// or vsetivli.
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index cf8d120..9ed3b97 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -168,10 +168,13 @@ struct DemandedFields {
// If this is true, we demand that VTYPE is set to some legal state, i.e. that
// vill is unset.
bool VILL = false;
+ bool UseTWiden = false;
+ bool UseAltFmt = false;
// Return true if any part of VTYPE was used
bool usedVTYPE() const {
- return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL;
+ return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL ||
+ UseTWiden || UseAltFmt;
}
// Return true if any property of VL was used
@@ -187,6 +190,8 @@ struct DemandedFields {
TailPolicy = true;
MaskPolicy = true;
VILL = true;
+ UseTWiden = true;
+ UseAltFmt = true;
}
// Mark all VL properties as demanded
@@ -212,6 +217,8 @@ struct DemandedFields {
TailPolicy |= B.TailPolicy;
MaskPolicy |= B.MaskPolicy;
VILL |= B.VILL;
+ UseAltFmt |= B.UseAltFmt;
+ UseTWiden |= B.UseTWiden;
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -258,7 +265,9 @@ struct DemandedFields {
OS << "SEWLMULRatio=" << SEWLMULRatio << ", ";
OS << "TailPolicy=" << TailPolicy << ", ";
OS << "MaskPolicy=" << MaskPolicy << ", ";
- OS << "VILL=" << VILL;
+ OS << "VILL=" << VILL << ", ";
+ OS << "UseAltFmt=" << UseAltFmt << ", ";
+ OS << "UseTWiden=" << UseTWiden;
OS << "}";
}
#endif
@@ -328,6 +337,15 @@ static bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType,
if (Used.MaskPolicy && RISCVVType::isMaskAgnostic(CurVType) !=
RISCVVType::isMaskAgnostic(NewVType))
return false;
+ if (Used.UseTWiden && (RISCVVType::hasXSfmmWiden(CurVType) !=
+ RISCVVType::hasXSfmmWiden(NewVType) ||
+ (RISCVVType::hasXSfmmWiden(CurVType) &&
+ RISCVVType::getXSfmmWiden(CurVType) !=
+ RISCVVType::getXSfmmWiden(NewVType))))
+ return false;
+ if (Used.UseAltFmt &&
+ RISCVVType::isAltFmt(CurVType) != RISCVVType::isAltFmt(NewVType))
+ return false;
return true;
}
@@ -479,6 +497,11 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
Res.TailPolicy = false;
}
+ Res.UseAltFmt = RISCVII::getAltFmtType(MI.getDesc().TSFlags) !=
+ RISCVII::AltFmtType::DontCare;
+ Res.UseTWiden = RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
+ RISCVInstrInfo::isXSfmmVectorConfigInstr(MI);
+
return Res;
}
@@ -510,6 +533,8 @@ class VSETVLIInfo {
uint8_t TailAgnostic : 1;
uint8_t MaskAgnostic : 1;
uint8_t SEWLMULRatioOnly : 1;
+ uint8_t AltFmt : 1;
+ uint8_t TWiden : 3;
public:
VSETVLIInfo()
@@ -586,6 +611,8 @@ public:
RISCVVType::VLMUL getVLMUL() const { return VLMul; }
bool getTailAgnostic() const { return TailAgnostic; }
bool getMaskAgnostic() const { return MaskAgnostic; }
+ bool getAltFmt() const { return AltFmt; }
+ unsigned getTWiden() const { return TWiden; }
bool hasNonZeroAVL(const LiveIntervals *LIS) const {
if (hasAVLImm())
@@ -647,21 +674,31 @@ public:
SEW = RISCVVType::getSEW(VType);
TailAgnostic = RISCVVType::isTailAgnostic(VType);
MaskAgnostic = RISCVVType::isMaskAgnostic(VType);
+ AltFmt = RISCVVType::isAltFmt(VType);
+ TWiden =
+ RISCVVType::hasXSfmmWiden(VType) ? RISCVVType::getXSfmmWiden(VType) : 0;
}
- void setVTYPE(RISCVVType::VLMUL L, unsigned S, bool TA, bool MA) {
+ void setVTYPE(RISCVVType::VLMUL L, unsigned S, bool TA, bool MA, bool Altfmt,
+ unsigned W) {
assert(isValid() && !isUnknown() &&
"Can't set VTYPE for uninitialized or unknown");
VLMul = L;
SEW = S;
TailAgnostic = TA;
MaskAgnostic = MA;
+ AltFmt = Altfmt;
+ TWiden = W;
}
+ void setAltFmt(bool AF) { AltFmt = AF; }
+
void setVLMul(RISCVVType::VLMUL VLMul) { this->VLMul = VLMul; }
unsigned encodeVTYPE() const {
assert(isValid() && !isUnknown() && !SEWLMULRatioOnly &&
"Can't encode VTYPE for uninitialized or unknown");
+ if (TWiden != 0)
+ return RISCVVType::encodeXSfmmVType(SEW, TWiden, AltFmt);
return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic);
}
@@ -674,9 +711,9 @@ public:
"Can't compare VTYPE in unknown state");
assert(!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly &&
"Can't compare when only LMUL/SEW ratio is valid.");
- return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) ==
+ return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden) ==
std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic,
- Other.MaskAgnostic);
+ Other.MaskAgnostic, Other.AltFmt, Other.TWiden);
}
unsigned getSEWLMULRatio() const {
@@ -825,7 +862,9 @@ public:
<< "SEW=e" << (unsigned)SEW << ", "
<< "TailAgnostic=" << (bool)TailAgnostic << ", "
<< "MaskAgnostic=" << (bool)MaskAgnostic << ", "
- << "SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly << "}";
+ << "SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly << ", "
+ << "TWiden=" << (unsigned)TWiden << ", "
+ << "AltFmt=" << (bool)AltFmt << "}";
}
#endif
};
@@ -853,6 +892,11 @@ struct BlockData {
BlockData() = default;
};
+enum TKTMMode {
+ VSETTK = 0,
+ VSETTM = 1,
+};
+
class RISCVInsertVSETVLI : public MachineFunctionPass {
const RISCVSubtarget *ST;
const TargetInstrInfo *TII;
@@ -908,6 +952,7 @@ private:
VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) const;
VSETVLIInfo computeInfoForInstr(const MachineInstr &MI) const;
void forwardVSETVLIAVL(VSETVLIInfo &Info) const;
+ bool insertVSETMTK(MachineBasicBlock &MBB, TKTMMode Mode) const;
};
} // end anonymous namespace
@@ -945,6 +990,18 @@ RISCVInsertVSETVLI::getInfoForVSETVLI(const MachineInstr &MI) const {
VSETVLIInfo NewInfo;
if (MI.getOpcode() == RISCV::PseudoVSETIVLI) {
NewInfo.setAVLImm(MI.getOperand(1).getImm());
+ } else if (RISCVInstrInfo::isXSfmmVectorConfigTNInstr(MI)) {
+ assert(MI.getOpcode() == RISCV::PseudoSF_VSETTNT ||
+ MI.getOpcode() == RISCV::PseudoSF_VSETTNTX0);
+ switch (MI.getOpcode()) {
+ case RISCV::PseudoSF_VSETTNTX0:
+ NewInfo.setAVLVLMAX();
+ break;
+ case RISCV::PseudoSF_VSETTNT:
+ Register ATNReg = MI.getOperand(1).getReg();
+ NewInfo.setAVLRegDef(getVNInfoFromReg(ATNReg, MI, LIS), ATNReg);
+ break;
+ }
} else {
assert(MI.getOpcode() == RISCV::PseudoVSETVLI ||
MI.getOpcode() == RISCV::PseudoVSETVLIX0);
@@ -1005,11 +1062,34 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const {
RISCVVType::VLMUL VLMul = RISCVII::getLMul(TSFlags);
+ bool AltFmt = RISCVII::getAltFmtType(TSFlags) == RISCVII::AltFmtType::AltFmt;
+ InstrInfo.setAltFmt(AltFmt);
+
unsigned Log2SEW = MI.getOperand(getSEWOpNum(MI)).getImm();
// A Log2SEW of 0 is an operation on mask registers only.
unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
+ if (RISCVII::hasTWidenOp(TSFlags)) {
+ const MachineOperand &TWidenOp =
+ MI.getOperand(MI.getNumExplicitOperands() - 1);
+ unsigned TWiden = TWidenOp.getImm();
+
+ InstrInfo.setAVLVLMAX();
+ if (RISCVII::hasVLOp(TSFlags)) {
+ const MachineOperand &TNOp =
+ MI.getOperand(RISCVII::getTNOpNum(MI.getDesc()));
+
+ if (TNOp.getReg().isVirtual())
+ InstrInfo.setAVLRegDef(getVNInfoFromReg(TNOp.getReg(), MI, LIS),
+ TNOp.getReg());
+ }
+
+ InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden);
+
+ return InstrInfo;
+ }
+
if (RISCVII::hasVLOp(TSFlags)) {
const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
if (VLOp.isImm()) {
@@ -1045,7 +1125,9 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const {
assert(SEW == EEW && "Initial SEW doesn't match expected EEW");
}
#endif
- InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic);
+ // TODO: Propagate the twiden from previous vtype for potential reuse.
+ InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt,
+ /*TWiden*/ 0);
forwardVSETVLIAVL(InstrInfo);
@@ -1053,10 +1135,33 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const {
}
void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator InsertPt, DebugLoc DL,
- const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo) {
-
+ MachineBasicBlock::iterator InsertPt,
+ DebugLoc DL, const VSETVLIInfo &Info,
+ const VSETVLIInfo &PrevInfo) {
++NumInsertedVSETVL;
+
+ if (Info.getTWiden()) {
+ if (Info.hasAVLVLMAX()) {
+ Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
+ auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNTX0))
+ .addReg(DestReg, RegState::Define | RegState::Dead)
+ .addReg(RISCV::X0, RegState::Kill)
+ .addImm(Info.encodeVTYPE());
+ if (LIS) {
+ LIS->InsertMachineInstrInMaps(*MI);
+ LIS->createAndComputeVirtRegInterval(DestReg);
+ }
+ } else {
+ auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNT))
+ .addReg(RISCV::X0, RegState::Define | RegState::Dead)
+ .addReg(Info.getAVLReg())
+ .addImm(Info.encodeVTYPE());
+ if (LIS)
+ LIS->InsertMachineInstrInMaps(*MI);
+ }
+ return;
+ }
+
if (PrevInfo.isValid() && !PrevInfo.isUnknown()) {
// Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same
// VLMAX.
@@ -1198,7 +1303,8 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
// be coalesced into another vsetvli since we won't demand any fields.
VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly
NewInfo.setAVLImm(1);
- NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true);
+ NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true,
+ /*AltFmt*/ false, /*W*/ 0);
Info = NewInfo;
return;
}
@@ -1240,7 +1346,9 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
(Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() ||
IncomingInfo.getTailAgnostic(),
(Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
- IncomingInfo.getMaskAgnostic());
+ IncomingInfo.getMaskAgnostic(),
+ (Demanded.UseAltFmt ? IncomingInfo : Info).getAltFmt(),
+ Demanded.UseTWiden ? IncomingInfo.getTWiden() : 0);
// If we only knew the sew/lmul ratio previously, replace the VTYPE but keep
// the AVL.
@@ -1293,7 +1401,8 @@ bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
- isVectorCopy(ST->getRegisterInfo(), MI))
+ isVectorCopy(ST->getRegisterInfo(), MI) ||
+ RISCVInstrInfo::isXSfmmVectorConfigInstr(MI))
HadVectorOp = true;
transferAfter(Info, MI);
@@ -1675,6 +1784,12 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
};
for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
+ // TODO: Support XSfmm.
+ if (RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
+ RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) {
+ NextMI = nullptr;
+ continue;
+ }
if (!RISCVInstrInfo::isVectorConfigInstr(MI)) {
Used.doUnion(getDemanded(MI, ST));
@@ -1788,6 +1903,65 @@ void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) {
}
}
+bool RISCVInsertVSETVLI::insertVSETMTK(MachineBasicBlock &MBB,
+ TKTMMode Mode) const {
+
+ bool Changed = false;
+ for (auto &MI : MBB) {
+ uint64_t TSFlags = MI.getDesc().TSFlags;
+ if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI) ||
+ !RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasTWidenOp(TSFlags))
+ continue;
+
+ VSETVLIInfo CurrInfo = computeInfoForInstr(MI);
+
+ if (Mode == VSETTK && !RISCVII::hasTKOp(TSFlags))
+ continue;
+
+ if (Mode == VSETTM && !RISCVII::hasTMOp(TSFlags))
+ continue;
+
+ unsigned OpNum = 0;
+ unsigned Opcode = 0;
+ switch (Mode) {
+ case VSETTK:
+ OpNum = RISCVII::getTKOpNum(MI.getDesc());
+ Opcode = RISCV::PseudoSF_VSETTK;
+ break;
+ case VSETTM:
+ OpNum = RISCVII::getTMOpNum(MI.getDesc());
+ Opcode = RISCV::PseudoSF_VSETTM;
+ break;
+ }
+
+ assert(OpNum && Opcode && "Invalid OpNum or Opcode");
+
+ MachineOperand &Op = MI.getOperand(OpNum);
+
+ auto TmpMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(Opcode))
+ .addReg(RISCV::X0, RegState::Define | RegState::Dead)
+ .addReg(Op.getReg())
+ .addImm(Log2_32(CurrInfo.getSEW()))
+ .addImm(Log2_32(CurrInfo.getTWiden()) + 1);
+
+ Changed = true;
+ Register Reg = Op.getReg();
+ Op.setReg(Register());
+ Op.setIsKill(false);
+ if (LIS) {
+ LIS->InsertMachineInstrInMaps(*TmpMI);
+ LiveInterval &LI = LIS->getInterval(Reg);
+
+ // Erase the AVL operand from the instruction.
+ LIS->shrinkToUses(&LI);
+ // TODO: Enable this once needVSETVLIPHI is supported.
+ // SmallVector<LiveInterval *> SplitLIs;
+ // LIS->splitSeparateComponents(LI, SplitLIs);
+ }
+ }
+ return Changed;
+}
+
bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
// Skip if the vector extension is not enabled.
ST = &MF.getSubtarget<RISCVSubtarget>();
@@ -1865,6 +2039,11 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock &MBB : MF)
insertReadVL(MBB);
+ for (MachineBasicBlock &MBB : MF) {
+ insertVSETMTK(MBB, VSETTM);
+ insertVSETMTK(MBB, VSETTK);
+ }
+
BlockInfo.clear();
return HaveVectorOp;
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index 2afd77a..5b06303 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -267,6 +267,22 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
// operands' VLs.
bit ReadsPastVL = 0;
let TSFlags{26} = ReadsPastVL;
+
+ // 0 -> Don't care about altfmt bit in VTYPE.
+ // 1 -> Is not altfmt.
+ // 2 -> Is altfmt(BF16).
+ bits<2> AltFmtType = 0;
+ let TSFlags{28-27} = AltFmtType;
+
+ // XSfmmbase
+ bit HasTWidenOp = 0;
+ let TSFlags{29} = HasTWidenOp;
+
+ bit HasTmOp = 0;
+ let TSFlags{30} = HasTmOp;
+
+ bit HasTkOp = 0;
+ let TSFlags{31} = HasTkOp;
}
class RVInst<dag outs, dag ins, string opcodestr, string argstr,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 96e1078..ddb53a2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3005,6 +3005,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
else
Ok = RISCVFPRndMode::isValidRoundingMode(Imm);
break;
+ case RISCVOp::OPERAND_XSFMM_VTYPE:
+ Ok = RISCVVType::isValidXSfmmVType(Imm);
+ break;
}
if (!Ok) {
ErrInfo = "Invalid immediate";
@@ -3670,6 +3673,11 @@ std::string RISCVInstrInfo::createMIROperandComment(
RISCVVType::printVType(Imm, OS);
break;
}
+ case RISCVOp::OPERAND_XSFMM_VTYPE: {
+ unsigned Imm = Op.getImm();
+ RISCVVType::printXSfmmVType(Imm, OS);
+ break;
+ }
case RISCVOp::OPERAND_SEW:
case RISCVOp::OPERAND_SEW_MASK: {
unsigned Log2SEW = Op.getImm();
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index 298d35a..c1b23af 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -128,6 +128,9 @@ defvar TAIL_AGNOSTIC = 1;
defvar TU_MU = 0;
defvar TA_MU = 1;
defvar TA_MA = 3;
+defvar DONT_CARE_ALTFMT = 0;
+defvar IS_NOT_ALTFMT = 1;
+defvar IS_ALTFMT = 2;
//===----------------------------------------------------------------------===//
// Utilities.
@@ -159,7 +162,8 @@ class PseudoToVInst<string PseudoInst> {
["_M4", ""],
["_M8", ""],
["_SE", ""],
- ["_RM", ""]
+ ["_RM", ""],
+ ["_ALT", ""]
];
string VInst = !foldl(PseudoInst, AffixSubsts, Acc, AffixSubst,
!subst(AffixSubst[0], AffixSubst[1], Acc));
@@ -6396,7 +6400,7 @@ let Defs = [VXSAT] in {
// 13. Vector Floating-Point Instructions
//===----------------------------------------------------------------------===//
-let Predicates = [HasVInstructionsAnyF] in {
+let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in {
//===----------------------------------------------------------------------===//
// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions
//===----------------------------------------------------------------------===//
@@ -6565,7 +6569,7 @@ defm PseudoVFNCVT_F_F : VPseudoVNCVTD_W_RM;
defm PseudoVFNCVT_ROD_F_F : VPseudoVNCVTD_W;
} // mayRaiseFPException = true
-} // Predicates = [HasVInstructionsAnyF]
+} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT
//===----------------------------------------------------------------------===//
// 14. Vector Reduction Operations
@@ -6593,7 +6597,7 @@ defm PseudoVWREDSUM : VPseudoVWRED_VS;
}
} // Predicates = [HasVInstructions]
-let Predicates = [HasVInstructionsAnyF] in {
+let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in {
//===----------------------------------------------------------------------===//
// 14.3. Vector Single-Width Floating-Point Reduction Instructions
//===----------------------------------------------------------------------===//
@@ -6612,7 +6616,7 @@ defm PseudoVFWREDUSUM : VPseudoVFWRED_VS_RM;
defm PseudoVFWREDOSUM : VPseudoVFWREDO_VS_RM;
}
-} // Predicates = [HasVInstructionsAnyF]
+} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT
//===----------------------------------------------------------------------===//
// 15. Vector Mask Instructions
@@ -6703,7 +6707,7 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
// 16.2. Floating-Point Scalar Move Instructions
//===----------------------------------------------------------------------===//
-let Predicates = [HasVInstructionsAnyF] in {
+let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in {
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
foreach f = FPList in {
let HasSEWOp = 1, BaseInstr = VFMV_F_S in
@@ -6718,7 +6722,7 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
Sched<[WriteVMovSF, ReadVMovSF_V, ReadVMovSF_F]>;
}
}
-} // Predicates = [HasVInstructionsAnyF]
+} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT
//===----------------------------------------------------------------------===//
// 16.3. Vector Slide Instructions
@@ -6730,10 +6734,10 @@ let Predicates = [HasVInstructions] in {
defm PseudoVSLIDE1DOWN : VPseudoVSLD1_VX;
} // Predicates = [HasVInstructions]
-let Predicates = [HasVInstructionsAnyF] in {
+let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in {
defm PseudoVFSLIDE1UP : VPseudoVSLD1_VF<"@earlyclobber $rd">;
defm PseudoVFSLIDE1DOWN : VPseudoVSLD1_VF;
-} // Predicates = [HasVInstructionsAnyF]
+} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT
//===----------------------------------------------------------------------===//
// 16.4. Vector Register Gather Instructions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
index 557d873..6a4119a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td
@@ -438,8 +438,10 @@ let Predicates = [HasVendorXSfvcp] in {
}
foreach f = FPList in {
foreach m = f.MxList in {
- defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>;
- defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>;
+ let AltFmtType = IS_NOT_ALTFMT in {
+ defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>;
+ defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>;
+ }
}
}
foreach m = MxListW in {
@@ -449,7 +451,8 @@ let Predicates = [HasVendorXSfvcp] in {
}
foreach f = FPListW in {
foreach m = f.MxList in
- defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>;
+ let AltFmtType = IS_NOT_ALTFMT in
+ defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>;
}
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td
index a5ee701..5ad22e6b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td
@@ -225,7 +225,7 @@ let Predicates = [HasVendorXSfmmbase] in {
def SF_VSETTM : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00001,
"sf.vsettm", "$rd, $rs1">;
def SF_VSETTK : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00010,
- "sf.vsettk", "$rd, $rs1">;
+ "sf.vsettk", "$rd, $rs1">;
def SF_VTDISCARD : SFInstVtDiscard<"sf.vtdiscard">;
def SF_VTMV_V_T : SFInstTileMoveOp<0b010000, (outs VR:$vd), (ins GPR:$rs1),
@@ -277,3 +277,144 @@ let Uses = [FRM], mayRaiseFPException = true in {
} // Predicates = [HasVendorXSfmm32a8f]
} // DecoderNamespace = "XSfvector"
+
+class VPseudoSF_VTileLoad
+ : RISCVVPseudo<(outs), (ins GPR:$rs2, GPR:$rs1, AVL:$atn, ixlenimm:$sew,
+ ixlenimm:$twiden)> {
+ let mayLoad = 1;
+ let mayStore = 0;
+ let HasVLOp = 1; // Tn
+ let HasSEWOp = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+}
+
+class VPseudoSF_VTileStore
+ : RISCVVPseudo<(outs), (ins GPR:$rs2, GPR:$rs1, AVL:$atn, ixlenimm:$sew,
+ ixlenimm:$twiden)> {
+ let mayLoad = 0;
+ let mayStore = 1;
+ let HasVLOp = 1; // Tn
+ let HasSEWOp = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+}
+
+class VPseudoSF_VTileMove_V_T
+ : RISCVVPseudo<(outs VRM8:$vd), (ins GPR:$rs1, AVL:$atn, ixlenimm:$sew,
+ ixlenimm:$twiden)> {
+ let mayLoad = 0;
+ let mayStore = 0;
+ let HasVLOp = 1; // Tn
+ let HasSEWOp = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+}
+
+class VPseudoSF_VTileMove_T_V
+ : RISCVVPseudo<(outs), (ins GPR:$rs1, VRM8:$vs2, AVL:$atn, ixlenimm:$sew,
+ ixlenimm:$twiden)> {
+ let mayLoad = 0;
+ let mayStore = 0;
+ let HasVLOp = 1; // Tn
+ let HasSEWOp = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+}
+
+class VPseudoSF_MatMul<RegisterClass mtd_class>
+ : RISCVVPseudo<(outs),
+ (ins mtd_class:$rd, VRM8:$vs2, VRM8:$vs1, AVL:$atm, AVL:$atn,
+ AVL:$atk, ixlenimm:$sew, ixlenimm:$twiden)> {
+ let mayLoad = 0;
+ let mayStore = 0;
+ let HasTmOp = 1;
+ let HasVLOp = 1; // Tn
+ let HasTkOp = 1;
+ let HasSEWOp = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+}
+
+class VPseudoSF_MatMul_FRM<RegisterClass mtd_class>
+ : RISCVVPseudo<(outs),
+ (ins mtd_class:$rd, VRM8:$vs2, VRM8:$vs1, ixlenimm:$frm,
+ AVL:$atm, AVL:$atn, AVL:$atk, ixlenimm:$sew,
+ ixlenimm:$twiden), []> {
+ let mayLoad = 0;
+ let mayStore = 0;
+ let HasTmOp = 1;
+ let HasVLOp = 1; // Tn
+ let HasTkOp = 1;
+ let HasSEWOp = 1;
+ let HasRoundModeOp = 1;
+ let hasPostISelHook = 1;
+ let HasTWidenOp = 1;
+ let hasSideEffects = 1;
+ let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+let Defs = [VL, VTYPE] in {
+ def PseudoSF_VSETTNT
+ : Pseudo<(outs GPR:$rd),
+ (ins GPRNoX0:$rs1, XSfmmVTypeOp:$vtypei), []>,
+ PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>,
+ Sched<[WriteVSETVLI, ReadVSETVLI]>;
+ def PseudoSF_VSETTNTX0
+ : Pseudo<(outs GPRNoX0:$rd),
+ (ins GPRX0:$rs1, XSfmmVTypeOp:$vtypei), []>,
+ PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>,
+ Sched<[WriteVSETVLI, ReadVSETVLI]>;
+ def PseudoSF_VSETTNTX0X0
+ : Pseudo<(outs GPRX0:$rd),
+ (ins GPRX0:$rs1, XSfmmVTypeOp:$vtypei), []>,
+ PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>,
+ Sched<[WriteVSETVLI, ReadVSETVLI]>;
+}
+
+let Defs = [VTYPE], Uses = [VTYPE], HasTWidenOp = 1, HasSEWOp = 1 in {
+ def PseudoSF_VSETTM
+ : Pseudo<(outs GPR:$rd),
+ (ins GPR:$rs1, ixlenimm:$log2sew, ixlenimm:$twiden), []>,
+ PseudoInstExpansion<(SF_VSETTM GPR:$rd, GPR:$rs1)>,
+ Sched<[WriteVSETVLI, ReadVSETVLI]>;
+ def PseudoSF_VSETTK
+ : Pseudo<(outs GPR:$rd),
+ (ins GPR:$rs1, ixlenimm:$logwsew, ixlenimm:$twiden), []>,
+ PseudoInstExpansion<(SF_VSETTK GPR:$rd, GPR:$rs1)>,
+ Sched<[WriteVSETVLI, ReadVSETVLI]>;
+}
+}
+
+foreach eew = [8, 16, 32, 64] in {
+ def PseudoSF_VLTE # eew : VPseudoSF_VTileLoad;
+ def PseudoSF_VSTE # eew : VPseudoSF_VTileStore;
+}
+
+def PseudoSF_VTMV_T_V : VPseudoSF_VTileMove_T_V;
+def PseudoSF_VTMV_V_T : VPseudoSF_VTileMove_V_T;
+
+foreach a = I8Encodes in
+ foreach b = I8Encodes in
+ def PseudoSF_MM_ # !toupper(a.Name) # _ # !toupper(b.Name)
+ : VPseudoSF_MatMul<TRM4>;
+
+let AltFmtType = IS_NOT_ALTFMT in
+ def PseudoSF_MM_F_F : VPseudoSF_MatMul_FRM<TRM2>;
+let AltFmtType = IS_ALTFMT in
+ def PseudoSF_MM_F_F_ALT : VPseudoSF_MatMul_FRM<TRM2>;
+
+foreach e1 = [5, 4] in
+ foreach e2 = [5, 4] in
+ def PseudoSF_MM_E # e1 # M # !sub(7, e1) # _E # e2 # M # !sub(7, e2)
+ : VPseudoSF_MatMul_FRM<TRM4>;
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
+ let HasVLOp = 1, HasTmOp = 1, HasTWidenOp = 1, HasSEWOp = 1 in
+ def PseudoSF_VTZERO_T
+ : RISCVVPseudo<(outs),
+ (ins TR:$rd, AVL:$atm, AVL:$atn, ixlenimm:$sew,
+ ixlenimm:$twiden)>;
+ def PseudoSF_VTDISCARD : RISCVVPseudo<(outs), (ins), []>;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
index 3658817..dcae977 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td
@@ -78,7 +78,41 @@ def isVectorConfigInstr
PseudoVSETVLI,
PseudoVSETVLIX0,
PseudoVSETVLIX0X0,
- PseudoVSETIVLI
+ PseudoVSETIVLI,
+ PseudoSF_VSETTNT,
+ PseudoSF_VSETTNTX0,
+ PseudoSF_VSETTNTX0X0
+ ]>>>;
+
+// Returns true if this is a PseudoSF_VSETTNT* instructions.
+def isXSfmmVectorConfigTNInstr
+ : TIIPredicate<"isXSfmmVectorConfigTNInstr",
+ MCReturnStatement<
+ CheckOpcode<[
+ PseudoSF_VSETTNT,
+ PseudoSF_VSETTNTX0,
+ PseudoSF_VSETTNTX0X0
+ ]>>>;
+
+// Returns true if this is PseudoSF_VSETTM or PseudoSF_VSETTK.
+def isXSfmmVectorConfigTMTKInstr
+ : TIIPredicate<"isXSfmmVectorConfigTMTKInstr",
+ MCReturnStatement<
+ CheckOpcode<[
+ PseudoSF_VSETTM,
+ PseudoSF_VSETTK
+ ]>>>;
+
+// Returns true if this is a XSfmm vector configuration instruction.
+def isXSfmmVectorConfigInstr
+ : TIIPredicate<"isXSfmmVectorConfigInstr",
+ MCReturnStatement<
+ CheckOpcode<[
+ PseudoSF_VSETTNT,
+ PseudoSF_VSETTNTX0,
+ PseudoSF_VSETTNTX0X0,
+ PseudoSF_VSETTM,
+ PseudoSF_VSETTK
]>>>;
// Return true if this is 'vsetvli x0, x0, vtype' which preserves
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 40b6416..e9f43b9 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -178,6 +178,10 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// Shadow stack pointer.
markSuperRegs(Reserved, RISCV::SSP);
+ // XSfmmbase
+ for (MCPhysReg Reg = RISCV::T0; Reg <= RISCV::T15; Reg++)
+ markSuperRegs(Reserved, Reg);
+
assert(checkAllSuperRegsMarked(Reserved));
return Reserved;
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 6472334..47c24fc 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -317,6 +317,15 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Custom);
}
+ if (Subtarget->hasFP16()) {
+ setOperationAction(ISD::FMA, MVT::v8f16, Legal);
+ }
+
+ if (Subtarget->hasRelaxedSIMD()) {
+ setOperationAction(ISD::FMULADD, MVT::v4f32, Legal);
+ setOperationAction(ISD::FMULADD, MVT::v2f64, Legal);
+ }
+
// Partial MLA reductions.
for (auto Op : {ISD::PARTIAL_REDUCE_SMLA, ISD::PARTIAL_REDUCE_UMLA}) {
setPartialReduceMLAAction(Op, MVT::v4i32, MVT::v16i8, Legal);
@@ -1120,6 +1129,18 @@ WebAssemblyTargetLowering::getPreferredVectorAction(MVT VT) const {
return TargetLoweringBase::getPreferredVectorAction(VT);
}
+bool WebAssemblyTargetLowering::isFMAFasterThanFMulAndFAdd(
+ const MachineFunction &MF, EVT VT) const {
+ if (!Subtarget->hasFP16() || !VT.isVector())
+ return false;
+
+ EVT ScalarVT = VT.getScalarType();
+ if (!ScalarVT.isSimple())
+ return false;
+
+ return ScalarVT.getSimpleVT().SimpleTy == MVT::f16;
+}
+
bool WebAssemblyTargetLowering::shouldSimplifyDemandedVectorElts(
SDValue Op, const TargetLoweringOpt &TLO) const {
// ISel process runs DAGCombiner after legalization; this step is called
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index b33a853..472ec67 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -81,6 +81,8 @@ private:
TargetLoweringBase::LegalizeTypeAction
getPreferredVectorAction(MVT VT) const override;
+ bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
+ EVT VT) const override;
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index 49af78b..0f6e1ca 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1213,6 +1213,27 @@ defm EXTMUL_LOW_U :
defm EXTMUL_HIGH_U :
SIMDExtBinary<I64x2, extmul_high_u, "extmul_high_i32x4_u", 0xdf>;
+// Pattern for i32x4.dot_i16x8_s
+def : Pat<
+ (v4i32 (add
+ (wasm_shuffle
+ (v4i32 (extmul_low_s v8i16:$lhs, v8i16:$rhs)),
+ (v4i32 (extmul_high_s v8i16:$lhs, v8i16:$rhs)),
+ (i32 0), (i32 1), (i32 2), (i32 3),
+ (i32 8), (i32 9), (i32 10), (i32 11),
+ (i32 16), (i32 17), (i32 18), (i32 19),
+ (i32 24), (i32 25), (i32 26), (i32 27)),
+ (wasm_shuffle
+ (v4i32 (extmul_low_s v8i16:$lhs, v8i16:$rhs)),
+ (v4i32 (extmul_high_s v8i16:$lhs, v8i16:$rhs)),
+ (i32 4), (i32 5), (i32 6), (i32 7),
+ (i32 12), (i32 13), (i32 14), (i32 15),
+ (i32 20), (i32 21), (i32 22), (i32 23),
+ (i32 28), (i32 29), (i32 30), (i32 31)))
+ ),
+ (v4i32 (DOT v8i16:$lhs, v8i16:$rhs))
+>;
+
//===----------------------------------------------------------------------===//
// Floating-point unary arithmetic
//===----------------------------------------------------------------------===//
@@ -1626,7 +1647,8 @@ defm "" : RelaxedConvert<I32x4, F64x2, int_wasm_relaxed_trunc_unsigned_zero,
// Relaxed (Negative) Multiply-Add (madd/nmadd)
//===----------------------------------------------------------------------===//
-multiclass SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, list<Predicate> reqs> {
+multiclass RELAXED_SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS,
+ list<Predicate> reqs> {
defm MADD_#vec :
SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins),
[(set (vec.vt V128:$dst), (int_wasm_relaxed_madd
@@ -1640,16 +1662,46 @@ multiclass SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, list<Predicate>
vec.prefix#".relaxed_nmadd\t$dst, $a, $b, $c",
vec.prefix#".relaxed_nmadd", simdopS, reqs>;
- def : Pat<(fadd_contract (vec.vt V128:$a), (fmul_contract (vec.vt V128:$b), (vec.vt V128:$c))),
- (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<[HasRelaxedSIMD]>;
+ def : Pat<(fadd_contract (fmul_contract (vec.vt V128:$a), (vec.vt V128:$b)), (vec.vt V128:$c)),
+ (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>;
+ def : Pat<(fmuladd (vec.vt V128:$a), (vec.vt V128:$b), (vec.vt V128:$c)),
+ (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>;
- def : Pat<(fsub_contract (vec.vt V128:$a), (fmul_contract (vec.vt V128:$b), (vec.vt V128:$c))),
- (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<[HasRelaxedSIMD]>;
+ def : Pat<(fsub_contract (vec.vt V128:$c), (fmul_contract (vec.vt V128:$a), (vec.vt V128:$b))),
+ (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>;
+ def : Pat<(fmuladd (fneg (vec.vt V128:$a)), (vec.vt V128:$b), (vec.vt V128:$c)),
+ (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>;
}
-defm "" : SIMDMADD<F32x4, 0x105, 0x106, [HasRelaxedSIMD]>;
-defm "" : SIMDMADD<F64x2, 0x107, 0x108, [HasRelaxedSIMD]>;
-defm "" : SIMDMADD<F16x8, 0x14e, 0x14f, [HasFP16]>;
+defm "" : RELAXED_SIMDMADD<F32x4, 0x105, 0x106, [HasRelaxedSIMD]>;
+defm "" : RELAXED_SIMDMADD<F64x2, 0x107, 0x108, [HasRelaxedSIMD]>;
+
+//===----------------------------------------------------------------------===//
+// FP16 (Negative) Multiply-Add (madd/nmadd)
+//===----------------------------------------------------------------------===//
+
+multiclass HALF_PRECISION_SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS,
+ list<Predicate> reqs> {
+ defm MADD_#vec :
+ SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins),
+ [(set (vec.vt V128:$dst), (fma
+ (vec.vt V128:$a), (vec.vt V128:$b), (vec.vt V128:$c)))],
+ vec.prefix#".madd\t$dst, $a, $b, $c",
+ vec.prefix#".madd", simdopA, reqs>;
+ defm NMADD_#vec :
+ SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins),
+ [(set (vec.vt V128:$dst), (fma
+ (fneg (vec.vt V128:$a)), (vec.vt V128:$b), (vec.vt V128:$c)))],
+ vec.prefix#".nmadd\t$dst, $a, $b, $c",
+ vec.prefix#".nmadd", simdopS, reqs>;
+}
+defm "" : HALF_PRECISION_SIMDMADD<F16x8, 0x14e, 0x14f, [HasFP16]>;
+
+// TODO: I think separate intrinsics should be introduced for these FP16 operations.
+def : Pat<(v8f16 (int_wasm_relaxed_madd (v8f16 V128:$a), (v8f16 V128:$b), (v8f16 V128:$c))),
+ (MADD_F16x8 V128:$a, V128:$b, V128:$c)>;
+def : Pat<(v8f16 (int_wasm_relaxed_nmadd (v8f16 V128:$a), (v8f16 V128:$b), (v8f16 V128:$c))),
+ (NMADD_F16x8 V128:$a, V128:$b, V128:$c)>;
//===----------------------------------------------------------------------===//
// Laneselect
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index acf8e4c..5ea63a9 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -228,6 +228,10 @@ void printVType(unsigned VType, raw_ostream &OS) {
OS << ", mu";
}
+void printXSfmmVType(unsigned VType, raw_ostream &OS) {
+ OS << "e" << getSEW(VType) << ", w" << getXSfmmWiden(VType);
+}
+
unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul) {
unsigned LMul;
bool Fractional;
diff --git a/llvm/lib/Transforms/Coroutines/CoroCloner.h b/llvm/lib/Transforms/Coroutines/CoroCloner.h
index 26ec4f3..e05fe28 100644
--- a/llvm/lib/Transforms/Coroutines/CoroCloner.h
+++ b/llvm/lib/Transforms/Coroutines/CoroCloner.h
@@ -1,3 +1,4 @@
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -19,9 +20,7 @@
#include "llvm/Transforms/Coroutines/CoroInstr.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
-namespace llvm {
-
-namespace coro {
+namespace llvm::coro {
enum class CloneKind {
/// The shared resume function for a switch lowering.
@@ -149,8 +148,6 @@ public:
}
};
-} // end namespace coro
-
-} // end namespace llvm
+} // end namespace llvm::coro
#endif // LLVM_LIB_TRANSFORMS_COROUTINES_COROCLONER_H
diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index 471b9eb..cdb5852 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -38,7 +38,7 @@ public:
AnyResumeFnPtrTy(PointerType::getUnqual(Context)) {}
void lowerEarlyIntrinsics(Function &F);
};
-}
+} // namespace
// Replace a direct call to coro.resume or coro.destroy with an indirect call to
// an address returned by coro.subfn.addr intrinsic. This is done so that
diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h
index 52f4ffe..cc47a55 100644
--- a/llvm/lib/Transforms/Coroutines/CoroInternal.h
+++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h
@@ -16,11 +16,7 @@
#include "llvm/Transforms/Coroutines/CoroInstr.h"
#include "llvm/Transforms/Coroutines/CoroShape.h"
-namespace llvm {
-
-class CallGraph;
-
-namespace coro {
+namespace llvm::coro {
bool isSuspendBlock(BasicBlock *BB);
bool declaresAnyIntrinsic(const Module &M);
@@ -61,7 +57,6 @@ void normalizeCoroutine(Function &F, coro::Shape &Shape,
CallInst *createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
TargetTransformInfo &TTI,
ArrayRef<Value *> Arguments, IRBuilder<> &);
-} // End namespace coro.
-} // End namespace llvm
+} // End namespace llvm::coro
#endif
diff --git a/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp b/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp
index 6aaabca..f2444da 100644
--- a/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp
+++ b/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp
@@ -137,8 +137,7 @@ struct RematGraph {
} // namespace
-namespace llvm {
-template <> struct GraphTraits<RematGraph *> {
+template <> struct llvm::GraphTraits<RematGraph *> {
using NodeRef = RematGraph::RematNode *;
using ChildIteratorType = RematGraph::RematNode **;
@@ -149,8 +148,6 @@ template <> struct GraphTraits<RematGraph *> {
static ChildIteratorType child_end(NodeRef N) { return N->Operands.end(); }
};
-} // end namespace llvm
-
// For each instruction identified as materializable across the suspend point,
// and its associated DAG of other rematerializable instructions,
// recreate the DAG of instructions after the suspend point.
diff --git a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
index e474c07..81fe0c9 100644
--- a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
+++ b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
@@ -16,11 +16,8 @@
#include "llvm/IR/InstIterator.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-namespace llvm {
-
-namespace coro {
-
-namespace {
+using namespace llvm;
+using namespace llvm::coro;
typedef SmallPtrSet<BasicBlock *, 8> VisitedBlocksSet;
@@ -71,7 +68,7 @@ static bool isLocalAlloca(CoroAllocaAllocInst *AI) {
/// This happens during the all-instructions iteration, so it must not
/// delete the call.
static Instruction *
-lowerNonLocalAlloca(CoroAllocaAllocInst *AI, const coro::Shape &Shape,
+lowerNonLocalAlloca(CoroAllocaAllocInst *AI, const Shape &Shape,
SmallVectorImpl<Instruction *> &DeadInsts) {
IRBuilder<> Builder(AI);
auto Alloc = Shape.emitAlloc(Builder, AI->getSize(), nullptr);
@@ -450,10 +447,8 @@ static void collectFrameAlloca(AllocaInst *AI, const coro::Shape &Shape,
Visitor.getMayWriteBeforeCoroBegin());
}
-} // namespace
-
-void collectSpillsFromArgs(SpillInfo &Spills, Function &F,
- const SuspendCrossingInfo &Checker) {
+void coro::collectSpillsFromArgs(SpillInfo &Spills, Function &F,
+ const SuspendCrossingInfo &Checker) {
// Collect the spills for arguments and other not-materializable values.
for (Argument &A : F.args())
for (User *U : A.users())
@@ -461,7 +456,7 @@ void collectSpillsFromArgs(SpillInfo &Spills, Function &F,
Spills[&A].push_back(cast<Instruction>(U));
}
-void collectSpillsAndAllocasFromInsts(
+void coro::collectSpillsAndAllocasFromInsts(
SpillInfo &Spills, SmallVector<AllocaInfo, 8> &Allocas,
SmallVector<Instruction *, 4> &DeadInstructions,
SmallVector<CoroAllocaAllocInst *, 4> &LocalAllocas, Function &F,
@@ -516,8 +511,8 @@ void collectSpillsAndAllocasFromInsts(
}
}
-void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F,
- const SuspendCrossingInfo &Checker) {
+void coro::collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F,
+ const SuspendCrossingInfo &Checker) {
// We don't want the layout of coroutine frame to be affected
// by debug information. So we only choose to salvage dbg.values for
// whose value is already in the frame.
@@ -535,10 +530,9 @@ void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F,
/// Async and Retcon{Once} conventions assume that all spill uses can be sunk
/// after the coro.begin intrinsic.
-void sinkSpillUsesAfterCoroBegin(const DominatorTree &Dom,
- CoroBeginInst *CoroBegin,
- coro::SpillInfo &Spills,
- SmallVectorImpl<coro::AllocaInfo> &Allocas) {
+void coro::sinkSpillUsesAfterCoroBegin(
+ const DominatorTree &Dom, CoroBeginInst *CoroBegin, coro::SpillInfo &Spills,
+ SmallVectorImpl<coro::AllocaInfo> &Allocas) {
SmallSetVector<Instruction *, 32> ToMove;
SmallVector<Instruction *, 32> Worklist;
@@ -582,8 +576,9 @@ void sinkSpillUsesAfterCoroBegin(const DominatorTree &Dom,
Inst->moveBefore(InsertPt->getIterator());
}
-BasicBlock::iterator getSpillInsertionPt(const coro::Shape &Shape, Value *Def,
- const DominatorTree &DT) {
+BasicBlock::iterator coro::getSpillInsertionPt(const coro::Shape &Shape,
+ Value *Def,
+ const DominatorTree &DT) {
BasicBlock::iterator InsertPt;
if (auto *Arg = dyn_cast<Argument>(Def)) {
// For arguments, we will place the store instruction right after
@@ -625,7 +620,3 @@ BasicBlock::iterator getSpillInsertionPt(const coro::Shape &Shape, Value *Def,
return InsertPt;
}
-
-} // End namespace coro.
-
-} // End namespace llvm.
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 7071876..943c223 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -471,7 +471,6 @@ private:
Value *simplifyNonNullOperand(Value *V, bool HasDereferenceable,
unsigned Depth = 0);
-public:
/// Create `select C, S1, S2`. Use only when the profile cannot be calculated
/// from existing profile metadata: if the Function has profiles, this will
/// set the profile of this select to "unknown".
@@ -484,6 +483,7 @@ public:
return Sel;
}
+public:
/// Create and insert the idiom we use to indicate a block is unreachable
/// without having to rewrite the CFG from within InstCombine.
void CreateNonTerminatorUnreachable(Instruction *InsertAt) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 63e24a0..a330bb7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -110,8 +110,8 @@ static Value *simplifyShiftSelectingPackedElement(Instruction *I,
ShrAmt->getName() + ".z");
// There is no existing !prof metadata we can derive the !prof metadata for
// this select.
- Value *Select = IC.createSelectInstWithUnknownProfile(ShrAmtZ, Lower, Upper);
- IC.Builder.Insert(Select);
+ Value *Select = IC.Builder.CreateSelectWithUnknownProfile(ShrAmtZ, Lower,
+ Upper, DEBUG_TYPE);
Select->takeName(I);
return Select;
}
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index c86092b..a6ec6c1 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/MemoryProfileInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/StaticDataProfileInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
@@ -194,6 +195,30 @@ static bool isAllocationWithHotColdVariant(const Function *Callee,
}
}
+static void HandleUnsupportedAnnotationKinds(GlobalVariable &GVar,
+ AnnotationKind Kind) {
+ assert(Kind != llvm::memprof::AnnotationKind::AnnotationOK &&
+ "Should not handle AnnotationOK here");
+ SmallString<32> Reason;
+ switch (Kind) {
+ case llvm::memprof::AnnotationKind::ExplicitSection:
+ ++NumOfMemProfExplicitSectionGlobalVars;
+ Reason.append("explicit section name");
+ break;
+ case llvm::memprof::AnnotationKind::DeclForLinker:
+ Reason.append("linker declaration");
+ break;
+ case llvm::memprof::AnnotationKind::ReservedName:
+ Reason.append("name starts with `llvm.`");
+ break;
+ default:
+ llvm_unreachable("Unexpected annotation kind");
+ }
+ LLVM_DEBUG(dbgs() << "Skip annotation for " << GVar.getName() << " due to "
+ << Reason << ".\n");
+ return;
+}
+
struct AllocMatchInfo {
uint64_t TotalSize = 0;
AllocationType AllocType = AllocationType::None;
@@ -775,29 +800,13 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) {
return PreservedAnalyses::none();
}
-// Returns true iff the global variable has custom section either by
-// __attribute__((section("name")))
-// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
-// or #pragma clang section directives
-// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
-static bool hasExplicitSectionName(const GlobalVariable &GVar) {
- if (GVar.hasSection())
- return true;
-
- auto Attrs = GVar.getAttributes();
- if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
- Attrs.hasAttribute("relro-section") ||
- Attrs.hasAttribute("rodata-section"))
- return true;
- return false;
-}
-
bool MemProfUsePass::annotateGlobalVariables(
Module &M, const memprof::DataAccessProfData *DataAccessProf) {
if (!AnnotateStaticDataSectionPrefix || M.globals().empty())
return false;
if (!DataAccessProf) {
+ M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 0U);
M.getContext().diagnose(DiagnosticInfoPGOProfile(
MemoryProfileFileName.data(),
StringRef("Data access profiles not found in memprof. Ignore "
@@ -805,6 +814,7 @@ bool MemProfUsePass::annotateGlobalVariables(
DS_Warning));
return false;
}
+ M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 1U);
bool Changed = false;
// Iterate all global variables in the module and annotate them based on
@@ -815,13 +825,9 @@ bool MemProfUsePass::annotateGlobalVariables(
for (GlobalVariable &GVar : M.globals()) {
assert(!GVar.getSectionPrefix().has_value() &&
"GVar shouldn't have section prefix yet");
- if (GVar.isDeclarationForLinker())
- continue;
-
- if (hasExplicitSectionName(GVar)) {
- ++NumOfMemProfExplicitSectionGlobalVars;
- LLVM_DEBUG(dbgs() << "Global variable " << GVar.getName()
- << " has explicit section name. Skip annotating.\n");
+ auto Kind = llvm::memprof::getAnnotationKind(GVar);
+ if (Kind != llvm::memprof::AnnotationKind::AnnotationOK) {
+ HandleUnsupportedAnnotationKinds(GVar, Kind);
continue;
}
@@ -831,7 +837,6 @@ bool MemProfUsePass::annotateGlobalVariables(
// TODO: Track string content hash in the profiles and compute it inside the
// compiler to categeorize the hotness string literals.
if (Name.starts_with(".str")) {
-
LLVM_DEBUG(dbgs() << "Skip annotating string literal " << Name << "\n");
continue;
}
diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
index ccb86eb..fb39fdd 100644
--- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
+++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp
@@ -269,8 +269,7 @@ static bool replaceIfIdentical(PHINode &PHI, PHINode &ReplPHI) {
bool EliminateNewDuplicatePHINodes(BasicBlock *BB,
BasicBlock::phi_iterator FirstExistingPN) {
- auto NewPHIs = make_range(BB->phis().begin(), FirstExistingPN);
- assert(!PHIAreRefEachOther(NewPHIs));
+ assert(!PHIAreRefEachOther(make_range(BB->phis().begin(), FirstExistingPN)));
// Deduplicate new PHIs first to reduce the number of comparisons on the
// following new -> existing pass.
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index f95d288..88af2cf 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -19460,7 +19460,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
}
assert(getNumElements(Cond->getType()) == TrueNumElements &&
"Cannot vectorize Instruction::Select");
- Value *V = Builder.CreateSelect(Cond, True, False);
+ Value *V =
+ Builder.CreateSelectWithUnknownProfile(Cond, True, False, DEBUG_TYPE);
V = FinalShuffle(V, E);
E->VectorizedValue = V;
@@ -23580,18 +23581,19 @@ class HorizontalReduction {
switch (Kind) {
case RecurKind::Or: {
if (UseSelect && OpTy == CmpInst::makeCmpResultType(OpTy))
- return Builder.CreateSelect(
+ return Builder.CreateSelectWithUnknownProfile(
LHS, ConstantInt::getAllOnesValue(CmpInst::makeCmpResultType(OpTy)),
- RHS, Name);
+ RHS, DEBUG_TYPE, Name);
unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
Name);
}
case RecurKind::And: {
if (UseSelect && OpTy == CmpInst::makeCmpResultType(OpTy))
- return Builder.CreateSelect(
+ return Builder.CreateSelectWithUnknownProfile(
LHS, RHS,
- ConstantInt::getNullValue(CmpInst::makeCmpResultType(OpTy)), Name);
+ ConstantInt::getNullValue(CmpInst::makeCmpResultType(OpTy)),
+ DEBUG_TYPE, Name);
unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
Name);
@@ -23612,7 +23614,8 @@ class HorizontalReduction {
if (UseSelect) {
CmpInst::Predicate Pred = llvm::getMinMaxReductionPredicate(Kind);
Value *Cmp = Builder.CreateICmp(Pred, LHS, RHS, Name);
- return Builder.CreateSelect(Cmp, LHS, RHS, Name);
+ return Builder.CreateSelectWithUnknownProfile(Cmp, LHS, RHS, DEBUG_TYPE,
+ Name);
}
[[fallthrough]];
case RecurKind::FMax:
diff --git a/llvm/lib/XRay/BlockIndexer.cpp b/llvm/lib/XRay/BlockIndexer.cpp
index f4ba0eb..d0c6853 100644
--- a/llvm/lib/XRay/BlockIndexer.cpp
+++ b/llvm/lib/XRay/BlockIndexer.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/BlockIndexer.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error BlockIndexer::visit(BufferExtents &) { return Error::success(); }
@@ -89,6 +89,3 @@ Error BlockIndexer::flush() {
CurrentBlock.WallclockTime = nullptr;
return Error::success();
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/BlockPrinter.cpp b/llvm/lib/XRay/BlockPrinter.cpp
index 63a60c3..d85be5b 100644
--- a/llvm/lib/XRay/BlockPrinter.cpp
+++ b/llvm/lib/XRay/BlockPrinter.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/BlockPrinter.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error BlockPrinter::visit(BufferExtents &R) {
OS << "\n[New Block]\n";
@@ -108,6 +108,3 @@ Error BlockPrinter::visit(EndBufferRecord &R) {
auto E = RP.visit(R);
return E;
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/BlockVerifier.cpp b/llvm/lib/XRay/BlockVerifier.cpp
index 99f255e..e39f6b6 100644
--- a/llvm/lib/XRay/BlockVerifier.cpp
+++ b/llvm/lib/XRay/BlockVerifier.cpp
@@ -10,19 +10,18 @@
#include <bitset>
-namespace llvm {
-namespace xray {
-namespace {
+using namespace llvm;
+using namespace llvm::xray;
-constexpr unsigned long long mask(BlockVerifier::State S) {
+static constexpr unsigned long long mask(BlockVerifier::State S) {
return 1uLL << static_cast<std::size_t>(S);
}
-constexpr std::size_t number(BlockVerifier::State S) {
+static constexpr std::size_t number(BlockVerifier::State S) {
return static_cast<std::size_t>(S);
}
-StringRef recordToString(BlockVerifier::State R) {
+static StringRef recordToString(BlockVerifier::State R) {
switch (R) {
case BlockVerifier::State::BufferExtents:
return "BufferExtents";
@@ -53,6 +52,8 @@ StringRef recordToString(BlockVerifier::State R) {
llvm_unreachable("Unkown state!");
}
+namespace {
+
struct Transition {
BlockVerifier::State From;
std::bitset<number(BlockVerifier::State::StateMax)> ToStates;
@@ -133,7 +134,7 @@ Error BlockVerifier::transition(State To) {
CurrentRecord = To;
return Error::success();
-} // namespace xray
+}
Error BlockVerifier::visit(BufferExtents &) {
return transition(State::BufferExtents);
@@ -201,6 +202,3 @@ Error BlockVerifier::verify() {
}
void BlockVerifier::reset() { CurrentRecord = State::Unknown; }
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/FDRRecordProducer.cpp b/llvm/lib/XRay/FDRRecordProducer.cpp
index 479b710..0f4eed1 100644
--- a/llvm/lib/XRay/FDRRecordProducer.cpp
+++ b/llvm/lib/XRay/FDRRecordProducer.cpp
@@ -10,8 +10,8 @@
#include <cstdint>
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
namespace {
@@ -31,8 +31,9 @@ enum MetadataRecordKinds : uint8_t {
// This is an end marker, used to identify the upper bound for this enum.
EnumEndMarker,
};
+} // namespace
-Expected<std::unique_ptr<Record>>
+static Expected<std::unique_ptr<Record>>
metadataRecordType(const XRayFileHeader &Header, uint8_t T) {
if (T >= static_cast<uint8_t>(MetadataRecordKinds::EnumEndMarker))
@@ -72,12 +73,10 @@ metadataRecordType(const XRayFileHeader &Header, uint8_t T) {
llvm_unreachable("Unhandled MetadataRecordKinds enum value");
}
-constexpr bool isMetadataIntroducer(uint8_t FirstByte) {
+static constexpr bool isMetadataIntroducer(uint8_t FirstByte) {
return FirstByte & 0x01u;
}
-} // namespace
-
Expected<std::unique_ptr<Record>>
FileBasedRecordProducer::findNextBufferExtent() {
// We seek one byte at a time until we find a suitable buffer extents metadata
@@ -193,6 +192,3 @@ Expected<std::unique_ptr<Record>> FileBasedRecordProducer::produce() {
assert(R != nullptr);
return std::move(R);
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/FDRRecords.cpp b/llvm/lib/XRay/FDRRecords.cpp
index ff315d3..a18f733 100644
--- a/llvm/lib/XRay/FDRRecords.cpp
+++ b/llvm/lib/XRay/FDRRecords.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/FDRRecords.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error BufferExtents::apply(RecordVisitor &V) { return V.visit(*this); }
Error WallclockRecord::apply(RecordVisitor &V) { return V.visit(*this); }
@@ -61,6 +61,3 @@ StringRef Record::kindToString(RecordKind K) {
}
return "Unknown";
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/FDRTraceExpander.cpp b/llvm/lib/XRay/FDRTraceExpander.cpp
index b68e997..991e6e5 100644
--- a/llvm/lib/XRay/FDRTraceExpander.cpp
+++ b/llvm/lib/XRay/FDRTraceExpander.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/FDRTraceExpander.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
void TraceExpander::resetCurrentRecord() {
if (BuildingRecord)
@@ -126,6 +126,3 @@ Error TraceExpander::flush() {
resetCurrentRecord();
return Error::success();
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/FDRTraceWriter.cpp b/llvm/lib/XRay/FDRTraceWriter.cpp
index fb59125..3e320a6 100644
--- a/llvm/lib/XRay/FDRTraceWriter.cpp
+++ b/llvm/lib/XRay/FDRTraceWriter.cpp
@@ -12,8 +12,8 @@
#include "llvm/XRay/FDRTraceWriter.h"
#include <tuple>
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
namespace {
@@ -37,9 +37,10 @@ template <size_t Index> struct IndexedWriter {
return 0;
}
};
+} // namespace
template <uint8_t Kind, class... Values>
-Error writeMetadata(support::endian::Writer &OS, Values &&... Ds) {
+static Error writeMetadata(support::endian::Writer &OS, Values &&...Ds) {
// The first bit in the first byte of metadata records is always set to 1, so
// we ensure this is the case when we write out the first byte of the record.
uint8_t FirstByte = (static_cast<uint8_t>(Kind) << 1) | uint8_t{0x01u};
@@ -54,8 +55,6 @@ Error writeMetadata(support::endian::Writer &OS, Values &&... Ds) {
return Error::success();
}
-} // namespace
-
FDRTraceWriter::FDRTraceWriter(raw_ostream &O, const XRayFileHeader &H)
: OS(O, llvm::endianness::native) {
// We need to re-construct a header, by writing the fields we care about for
@@ -146,6 +145,3 @@ Error FDRTraceWriter::visit(FunctionRecord &R) {
OS.write(R.delta());
return Error::success();
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/FileHeaderReader.cpp b/llvm/lib/XRay/FileHeaderReader.cpp
index 6b6daf9..681cef7 100644
--- a/llvm/lib/XRay/FileHeaderReader.cpp
+++ b/llvm/lib/XRay/FileHeaderReader.cpp
@@ -7,12 +7,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/FileHeaderReader.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
// Populates the FileHeader reference by reading the first 32 bytes of the file.
-Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor,
- uint64_t &OffsetPtr) {
+Expected<XRayFileHeader>
+xray::readBinaryFormatHeader(DataExtractor &HeaderExtractor,
+ uint64_t &OffsetPtr) {
// FIXME: Maybe deduce whether the data is little or big-endian using some
// magic bytes in the beginning of the file?
@@ -68,6 +69,3 @@ Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor,
OffsetPtr += 16;
return std::move(FileHeader);
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/LogBuilderConsumer.cpp b/llvm/lib/XRay/LogBuilderConsumer.cpp
index ffb49f9..f0fc336 100644
--- a/llvm/lib/XRay/LogBuilderConsumer.cpp
+++ b/llvm/lib/XRay/LogBuilderConsumer.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/FDRRecordConsumer.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error LogBuilderConsumer::consume(std::unique_ptr<Record> R) {
if (!R)
@@ -32,6 +32,3 @@ Error PipelineConsumer::consume(std::unique_ptr<Record> R) {
Result = joinErrors(std::move(Result), R->apply(*V));
return Result;
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/Profile.cpp b/llvm/lib/XRay/Profile.cpp
index 1b340e5..ecb767b 100644
--- a/llvm/lib/XRay/Profile.cpp
+++ b/llvm/lib/XRay/Profile.cpp
@@ -18,8 +18,8 @@
#include "llvm/XRay/Trace.h"
#include <memory>
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Profile::Profile(const Profile &O) {
// We need to re-create all the tries from the original (O), into the current
@@ -46,6 +46,7 @@ struct BlockHeader {
uint32_t Number;
uint64_t Thread;
};
+} // namespace
static Expected<BlockHeader> readBlockHeader(DataExtractor &Extractor,
uint64_t &Offset) {
@@ -115,8 +116,6 @@ static Expected<Profile::Data> readData(DataExtractor &Extractor,
return D;
}
-} // namespace
-
Error Profile::addBlock(Block &&B) {
if (B.PathData.empty())
return make_error<StringError>(
@@ -189,7 +188,7 @@ Profile::PathID Profile::internPath(ArrayRef<FuncID> P) {
return Node->ID;
}
-Profile mergeProfilesByThread(const Profile &L, const Profile &R) {
+Profile xray::mergeProfilesByThread(const Profile &L, const Profile &R) {
Profile Merged;
using PathDataMap = DenseMap<Profile::PathID, Profile::Data>;
using PathDataMapPtr = std::unique_ptr<PathDataMap>;
@@ -228,7 +227,7 @@ Profile mergeProfilesByThread(const Profile &L, const Profile &R) {
return Merged;
}
-Profile mergeProfilesByStack(const Profile &L, const Profile &R) {
+Profile xray::mergeProfilesByStack(const Profile &L, const Profile &R) {
Profile Merged;
using PathDataMap = DenseMap<Profile::PathID, Profile::Data>;
PathDataMap PathData;
@@ -258,7 +257,7 @@ Profile mergeProfilesByStack(const Profile &L, const Profile &R) {
return Merged;
}
-Expected<Profile> loadProfile(StringRef Filename) {
+Expected<Profile> xray::loadProfile(StringRef Filename) {
Expected<sys::fs::file_t> FdOrErr = sys::fs::openNativeFileForRead(Filename);
if (!FdOrErr)
return FdOrErr.takeError();
@@ -322,7 +321,7 @@ struct StackEntry {
} // namespace
-Expected<Profile> profileFromTrace(const Trace &T) {
+Expected<Profile> xray::profileFromTrace(const Trace &T) {
Profile P;
// The implementation of the algorithm re-creates the execution of
@@ -397,6 +396,3 @@ Expected<Profile> profileFromTrace(const Trace &T) {
return P;
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/RecordInitializer.cpp b/llvm/lib/XRay/RecordInitializer.cpp
index 68ab3db..83d5f14 100644
--- a/llvm/lib/XRay/RecordInitializer.cpp
+++ b/llvm/lib/XRay/RecordInitializer.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/XRay/FDRRecords.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error RecordInitializer::visit(BufferExtents &R) {
if (!E.isValidOffsetForDataOfSize(OffsetPtr, sizeof(uint64_t)))
@@ -426,6 +426,3 @@ Error RecordInitializer::visit(FunctionRecord &R) {
assert(FunctionRecord::kFunctionRecordSize == (OffsetPtr - BeginOffset));
return Error::success();
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/RecordPrinter.cpp b/llvm/lib/XRay/RecordPrinter.cpp
index 32d4210..b9b7a16 100644
--- a/llvm/lib/XRay/RecordPrinter.cpp
+++ b/llvm/lib/XRay/RecordPrinter.cpp
@@ -9,8 +9,8 @@
#include "llvm/Support/FormatVariadic.h"
-namespace llvm {
-namespace xray {
+using namespace llvm;
+using namespace llvm::xray;
Error RecordPrinter::visit(BufferExtents &R) {
OS << formatv("<Buffer: size = {0} bytes>", R.size()) << Delim;
@@ -103,6 +103,3 @@ Error RecordPrinter::visit(FunctionRecord &R) {
OS << Delim;
return Error::success();
}
-
-} // namespace xray
-} // namespace llvm
diff --git a/llvm/lib/XRay/Trace.cpp b/llvm/lib/XRay/Trace.cpp
index 74515b1..14a3f01 100644
--- a/llvm/lib/XRay/Trace.cpp
+++ b/llvm/lib/XRay/Trace.cpp
@@ -29,11 +29,9 @@ using namespace llvm;
using namespace llvm::xray;
using llvm::yaml::Input;
-namespace {
-
-Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian,
- XRayFileHeader &FileHeader,
- std::vector<XRayRecord> &Records) {
+static Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian,
+ XRayFileHeader &FileHeader,
+ std::vector<XRayRecord> &Records) {
if (Data.size() < 32)
return make_error<StringError>(
"Not enough bytes for an XRay log.",
@@ -265,8 +263,9 @@ Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian,
/// what FunctionRecord instances use, and we no longer need to include the CPU
/// id in the CustomEventRecord.
///
-Error loadFDRLog(StringRef Data, bool IsLittleEndian,
- XRayFileHeader &FileHeader, std::vector<XRayRecord> &Records) {
+static Error loadFDRLog(StringRef Data, bool IsLittleEndian,
+ XRayFileHeader &FileHeader,
+ std::vector<XRayRecord> &Records) {
if (Data.size() < 32)
return createStringError(std::make_error_code(std::errc::invalid_argument),
@@ -348,8 +347,8 @@ Error loadFDRLog(StringRef Data, bool IsLittleEndian,
return Error::success();
}
-Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader,
- std::vector<XRayRecord> &Records) {
+static Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader,
+ std::vector<XRayRecord> &Records) {
YAMLXRayTrace Trace;
Input In(Data);
In >> Trace;
@@ -376,7 +375,6 @@ Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader,
});
return Error::success();
}
-} // namespace
Expected<Trace> llvm::xray::loadTraceFile(StringRef Filename, bool Sort) {
Expected<sys::fs::file_t> FdOrErr = sys::fs::openNativeFileForRead(Filename);
diff --git a/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir b/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir
new file mode 100644
index 0000000..a4aad57
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir
@@ -0,0 +1,59 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -run-pass=machine-scheduler -o - %s | FileCheck %s
+
+---
+name: buffer_load_lds_not_valu
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0_vgpr1
+ ; CHECK-LABEL: name: buffer_load_lds_not_valu
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $exec = IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF1:%[0-9]+]]:sgpr_128 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF2:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF3:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[DEF2]], [[DEF3]], implicit $exec
+ ; CHECK-NEXT: [[V_ADD_U32_e32_1:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[DEF3]], [[V_ADD_U32_e32_]], implicit $exec
+ ; CHECK-NEXT: $m0 = S_MOV_B32 0
+ ; CHECK-NEXT: BUFFER_LOAD_DWORDX4_LDS_OFFEN [[DEF]], [[DEF1]], 0, 0, 0, 0, implicit $exec, implicit $m0
+ ; CHECK-NEXT: [[V_ADD_U32_e32_2:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_]], [[V_ADD_U32_e32_1]], implicit $exec
+ ; CHECK-NEXT: [[V_ADD_U32_e32_3:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_1]], [[V_ADD_U32_e32_2]], implicit $exec
+ ; CHECK-NEXT: $m0 = S_MOV_B32 1
+ ; CHECK-NEXT: BUFFER_LOAD_DWORDX4_LDS_OFFEN [[DEF]], [[DEF1]], 0, 0, 0, 0, implicit $exec, implicit $m0
+ ; CHECK-NEXT: [[V_ADD_U32_e32_4:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_2]], [[V_ADD_U32_e32_3]], implicit $exec
+ ; CHECK-NEXT: [[V_ADD_U32_e32_5:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_3]], [[V_ADD_U32_e32_4]], implicit $exec
+ ; CHECK-NEXT: [[V_ADD_U32_e32_6:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_4]], [[V_ADD_U32_e32_5]], implicit $exec
+ ; CHECK-NEXT: dead [[V_ADD_U32_e32_7:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_5]], [[V_ADD_U32_e32_6]], implicit $exec
+ ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 2, 0
+ ; CHECK-NEXT: SCHED_GROUP_BARRIER 4, 1, 0
+ ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 2, 0
+ ; CHECK-NEXT: SCHED_GROUP_BARRIER 4, 1, 0
+ ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 4, 0
+ ; CHECK-NEXT: S_ENDPGM 0
+ $exec = IMPLICIT_DEF
+ %0:vgpr_32 = IMPLICIT_DEF
+ %1:sgpr_128 = IMPLICIT_DEF
+ %2:vgpr_32 = IMPLICIT_DEF
+ %3:vgpr_32 = IMPLICIT_DEF
+ %4:vgpr_32 = V_ADD_U32_e32 %2, %3, implicit $exec
+ %5:vgpr_32 = V_ADD_U32_e32 %3, %4, implicit $exec
+ $m0 = S_MOV_B32 0
+ BUFFER_LOAD_DWORDX4_LDS_OFFEN %0, %1, 0, 0, 0, 0, implicit $exec, implicit $m0
+ $m0 = S_MOV_B32 1
+ BUFFER_LOAD_DWORDX4_LDS_OFFEN %0, %1, 0, 0, 0, 0, implicit $exec, implicit $m0
+ %6:vgpr_32 = V_ADD_U32_e32 %4, %5, implicit $exec
+ %7:vgpr_32 = V_ADD_U32_e32 %5, %6, implicit $exec
+ %8:vgpr_32 = V_ADD_U32_e32 %6, %7, implicit $exec
+ %9:vgpr_32 = V_ADD_U32_e32 %7, %8, implicit $exec
+ %10:vgpr_32 = V_ADD_U32_e32 %8, %9, implicit $exec
+ %11:vgpr_32 = V_ADD_U32_e32 %9, %10, implicit $exec
+ SCHED_GROUP_BARRIER 2, 2, 0
+ SCHED_GROUP_BARRIER 4, 1 ,0
+ SCHED_GROUP_BARRIER 2, 2, 0
+ SCHED_GROUP_BARRIER 4, 1 ,0
+ SCHED_GROUP_BARRIER 2, 4, 0
+ S_ENDPGM 0
+...
diff --git a/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir b/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir
new file mode 100644
index 0000000..389283a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir
@@ -0,0 +1,523 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc %s -o - -mtriple=riscv64 -mattr=+v \
+# RUN: -run-pass=phi-node-elimination,register-coalescer,riscv-insert-vsetvli | FileCheck %s
+
+--- |
+ define void @xsfmm_same_state(<vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 noundef %tm, i64 noundef %tn, i64 noundef %tk) {
+ entry:
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ ret void
+ }
+
+ define void @xsfmm_different_state(<vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk) {
+ entry:
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 4)
+ ret void
+ }
+
+ define void @xsfmm_different_state_bf(<vscale x 32 x half> %tile1, <vscale x 32 x bfloat> %tile2, i64 %tm, i64 %tn, i64 %tk) {
+ entry:
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile1, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32bf16(i64 2, <vscale x 32 x bfloat> %tile2, <vscale x 32 x bfloat> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile1, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ ret void
+ }
+
+ define <vscale x 64 x i8> @interleave_rvv_and_xsfmm(<vscale x 64 x i8> %tile, i64 %vl, ptr %base) {
+ entry:
+ %0 = call <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64 1, i64 %vl)
+ %1 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %0, i64 %vl)
+ call void @llvm.riscv.sf.vste16.i64(i64 1, ptr %base, i64 %vl)
+ ret <vscale x 64 x i8> %1
+ }
+
+ define <vscale x 64 x i8> @interleave_rvv_and_xsfmm2(<vscale x 64 x i8> %tile, i64 %vl, ptr %base) {
+ entry:
+ %0 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %tile, i64 %vl)
+ %1 = call <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64 1, i64 %vl)
+ %2 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %0, i64 %vl)
+ call void @llvm.riscv.sf.vste16.i64(i64 1, ptr %base, i64 %vl)
+ ret <vscale x 64 x i8> %2
+ }
+
+ define void @consecutive_xsfmm(<vscale x 32 x half> %tile, i64 %tm, i64 %tn, i64 %tk, ptr %base) {
+ entry:
+ tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 0, <vscale x 32 x half> %tile, <vscale x 32 x half> %tile, i64 %tm, i64 %tn, i64 %tk, i64 2)
+ call void @llvm.riscv.sf.vste16.i64(i64 0, ptr %base, i64 %tn)
+ ret void
+ }
+
+ define i64 @vsettnt_max(i64 %vl) {
+ entry:
+ %0 = call i64 @llvm.riscv.sf.vsettm.i64(i64 %vl, i64 1, i64 2)
+ %1 = call i64 @llvm.riscv.sf.vsettnt_max.i64(i64 1, i64 2)
+ ret i64 %0
+ }
+
+ define i64 @single_vsettm(i64 %vl) {
+ entry:
+ %0 = call i64 @llvm.riscv.sf.vsettm.i64(i64 %vl, i64 1, i64 2)
+ ret i64 %0
+ }
+
+ define i64 @single_vsettn(i64 %vl) {
+ entry:
+ %0 = call i64 @llvm.riscv.sf.vsettn.i64(i64 %vl, i64 1, i64 2)
+ ret i64 %0
+ }
+
+ define i64 @single_vsettk(i64 %vl) {
+ entry:
+ %0 = call i64 @llvm.riscv.sf.vsettk.i64(i64 %vl, i64 1, i64 2)
+ ret i64 %0
+ }
+
+ define void @sf_vtzero(i64 %tm, i64 %tn) {
+ entry:
+ call void @llvm.riscv.sf.vtzero.i64(i64 1, i64 %tm, i64 %tn, i64 3, i64 4)
+ ret void
+ }
+
+ declare void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64, <vscale x 32 x half>, <vscale x 32 x half>, i64, i64, i64, i64)
+ declare void @llvm.riscv.sf.mm.f.f.i64.nxv32bf16(i64, <vscale x 32 x bfloat>, <vscale x 32 x bfloat>, i64, i64, i64, i64)
+ declare <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64, i64)
+ declare <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8>, <vscale x 64 x i8>, <vscale x 64 x i8>, i64)
+ declare void @llvm.riscv.sf.vste16.i64(i64, ptr, i64)
+ declare i64 @llvm.riscv.sf.vsettnt_max.i64(i64, i64)
+ declare i64 @llvm.riscv.sf.vsettm.i64(i64, i64, i64)
+ declare i64 @llvm.riscv.sf.vsettn.i64(i64, i64, i64)
+ declare i64 @llvm.riscv.sf.vsettk.i64(i64, i64, i64)
+ declare void @llvm.riscv.sf.vtzero.i64(i64, i64, i64, i64, i64)
+...
+---
+name: xsfmm_same_state
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: vrm8 }
+ - { id: 2, class: gprnox0 }
+ - { id: 3, class: gprnox0 }
+ - { id: 4, class: gprnox0 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$v8m8', virtual-reg: '%1' }
+ - { reg: '$x10', virtual-reg: '%2' }
+ - { reg: '$x11', virtual-reg: '%3' }
+ - { reg: '$x12', virtual-reg: '%4' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-LABEL: name: xsfmm_same_state
+ ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: PseudoRET
+ %4:gprnox0 = COPY $x12
+ %3:gprnox0 = COPY $x11
+ %2:gprnox0 = COPY $x10
+ %1:vrm8 = COPY $v16m8
+ %0:vrm8 = COPY $v8m8
+ PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoRET
+...
+---
+name: xsfmm_different_state
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: vrm8 }
+ - { id: 2, class: gprnox0 }
+ - { id: 3, class: gprnox0 }
+ - { id: 4, class: gprnox0 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$v8m8', virtual-reg: '%1' }
+ - { reg: '$x10', virtual-reg: '%2' }
+ - { reg: '$x11', virtual-reg: '%3' }
+ - { reg: '$x12', virtual-reg: '%4' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-LABEL: name: xsfmm_different_state
+ ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1544 /* e16, w4 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 3, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 3, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 4, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: PseudoRET
+ %4:gprnox0 = COPY $x12
+ %3:gprnox0 = COPY $x11
+ %2:gprnox0 = COPY $x10
+ %1:vrm8 = COPY $v16m8
+ %0:vrm8 = COPY $v8m8
+ PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 4, implicit $frm
+ PseudoRET
+...
+---
+name: xsfmm_different_state_bf
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: vrm8 }
+ - { id: 2, class: gprnox0 }
+ - { id: 3, class: gprnox0 }
+ - { id: 4, class: gprnox0 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$v8m8', virtual-reg: '%1' }
+ - { reg: '$x10', virtual-reg: '%2' }
+ - { reg: '$x11', virtual-reg: '%3' }
+ - { reg: '$x12', virtual-reg: '%4' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-LABEL: name: xsfmm_different_state_bf
+ ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY4]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1288 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F_ALT $t2, [[COPY3]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY4]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: PseudoRET
+ %4:gprnox0 = COPY $x12
+ %3:gprnox0 = COPY $x11
+ %2:gprnox0 = COPY $x10
+ %1:vrm8 = COPY $v16m8
+ %0:vrm8 = COPY $v8m8
+ PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoSF_MM_F_F_ALT $t2, %1:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm
+ PseudoRET
+...
+---
+name: interleave_rvv_and_xsfmm
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: gprnox0 }
+ - { id: 2, class: gpr }
+ - { id: 3, class: gpr }
+ - { id: 4, class: vrm8 }
+ - { id: 5, class: vrm8 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$x10', virtual-reg: '%1' }
+ - { reg: '$x11', virtual-reg: '%2' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $x10, $x11
+ ; CHECK-LABEL: name: interleave_rvv_and_xsfmm
+ ; CHECK: liveins: $v8m8, $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x11
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 512 /* e8, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoSF_VTMV_V_T:%[0-9]+]]:vrm8 = PseudoSF_VTMV_V_T [[ADDI]], $noreg, 3, 1, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoVADD_VV_M8_:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[COPY2]], [[PseudoSF_VTMV_V_T]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: PseudoSF_VSTE16 [[ADDI]], [[COPY]], $noreg, 4, 1, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVADD_VV_M8_]], implicit $vtype
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %2:gpr = COPY $x11
+ %1:gprnox0 = COPY $x10
+ %0:vrm8 = COPY $v8m8
+ %3:gpr = ADDI $x0, 1
+ %4:vrm8 = PseudoSF_VTMV_V_T %3:gpr, %1:gprnox0, 3, 1
+ %5:vrm8 = PseudoVADD_VV_M8 $noreg, %0:vrm8, killed %4:vrm8, %1:gprnox0, 3, 0
+ PseudoSF_VSTE16 %3:gpr, %2:gpr, %1:gprnox0, 4, 1
+ $v8m8 = COPY %5:vrm8
+ PseudoRET implicit $v8m8
+...
+---
+name: interleave_rvv_and_xsfmm2
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: gprnox0 }
+ - { id: 2, class: gpr }
+ - { id: 3, class: gpr }
+ - { id: 4, class: vrm8 }
+ - { id: 5, class: vrm8 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$x10', virtual-reg: '%1' }
+ - { reg: '$x11', virtual-reg: '%2' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $x10, $x11
+ ; CHECK-LABEL: name: interleave_rvv_and_xsfmm2
+ ; CHECK: liveins: $v8m8, $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x11
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1
+ ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoVADD_VV_M8_:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[COPY2]], [[COPY2]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 512 /* e8, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead [[PseudoSF_VTMV_V_T:%[0-9]+]]:vrm8 = PseudoSF_VTMV_V_T [[ADDI]], $noreg, 3, 1, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoVADD_VV_M8_1:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[PseudoVADD_VV_M8_]], [[PseudoVADD_VV_M8_]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: PseudoSF_VSTE16 [[ADDI]], [[COPY]], $noreg, 4, 1, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: $v8m8 = COPY [[PseudoVADD_VV_M8_1]], implicit $vtype
+ ; CHECK-NEXT: PseudoRET implicit $v8m8
+ %2:gpr = COPY $x11
+ %1:gprnox0 = COPY $x10
+ %0:vrm8 = COPY $v8m8
+ %3:gpr = ADDI $x0, 1
+ %4:vrm8 = PseudoVADD_VV_M8 $noreg, %0:vrm8, killed %0:vrm8, %1:gprnox0, 3, 0
+ %5:vrm8 = PseudoSF_VTMV_V_T %3:gpr, %1:gprnox0, 3, 1
+ %6:vrm8 = PseudoVADD_VV_M8 $noreg, %4:vrm8, killed %4:vrm8, %1:gprnox0, 3, 0
+ PseudoSF_VSTE16 %3:gpr, %2:gpr, %1:gprnox0, 4, 1
+ $v8m8 = COPY %6:vrm8
+ PseudoRET implicit $v8m8
+...
+---
+name: consecutive_xsfmm
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: vrm8 }
+ - { id: 1, class: gprnox0 }
+ - { id: 2, class: gprnox0 }
+ - { id: 3, class: gprnox0 }
+ - { id: 4, class: gprnox0 }
+liveins:
+ - { reg: '$v8m8', virtual-reg: '%0' }
+ - { reg: '$x10', virtual-reg: '%1' }
+ - { reg: '$x11', virtual-reg: '%2' }
+ - { reg: '$x12', virtual-reg: '%3' }
+ - { reg: '$x13', virtual-reg: '%4' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $v8m8, $x10, $x11, $x12, $x13
+ ; CHECK-LABEL: name: consecutive_xsfmm
+ ; CHECK: liveins: $v8m8, $x10, $x11, $x12, $x13
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrm8 = COPY $v8m8
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x11
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gprnox0 = COPY $x12
+ ; CHECK-NEXT: dead [[COPY4:%[0-9]+]]:gprnox0 = COPY $x13
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY2]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY1]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY3]], 4, 2, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY]], [[COPY]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY3]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: PseudoSF_VSTE16 [[COPY1]], [[COPY2]], $noreg, 4, 1, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: PseudoRET
+ %0:vrm8 = COPY $v8m8
+ %1:gprnox0 = COPY $x10
+ %2:gprnox0 = COPY $x11
+ %3:gprnox0 = COPY $x12
+ %4:gprnox0 = COPY $x13
+ PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %1:gprnox0, %2:gprnox0, %3:gprnox0, 4, 2, implicit $frm
+ PseudoSF_VSTE16 %1:gprnox0, %2:gprnox0, %3:gprnox0, 4, 1
+ PseudoRET
+...
+---
+name: vsettnt_max
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprnox0 }
+liveins:
+ - { reg: '$x10', virtual-reg: '%0' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $x10
+ ; CHECK-LABEL: name: vsettnt_max
+ ; CHECK: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead [[PseudoSF_VSETTK:%[0-9]+]]:gprnox0 = PseudoSF_VSETTK [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype
+ ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_1:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: [[PseudoSF_VSETTM:%[0-9]+]]:gprnox0 = PseudoSF_VSETTM [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype
+ ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTM]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:gprnox0 = COPY $x10
+ %1:gprnox0 = PseudoSF_VSETTK %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype
+ %2:gprnox0 = PseudoSF_VSETTNTX0 $x0, 520, implicit-def $vl, implicit-def $vtype, implicit $vtype
+ %3:gprnox0 = PseudoSF_VSETTM %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype
+ $x10 = COPY %3:gprnox0
+ PseudoRET implicit $x10
+...
+---
+name: single_vsettm
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprnox0 }
+liveins:
+ - { reg: '$x10', virtual-reg: '%0' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $x10
+ ; CHECK-LABEL: name: single_vsettm
+ ; CHECK: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoSF_VSETTM:%[0-9]+]]:gprnox0 = PseudoSF_VSETTM [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype
+ ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTM]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:gprnox0 = COPY $x10
+ %1:gprnox0 = PseudoSF_VSETTM %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype
+ $x10 = COPY %1:gprnox0
+ PseudoRET implicit $x10
+...
+---
+name: single_vsettn
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprnox0 }
+liveins:
+ - { reg: '$x10', virtual-reg: '%0' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $x10
+ ; CHECK-LABEL: name: single_vsettn
+ ; CHECK: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[PseudoSF_VSETTNT:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNT [[COPY]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTNT]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:gprnox0 = COPY $x10
+ %1:gprnox0 = PseudoSF_VSETTNT %0:gprnox0, 520, implicit-def $vl, implicit-def $vtype, implicit $vtype
+ $x10 = COPY %1:gprnox0
+ PseudoRET implicit $x10
+...
+---
+name: single_vsettk
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprnox0 }
+liveins:
+ - { reg: '$x10', virtual-reg: '%0' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $x10
+ ; CHECK-LABEL: name: single_vsettk
+ ; CHECK: liveins: $x10
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoSF_VSETTK:%[0-9]+]]:gprnox0 = PseudoSF_VSETTK [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype
+ ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTK]]
+ ; CHECK-NEXT: PseudoRET implicit $x10
+ %0:gprnox0 = COPY $x10
+ %1:gprnox0 = PseudoSF_VSETTK %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype
+ $x10 = COPY %1:gprnox0
+ PseudoRET implicit $x10
+...
+---
+name: sf_vtzero
+alignment: 4
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gprnox0 }
+ - { id: 1, class: gprnox0 }
+liveins:
+ - { reg: '$x10', virtual-reg: '%0' }
+ - { reg: '$x11', virtual-reg: '%1' }
+frameInfo:
+ maxAlignment: 1
+machineFunctionInfo: {}
+body: |
+ bb.0.entry:
+ liveins: $x10, $x11
+ ; CHECK-LABEL: name: sf_vtzero
+ ; CHECK: liveins: $x10, $x11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1536 /* e8, w4 */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY]], 3, 3, implicit-def $vtype, implicit $vtype
+ ; CHECK-NEXT: PseudoSF_VTZERO_T $t1, $noreg, $noreg, 3, 4, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: PseudoRET
+ %0:gprnox0 = COPY $x10
+ %1:gprnox0 = COPY $x11
+ PseudoSF_VTZERO_T $t1, %0:gprnox0, %1:gprnox0, 3, 4
+ PseudoRET
+...
diff --git a/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll
new file mode 100644
index 0000000..3654aae
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll
@@ -0,0 +1,106 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mattr=+simd128 | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define <4 x i32> @dot_sext_1(<8 x i16> %a, <8 x i16> %b) {
+; CHECK-LABEL: dot_sext_1:
+; CHECK: .functype dot_sext_1 (v128, v128) -> (v128)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.dot_i16x8_s
+; CHECK-NEXT: # fallthrough-return
+ %sext1 = sext <8 x i16> %a to <8 x i32>
+ %sext2 = sext <8 x i16> %b to <8 x i32>
+ %mul = mul <8 x i32> %sext1, %sext2
+ %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+ %res = add <4 x i32> %shuffle1, %shuffle2
+ ret <4 x i32> %res
+}
+
+
+define <4 x i32> @dot_sext_2(<8 x i16> %a, <8 x i16> %b) {
+; CHECK-LABEL: dot_sext_2:
+; CHECK: .functype dot_sext_2 (v128, v128) -> (v128)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.dot_i16x8_s
+; CHECK-NEXT: # fallthrough-return
+ %sext1 = sext <8 x i16> %a to <8 x i32>
+ %sext2 = sext <8 x i16> %b to <8 x i32>
+ %mul = mul <8 x i32> %sext1, %sext2
+ %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+ %res = add <4 x i32> %shuffle2, %shuffle1
+ ret <4 x i32> %res
+}
+
+define <4 x i32> @dot_sext_self(<8 x i16> %v) {
+; CHECK-LABEL: dot_sext_self:
+; CHECK: .functype dot_sext_self (v128) -> (v128)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: i32x4.dot_i16x8_s
+; CHECK-NEXT: # fallthrough-return
+ %sext = sext <8 x i16> %v to <8 x i32>
+ %mul = mul <8 x i32> %sext, %sext
+ %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+ %res = add <4 x i32> %shuffle1, %shuffle2
+ ret <4 x i32> %res
+}
+
+; INFO: Negative test
+define <4 x i32> @dot_zext(<8 x i16> %a, <8 x i16> %b) {
+; CHECK-LABEL: dot_zext:
+; CHECK: .functype dot_zext (v128, v128) -> (v128)
+; CHECK-NEXT: .local v128
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.extmul_low_i16x8_u
+; CHECK-NEXT: local.tee 2
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.extmul_high_i16x8_u
+; CHECK-NEXT: local.tee 1
+; CHECK-NEXT: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
+; CHECK-NEXT: local.get 2
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
+; CHECK-NEXT: i32x4.add
+; CHECK-NEXT: # fallthrough-return
+ %zext1 = zext <8 x i16> %a to <8 x i32>
+ %zext2 = zext <8 x i16> %b to <8 x i32>
+ %mul = mul <8 x i32> %zext1, %zext2
+ %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+ %res = add <4 x i32> %shuffle1, %shuffle2
+ ret <4 x i32> %res
+}
+
+; INFO: Negative test
+define <4 x i32> @dot_wrong_shuffle(<8 x i16> %a, <8 x i16> %b) {
+; CHECK-LABEL: dot_wrong_shuffle:
+; CHECK: .functype dot_wrong_shuffle (v128, v128) -> (v128)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.extmul_low_i16x8_s
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: i32x4.extmul_high_i16x8_s
+; CHECK-NEXT: i32x4.add
+; CHECK-NEXT: # fallthrough-return
+ %sext1 = sext <8 x i16> %a to <8 x i32>
+ %sext2 = sext <8 x i16> %b to <8 x i32>
+ %mul = mul <8 x i32> %sext1, %sext2
+ %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+ %res = add <4 x i32> %shuffle1, %shuffle2
+ ret <4 x i32> %res
+}
diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll
index e065de3..600241a 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll
@@ -2,9 +2,278 @@
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+fp16,+simd128,+relaxed-simd | FileCheck %s --check-prefix=RELAXED
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+fp16,+simd128, | FileCheck %s --check-prefix=STRICT
+; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefix=NOFP16
+; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=NOSIMD
target triple = "wasm32"
+define half @fadd_fmul_contract_f16(half %a, half %b, half %c) {
+; RELAXED-LABEL: fadd_fmul_contract_f16:
+; RELAXED: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: call $push0=, __truncsfhf2, $0
+; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0
+; RELAXED-NEXT: call $push2=, __truncsfhf2, $1
+; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2
+; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3
+; RELAXED-NEXT: call $push5=, __truncsfhf2, $2
+; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5
+; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6
+; RELAXED-NEXT: return $pop7
+;
+; STRICT-LABEL: fadd_fmul_contract_f16:
+; STRICT: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: call $push0=, __truncsfhf2, $0
+; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0
+; STRICT-NEXT: call $push2=, __truncsfhf2, $1
+; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2
+; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3
+; STRICT-NEXT: call $push5=, __truncsfhf2, $2
+; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5
+; STRICT-NEXT: f32.add $push7=, $pop4, $pop6
+; STRICT-NEXT: return $pop7
+;
+; NOFP16-LABEL: fadd_fmul_contract_f16:
+; NOFP16: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $0
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: return $pop7
+;
+; NOSIMD-LABEL: fadd_fmul_contract_f16:
+; NOSIMD: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $0
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: return $pop7
+ %mul = fmul contract half %b, %a
+ %add = fadd contract half %mul, %c
+ ret half %add
+}
+
+define half @fmuladd_contract_f16(half %a, half %b, half %c) {
+; RELAXED-LABEL: fmuladd_contract_f16:
+; RELAXED: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: call $push0=, __truncsfhf2, $1
+; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0
+; RELAXED-NEXT: call $push2=, __truncsfhf2, $0
+; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2
+; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3
+; RELAXED-NEXT: call $push5=, __truncsfhf2, $2
+; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5
+; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6
+; RELAXED-NEXT: return $pop7
+;
+; STRICT-LABEL: fmuladd_contract_f16:
+; STRICT: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: call $push0=, __truncsfhf2, $1
+; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0
+; STRICT-NEXT: call $push2=, __truncsfhf2, $0
+; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2
+; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3
+; STRICT-NEXT: call $push5=, __truncsfhf2, $2
+; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5
+; STRICT-NEXT: f32.add $push7=, $pop4, $pop6
+; STRICT-NEXT: return $pop7
+;
+; NOFP16-LABEL: fmuladd_contract_f16:
+; NOFP16: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $0
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: return $pop7
+;
+; NOSIMD-LABEL: fmuladd_contract_f16:
+; NOSIMD: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $0
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: return $pop7
+ %fma = call contract half @llvm.fmuladd(half %a, half %b, half %c)
+ ret half %fma
+}
+
+define half @fmuladd_f16(half %a, half %b, half %c) {
+; RELAXED-LABEL: fmuladd_f16:
+; RELAXED: .functype fmuladd_f16 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: call $push0=, __truncsfhf2, $1
+; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0
+; RELAXED-NEXT: call $push2=, __truncsfhf2, $0
+; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2
+; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3
+; RELAXED-NEXT: call $push5=, __truncsfhf2, $2
+; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5
+; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6
+; RELAXED-NEXT: return $pop7
+;
+; STRICT-LABEL: fmuladd_f16:
+; STRICT: .functype fmuladd_f16 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: call $push0=, __truncsfhf2, $1
+; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0
+; STRICT-NEXT: call $push2=, __truncsfhf2, $0
+; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2
+; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3
+; STRICT-NEXT: call $push5=, __truncsfhf2, $2
+; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5
+; STRICT-NEXT: f32.add $push7=, $pop4, $pop6
+; STRICT-NEXT: return $pop7
+;
+; NOFP16-LABEL: fmuladd_f16:
+; NOFP16: .functype fmuladd_f16 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $0
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: return $pop7
+;
+; NOSIMD-LABEL: fmuladd_f16:
+; NOSIMD: .functype fmuladd_f16 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $0
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: return $pop7
+ %fma = call half @llvm.fmuladd(half %a, half %b, half %c)
+ ret half %fma
+}
+
+
+define float @fadd_fmul_contract_f32(float %a, float %b, float %c) {
+; RELAXED-LABEL: fadd_fmul_contract_f32:
+; RELAXED: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f32.mul $push0=, $1, $0
+; RELAXED-NEXT: f32.add $push1=, $pop0, $2
+; RELAXED-NEXT: return $pop1
+;
+; STRICT-LABEL: fadd_fmul_contract_f32:
+; STRICT: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f32.mul $push0=, $1, $0
+; STRICT-NEXT: f32.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fadd_fmul_contract_f32:
+; NOFP16: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32.mul $push0=, $1, $0
+; NOFP16-NEXT: f32.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_contract_f32:
+; NOSIMD: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $1, $0
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
+ %mul = fmul contract float %b, %a
+ %add = fadd contract float %mul, %c
+ ret float %add
+}
+
+define float @fmuladd_contract_f32(float %a, float %b, float %c) {
+; RELAXED-LABEL: fmuladd_contract_f32:
+; RELAXED: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f32.mul $push0=, $0, $1
+; RELAXED-NEXT: f32.add $push1=, $pop0, $2
+; RELAXED-NEXT: return $pop1
+;
+; STRICT-LABEL: fmuladd_contract_f32:
+; STRICT: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f32.mul $push0=, $0, $1
+; STRICT-NEXT: f32.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_contract_f32:
+; NOFP16: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32.mul $push0=, $0, $1
+; NOFP16-NEXT: f32.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_contract_f32:
+; NOSIMD: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $0, $1
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
+ %fma = call contract float @llvm.fmuladd(float %a, float %b, float %c)
+ ret float %fma
+}
+
+define float @fmuladd_f32(float %a, float %b, float %c) {
+; RELAXED-LABEL: fmuladd_f32:
+; RELAXED: .functype fmuladd_f32 (f32, f32, f32) -> (f32)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f32.mul $push0=, $0, $1
+; RELAXED-NEXT: f32.add $push1=, $pop0, $2
+; RELAXED-NEXT: return $pop1
+;
+; STRICT-LABEL: fmuladd_f32:
+; STRICT: .functype fmuladd_f32 (f32, f32, f32) -> (f32)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f32.mul $push0=, $0, $1
+; STRICT-NEXT: f32.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_f32:
+; NOFP16: .functype fmuladd_f32 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32.mul $push0=, $0, $1
+; NOFP16-NEXT: f32.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_f32:
+; NOSIMD: .functype fmuladd_f32 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $0, $1
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
+ %fma = call float @llvm.fmuladd(float %a, float %b, float %c)
+ ret float %fma
+}
+
define double @fadd_fmul_contract_f64(double %a, double %b, double %c) {
; RELAXED-LABEL: fadd_fmul_contract_f64:
; RELAXED: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64)
@@ -19,16 +288,94 @@ define double @fadd_fmul_contract_f64(double %a, double %b, double %c) {
; STRICT-NEXT: f64.mul $push0=, $1, $0
; STRICT-NEXT: f64.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fadd_fmul_contract_f64:
+; NOFP16: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64.mul $push0=, $1, $0
+; NOFP16-NEXT: f64.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_contract_f64:
+; NOSIMD: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $1, $0
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
%mul = fmul contract double %b, %a
%add = fadd contract double %mul, %c
ret double %add
}
+define double @fmuladd_f64(double %a, double %b, double %c) {
+; RELAXED-LABEL: fmuladd_f64:
+; RELAXED: .functype fmuladd_f64 (f64, f64, f64) -> (f64)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f64.mul $push0=, $0, $1
+; RELAXED-NEXT: f64.add $push1=, $pop0, $2
+; RELAXED-NEXT: return $pop1
+;
+; STRICT-LABEL: fmuladd_f64:
+; STRICT: .functype fmuladd_f64 (f64, f64, f64) -> (f64)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f64.mul $push0=, $0, $1
+; STRICT-NEXT: f64.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_f64:
+; NOFP16: .functype fmuladd_f64 (f64, f64, f64) -> (f64)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64.mul $push0=, $0, $1
+; NOFP16-NEXT: f64.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_f64:
+; NOSIMD: .functype fmuladd_f64 (f64, f64, f64) -> (f64)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $0, $1
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
+ %fma = call double @llvm.fmuladd(double %a, double %b, double %c)
+ ret double %fma
+}
+
+define double @fmuladd_contract_f64(double %a, double %b, double %c) {
+; RELAXED-LABEL: fmuladd_contract_f64:
+; RELAXED: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f64.mul $push0=, $0, $1
+; RELAXED-NEXT: f64.add $push1=, $pop0, $2
+; RELAXED-NEXT: return $pop1
+;
+; STRICT-LABEL: fmuladd_contract_f64:
+; STRICT: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f64.mul $push0=, $0, $1
+; STRICT-NEXT: f64.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_contract_f64:
+; NOFP16: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64.mul $push0=, $0, $1
+; NOFP16-NEXT: f64.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_contract_f64:
+; NOSIMD: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $0, $1
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $2
+; NOSIMD-NEXT: return $pop1
+ %fma = call contract double @llvm.fmuladd(double %a, double %b, double %c)
+ ret double %fma
+}
+
define <4 x float> @fadd_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; RELAXED-LABEL: fadd_fmul_contract_4xf32:
; RELAXED: .functype fadd_fmul_contract_4xf32 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $2, $1, $0
+; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fadd_fmul_contract_4xf32:
@@ -37,31 +384,222 @@ define <4 x float> @fadd_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4
; STRICT-NEXT: f32x4.mul $push0=, $1, $0
; STRICT-NEXT: f32x4.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fadd_fmul_contract_4xf32:
+; NOFP16: .functype fadd_fmul_contract_4xf32 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $1, $0
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_contract_4xf32:
+; NOSIMD: .functype fadd_fmul_contract_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $8, $4
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $12
+; NOSIMD-NEXT: f32.store 12($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $7, $3
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $11
+; NOSIMD-NEXT: f32.store 8($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $6, $2
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $10
+; NOSIMD-NEXT: f32.store 4($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $5, $1
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $9
+; NOSIMD-NEXT: f32.store 0($0), $pop7
+; NOSIMD-NEXT: return
%mul = fmul contract <4 x float> %b, %a
%add = fadd contract <4 x float> %mul, %c
ret <4 x float> %add
}
-
define <8 x half> @fadd_fmul_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) {
; RELAXED-LABEL: fadd_fmul_contract_8xf16:
; RELAXED: .functype fadd_fmul_contract_8xf16 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f16x8.relaxed_madd $push0=, $2, $1, $0
+; RELAXED-NEXT: f16x8.madd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fadd_fmul_contract_8xf16:
; STRICT: .functype fadd_fmul_contract_8xf16 (v128, v128, v128) -> (v128)
; STRICT-NEXT: # %bb.0:
-; STRICT-NEXT: f16x8.mul $push0=, $1, $0
-; STRICT-NEXT: f16x8.add $push1=, $pop0, $2
-; STRICT-NEXT: return $pop1
+; STRICT-NEXT: f16x8.madd $push0=, $1, $0, $2
+; STRICT-NEXT: return $pop0
+;
+; NOFP16-LABEL: fadd_fmul_contract_8xf16:
+; NOFP16: .functype fadd_fmul_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $8
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $16
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $24
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOFP16-NEXT: i32.store16 14($0), $pop8
+; NOFP16-NEXT: call $push9=, __truncsfhf2, $7
+; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOFP16-NEXT: call $push11=, __truncsfhf2, $15
+; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOFP16-NEXT: call $push14=, __truncsfhf2, $23
+; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15
+; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOFP16-NEXT: i32.store16 12($0), $pop17
+; NOFP16-NEXT: call $push18=, __truncsfhf2, $6
+; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOFP16-NEXT: call $push20=, __truncsfhf2, $14
+; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOFP16-NEXT: call $push23=, __truncsfhf2, $22
+; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24
+; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOFP16-NEXT: i32.store16 10($0), $pop26
+; NOFP16-NEXT: call $push27=, __truncsfhf2, $5
+; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOFP16-NEXT: call $push29=, __truncsfhf2, $13
+; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOFP16-NEXT: call $push32=, __truncsfhf2, $21
+; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33
+; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOFP16-NEXT: i32.store16 8($0), $pop35
+; NOFP16-NEXT: call $push36=, __truncsfhf2, $4
+; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOFP16-NEXT: call $push38=, __truncsfhf2, $12
+; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOFP16-NEXT: call $push41=, __truncsfhf2, $20
+; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42
+; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOFP16-NEXT: i32.store16 6($0), $pop44
+; NOFP16-NEXT: call $push45=, __truncsfhf2, $3
+; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOFP16-NEXT: call $push47=, __truncsfhf2, $11
+; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOFP16-NEXT: call $push50=, __truncsfhf2, $19
+; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51
+; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOFP16-NEXT: i32.store16 4($0), $pop53
+; NOFP16-NEXT: call $push54=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOFP16-NEXT: call $push56=, __truncsfhf2, $10
+; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOFP16-NEXT: call $push59=, __truncsfhf2, $18
+; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60
+; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOFP16-NEXT: i32.store16 2($0), $pop62
+; NOFP16-NEXT: call $push63=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOFP16-NEXT: call $push65=, __truncsfhf2, $9
+; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOFP16-NEXT: call $push68=, __truncsfhf2, $17
+; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69
+; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOFP16-NEXT: i32.store16 0($0), $pop71
+; NOFP16-NEXT: return
+;
+; NOSIMD-LABEL: fadd_fmul_contract_8xf16:
+; NOSIMD: .functype fadd_fmul_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $8
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $16
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOSIMD-NEXT: i32.store16 14($0), $pop8
+; NOSIMD-NEXT: call $push9=, __truncsfhf2, $7
+; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOSIMD-NEXT: call $push11=, __truncsfhf2, $15
+; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23
+; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15
+; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOSIMD-NEXT: i32.store16 12($0), $pop17
+; NOSIMD-NEXT: call $push18=, __truncsfhf2, $6
+; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOSIMD-NEXT: call $push20=, __truncsfhf2, $14
+; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22
+; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24
+; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOSIMD-NEXT: i32.store16 10($0), $pop26
+; NOSIMD-NEXT: call $push27=, __truncsfhf2, $5
+; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOSIMD-NEXT: call $push29=, __truncsfhf2, $13
+; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21
+; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33
+; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOSIMD-NEXT: i32.store16 8($0), $pop35
+; NOSIMD-NEXT: call $push36=, __truncsfhf2, $4
+; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOSIMD-NEXT: call $push38=, __truncsfhf2, $12
+; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20
+; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42
+; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOSIMD-NEXT: i32.store16 6($0), $pop44
+; NOSIMD-NEXT: call $push45=, __truncsfhf2, $3
+; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOSIMD-NEXT: call $push47=, __truncsfhf2, $11
+; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19
+; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51
+; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOSIMD-NEXT: i32.store16 4($0), $pop53
+; NOSIMD-NEXT: call $push54=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOSIMD-NEXT: call $push56=, __truncsfhf2, $10
+; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18
+; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60
+; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOSIMD-NEXT: i32.store16 2($0), $pop62
+; NOSIMD-NEXT: call $push63=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOSIMD-NEXT: call $push65=, __truncsfhf2, $9
+; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17
+; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69
+; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOSIMD-NEXT: i32.store16 0($0), $pop71
+; NOSIMD-NEXT: return
%mul = fmul contract <8 x half> %b, %a
%add = fadd contract <8 x half> %mul, %c
ret <8 x half> %add
}
-
define <4 x float> @fadd_fmul_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; RELAXED-LABEL: fadd_fmul_4xf32:
; RELAXED: .functype fadd_fmul_4xf32 (v128, v128, v128) -> (v128)
@@ -76,16 +614,412 @@ define <4 x float> @fadd_fmul_4xf32(<4 x float> %a, <4 x float> %b, <4 x float>
; STRICT-NEXT: f32x4.mul $push0=, $1, $0
; STRICT-NEXT: f32x4.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fadd_fmul_4xf32:
+; NOFP16: .functype fadd_fmul_4xf32 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $1, $0
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_4xf32:
+; NOSIMD: .functype fadd_fmul_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $8, $4
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $12
+; NOSIMD-NEXT: f32.store 12($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $7, $3
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $11
+; NOSIMD-NEXT: f32.store 8($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $6, $2
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $10
+; NOSIMD-NEXT: f32.store 4($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $5, $1
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $9
+; NOSIMD-NEXT: f32.store 0($0), $pop7
+; NOSIMD-NEXT: return
%mul = fmul <4 x float> %b, %a
%add = fadd contract <4 x float> %mul, %c
ret <4 x float> %add
}
+define <8 x half> @fmuladd_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) {
+; RELAXED-LABEL: fmuladd_contract_8xf16:
+; RELAXED: .functype fmuladd_contract_8xf16 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f16x8.madd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_contract_8xf16:
+; STRICT: .functype fmuladd_contract_8xf16 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f16x8.madd $push0=, $0, $1, $2
+; STRICT-NEXT: return $pop0
+;
+; NOFP16-LABEL: fmuladd_contract_8xf16:
+; NOFP16: .functype fmuladd_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $16
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $8
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $24
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOFP16-NEXT: i32.store16 14($0), $pop8
+; NOFP16-NEXT: call $push9=, __truncsfhf2, $15
+; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOFP16-NEXT: call $push11=, __truncsfhf2, $7
+; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOFP16-NEXT: call $push14=, __truncsfhf2, $23
+; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15
+; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOFP16-NEXT: i32.store16 12($0), $pop17
+; NOFP16-NEXT: call $push18=, __truncsfhf2, $14
+; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOFP16-NEXT: call $push20=, __truncsfhf2, $6
+; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOFP16-NEXT: call $push23=, __truncsfhf2, $22
+; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24
+; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOFP16-NEXT: i32.store16 10($0), $pop26
+; NOFP16-NEXT: call $push27=, __truncsfhf2, $13
+; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOFP16-NEXT: call $push29=, __truncsfhf2, $5
+; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOFP16-NEXT: call $push32=, __truncsfhf2, $21
+; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33
+; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOFP16-NEXT: i32.store16 8($0), $pop35
+; NOFP16-NEXT: call $push36=, __truncsfhf2, $12
+; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOFP16-NEXT: call $push38=, __truncsfhf2, $4
+; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOFP16-NEXT: call $push41=, __truncsfhf2, $20
+; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42
+; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOFP16-NEXT: i32.store16 6($0), $pop44
+; NOFP16-NEXT: call $push45=, __truncsfhf2, $11
+; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOFP16-NEXT: call $push47=, __truncsfhf2, $3
+; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOFP16-NEXT: call $push50=, __truncsfhf2, $19
+; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51
+; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOFP16-NEXT: i32.store16 4($0), $pop53
+; NOFP16-NEXT: call $push54=, __truncsfhf2, $10
+; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOFP16-NEXT: call $push56=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOFP16-NEXT: call $push59=, __truncsfhf2, $18
+; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60
+; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOFP16-NEXT: i32.store16 2($0), $pop62
+; NOFP16-NEXT: call $push63=, __truncsfhf2, $9
+; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOFP16-NEXT: call $push65=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOFP16-NEXT: call $push68=, __truncsfhf2, $17
+; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69
+; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOFP16-NEXT: i32.store16 0($0), $pop71
+; NOFP16-NEXT: return
+;
+; NOSIMD-LABEL: fmuladd_contract_8xf16:
+; NOSIMD: .functype fmuladd_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $16
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $8
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOSIMD-NEXT: i32.store16 14($0), $pop8
+; NOSIMD-NEXT: call $push9=, __truncsfhf2, $15
+; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOSIMD-NEXT: call $push11=, __truncsfhf2, $7
+; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23
+; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15
+; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOSIMD-NEXT: i32.store16 12($0), $pop17
+; NOSIMD-NEXT: call $push18=, __truncsfhf2, $14
+; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOSIMD-NEXT: call $push20=, __truncsfhf2, $6
+; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22
+; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24
+; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOSIMD-NEXT: i32.store16 10($0), $pop26
+; NOSIMD-NEXT: call $push27=, __truncsfhf2, $13
+; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOSIMD-NEXT: call $push29=, __truncsfhf2, $5
+; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21
+; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33
+; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOSIMD-NEXT: i32.store16 8($0), $pop35
+; NOSIMD-NEXT: call $push36=, __truncsfhf2, $12
+; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOSIMD-NEXT: call $push38=, __truncsfhf2, $4
+; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20
+; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42
+; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOSIMD-NEXT: i32.store16 6($0), $pop44
+; NOSIMD-NEXT: call $push45=, __truncsfhf2, $11
+; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOSIMD-NEXT: call $push47=, __truncsfhf2, $3
+; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19
+; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51
+; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOSIMD-NEXT: i32.store16 4($0), $pop53
+; NOSIMD-NEXT: call $push54=, __truncsfhf2, $10
+; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOSIMD-NEXT: call $push56=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18
+; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60
+; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOSIMD-NEXT: i32.store16 2($0), $pop62
+; NOSIMD-NEXT: call $push63=, __truncsfhf2, $9
+; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOSIMD-NEXT: call $push65=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17
+; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69
+; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOSIMD-NEXT: i32.store16 0($0), $pop71
+; NOSIMD-NEXT: return
+ %fma = call contract <8 x half> @llvm.fmuladd(<8 x half> %a, <8 x half> %b, <8 x half> %c)
+ ret <8 x half> %fma
+}
+
+define <8 x half> @fmuladd_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) {
+; RELAXED-LABEL: fmuladd_8xf16:
+; RELAXED: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f16x8.madd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_8xf16:
+; STRICT: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f16x8.madd $push0=, $0, $1, $2
+; STRICT-NEXT: return $pop0
+;
+; NOFP16-LABEL: fmuladd_8xf16:
+; NOFP16: .functype fmuladd_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, __truncsfhf2, $16
+; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOFP16-NEXT: call $push2=, __truncsfhf2, $8
+; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOFP16-NEXT: call $push5=, __truncsfhf2, $24
+; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6
+; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOFP16-NEXT: i32.store16 14($0), $pop8
+; NOFP16-NEXT: call $push9=, __truncsfhf2, $15
+; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOFP16-NEXT: call $push11=, __truncsfhf2, $7
+; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOFP16-NEXT: call $push14=, __truncsfhf2, $23
+; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15
+; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOFP16-NEXT: i32.store16 12($0), $pop17
+; NOFP16-NEXT: call $push18=, __truncsfhf2, $14
+; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOFP16-NEXT: call $push20=, __truncsfhf2, $6
+; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOFP16-NEXT: call $push23=, __truncsfhf2, $22
+; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24
+; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOFP16-NEXT: i32.store16 10($0), $pop26
+; NOFP16-NEXT: call $push27=, __truncsfhf2, $13
+; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOFP16-NEXT: call $push29=, __truncsfhf2, $5
+; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOFP16-NEXT: call $push32=, __truncsfhf2, $21
+; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33
+; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOFP16-NEXT: i32.store16 8($0), $pop35
+; NOFP16-NEXT: call $push36=, __truncsfhf2, $12
+; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOFP16-NEXT: call $push38=, __truncsfhf2, $4
+; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOFP16-NEXT: call $push41=, __truncsfhf2, $20
+; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42
+; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOFP16-NEXT: i32.store16 6($0), $pop44
+; NOFP16-NEXT: call $push45=, __truncsfhf2, $11
+; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOFP16-NEXT: call $push47=, __truncsfhf2, $3
+; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOFP16-NEXT: call $push50=, __truncsfhf2, $19
+; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51
+; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOFP16-NEXT: i32.store16 4($0), $pop53
+; NOFP16-NEXT: call $push54=, __truncsfhf2, $10
+; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOFP16-NEXT: call $push56=, __truncsfhf2, $2
+; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOFP16-NEXT: call $push59=, __truncsfhf2, $18
+; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60
+; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOFP16-NEXT: i32.store16 2($0), $pop62
+; NOFP16-NEXT: call $push63=, __truncsfhf2, $9
+; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOFP16-NEXT: call $push65=, __truncsfhf2, $1
+; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOFP16-NEXT: call $push68=, __truncsfhf2, $17
+; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69
+; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOFP16-NEXT: i32.store16 0($0), $pop71
+; NOFP16-NEXT: return
+;
+; NOSIMD-LABEL: fmuladd_8xf16:
+; NOSIMD: .functype fmuladd_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, __truncsfhf2, $16
+; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0
+; NOSIMD-NEXT: call $push2=, __truncsfhf2, $8
+; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2
+; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3
+; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24
+; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5
+; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6
+; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7
+; NOSIMD-NEXT: i32.store16 14($0), $pop8
+; NOSIMD-NEXT: call $push9=, __truncsfhf2, $15
+; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9
+; NOSIMD-NEXT: call $push11=, __truncsfhf2, $7
+; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11
+; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12
+; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23
+; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14
+; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15
+; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16
+; NOSIMD-NEXT: i32.store16 12($0), $pop17
+; NOSIMD-NEXT: call $push18=, __truncsfhf2, $14
+; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18
+; NOSIMD-NEXT: call $push20=, __truncsfhf2, $6
+; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20
+; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21
+; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22
+; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23
+; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24
+; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25
+; NOSIMD-NEXT: i32.store16 10($0), $pop26
+; NOSIMD-NEXT: call $push27=, __truncsfhf2, $13
+; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27
+; NOSIMD-NEXT: call $push29=, __truncsfhf2, $5
+; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29
+; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30
+; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21
+; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32
+; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33
+; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34
+; NOSIMD-NEXT: i32.store16 8($0), $pop35
+; NOSIMD-NEXT: call $push36=, __truncsfhf2, $12
+; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36
+; NOSIMD-NEXT: call $push38=, __truncsfhf2, $4
+; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38
+; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39
+; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20
+; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41
+; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42
+; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43
+; NOSIMD-NEXT: i32.store16 6($0), $pop44
+; NOSIMD-NEXT: call $push45=, __truncsfhf2, $11
+; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45
+; NOSIMD-NEXT: call $push47=, __truncsfhf2, $3
+; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47
+; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48
+; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19
+; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50
+; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51
+; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52
+; NOSIMD-NEXT: i32.store16 4($0), $pop53
+; NOSIMD-NEXT: call $push54=, __truncsfhf2, $10
+; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54
+; NOSIMD-NEXT: call $push56=, __truncsfhf2, $2
+; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56
+; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57
+; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18
+; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59
+; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60
+; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61
+; NOSIMD-NEXT: i32.store16 2($0), $pop62
+; NOSIMD-NEXT: call $push63=, __truncsfhf2, $9
+; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63
+; NOSIMD-NEXT: call $push65=, __truncsfhf2, $1
+; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65
+; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66
+; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17
+; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68
+; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69
+; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70
+; NOSIMD-NEXT: i32.store16 0($0), $pop71
+; NOSIMD-NEXT: return
+ %fma = call <8 x half> @llvm.fmuladd(<8 x half> %a, <8 x half> %b, <8 x half> %c)
+ ret <8 x half> %fma
+}
+
define <4 x float> @fmuladd_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; RELAXED-LABEL: fmuladd_contract_4xf32:
; RELAXED: .functype fmuladd_contract_4xf32 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $2, $0, $1
+; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $0, $1, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fmuladd_contract_4xf32:
@@ -94,18 +1028,40 @@ define <4 x float> @fmuladd_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x
; STRICT-NEXT: f32x4.mul $push0=, $0, $1
; STRICT-NEXT: f32x4.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_contract_4xf32:
+; NOFP16: .functype fmuladd_contract_4xf32 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $0, $1
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_contract_4xf32:
+; NOSIMD: .functype fmuladd_contract_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $4, $8
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $12
+; NOSIMD-NEXT: f32.store 12($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $3, $7
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $11
+; NOSIMD-NEXT: f32.store 8($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $2, $6
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $10
+; NOSIMD-NEXT: f32.store 4($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $1, $5
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $9
+; NOSIMD-NEXT: f32.store 0($0), $pop7
+; NOSIMD-NEXT: return
%fma = call contract <4 x float> @llvm.fmuladd(<4 x float> %a, <4 x float> %b, <4 x float> %c)
ret <4 x float> %fma
}
-; TODO: This should also have relaxed_madd in RELAXED case
define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; RELAXED-LABEL: fmuladd_4xf32:
; RELAXED: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.mul $push0=, $0, $1
-; RELAXED-NEXT: f32x4.add $push1=, $pop0, $2
-; RELAXED-NEXT: return $pop1
+; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fmuladd_4xf32:
; STRICT: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128)
@@ -113,10 +1069,170 @@ define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c
; STRICT-NEXT: f32x4.mul $push0=, $0, $1
; STRICT-NEXT: f32x4.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_4xf32:
+; NOFP16: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $0, $1
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_4xf32:
+; NOSIMD: .functype fmuladd_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $4, $8
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $12
+; NOSIMD-NEXT: f32.store 12($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $3, $7
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $11
+; NOSIMD-NEXT: f32.store 8($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $2, $6
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $10
+; NOSIMD-NEXT: f32.store 4($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $1, $5
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $9
+; NOSIMD-NEXT: f32.store 0($0), $pop7
+; NOSIMD-NEXT: return
%fma = call <4 x float> @llvm.fmuladd(<4 x float> %a, <4 x float> %b, <4 x float> %c)
ret <4 x float> %fma
}
+define <8 x float> @fmuladd_8xf32(<8 x float> %a, <8 x float> %b, <8 x float> %c) {
+; RELAXED-LABEL: fmuladd_8xf32:
+; RELAXED: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f32x4.mul $push0=, $2, $4
+; RELAXED-NEXT: f32x4.add $push1=, $pop0, $6
+; RELAXED-NEXT: v128.store 16($0), $pop1
+; RELAXED-NEXT: f32x4.mul $push2=, $1, $3
+; RELAXED-NEXT: f32x4.add $push3=, $pop2, $5
+; RELAXED-NEXT: v128.store 0($0), $pop3
+; RELAXED-NEXT: return
+;
+; STRICT-LABEL: fmuladd_8xf32:
+; STRICT: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f32x4.mul $push0=, $2, $4
+; STRICT-NEXT: f32x4.add $push1=, $pop0, $6
+; STRICT-NEXT: v128.store 16($0), $pop1
+; STRICT-NEXT: f32x4.mul $push2=, $1, $3
+; STRICT-NEXT: f32x4.add $push3=, $pop2, $5
+; STRICT-NEXT: v128.store 0($0), $pop3
+; STRICT-NEXT: return
+;
+; NOFP16-LABEL: fmuladd_8xf32:
+; NOFP16: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $2, $4
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $6
+; NOFP16-NEXT: v128.store 16($0), $pop1
+; NOFP16-NEXT: f32x4.mul $push2=, $1, $3
+; NOFP16-NEXT: f32x4.add $push3=, $pop2, $5
+; NOFP16-NEXT: v128.store 0($0), $pop3
+; NOFP16-NEXT: return
+;
+; NOSIMD-LABEL: fmuladd_8xf32:
+; NOSIMD: .functype fmuladd_8xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $8, $16
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $24
+; NOSIMD-NEXT: f32.store 28($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $7, $15
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $23
+; NOSIMD-NEXT: f32.store 24($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $6, $14
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $22
+; NOSIMD-NEXT: f32.store 20($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $5, $13
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $21
+; NOSIMD-NEXT: f32.store 16($0), $pop7
+; NOSIMD-NEXT: f32.mul $push8=, $4, $12
+; NOSIMD-NEXT: f32.add $push9=, $pop8, $20
+; NOSIMD-NEXT: f32.store 12($0), $pop9
+; NOSIMD-NEXT: f32.mul $push10=, $3, $11
+; NOSIMD-NEXT: f32.add $push11=, $pop10, $19
+; NOSIMD-NEXT: f32.store 8($0), $pop11
+; NOSIMD-NEXT: f32.mul $push12=, $2, $10
+; NOSIMD-NEXT: f32.add $push13=, $pop12, $18
+; NOSIMD-NEXT: f32.store 4($0), $pop13
+; NOSIMD-NEXT: f32.mul $push14=, $1, $9
+; NOSIMD-NEXT: f32.add $push15=, $pop14, $17
+; NOSIMD-NEXT: f32.store 0($0), $pop15
+; NOSIMD-NEXT: return
+ %fma = call <8 x float> @llvm.fmuladd(<8 x float> %a, <8 x float> %b, <8 x float> %c)
+ ret <8 x float> %fma
+}
+
+define <2 x double> @fmuladd_contract_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) {
+; RELAXED-LABEL: fmuladd_contract_2xf64:
+; RELAXED: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_contract_2xf64:
+; STRICT: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f64x2.mul $push0=, $0, $1
+; STRICT-NEXT: f64x2.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_contract_2xf64:
+; NOFP16: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64x2.mul $push0=, $0, $1
+; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_contract_2xf64:
+; NOSIMD: .functype fmuladd_contract_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $2, $4
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $6
+; NOSIMD-NEXT: f64.store 8($0), $pop1
+; NOSIMD-NEXT: f64.mul $push2=, $1, $3
+; NOSIMD-NEXT: f64.add $push3=, $pop2, $5
+; NOSIMD-NEXT: f64.store 0($0), $pop3
+; NOSIMD-NEXT: return
+ %fma = call contract <2 x double> @llvm.fmuladd(<2 x double> %a, <2 x double> %b, <2 x double> %c)
+ ret <2 x double> %fma
+}
+
+define <2 x double> @fmuladd_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) {
+; RELAXED-LABEL: fmuladd_2xf64:
+; RELAXED: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_2xf64:
+; STRICT: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f64x2.mul $push0=, $0, $1
+; STRICT-NEXT: f64x2.add $push1=, $pop0, $2
+; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fmuladd_2xf64:
+; NOFP16: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64x2.mul $push0=, $0, $1
+; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fmuladd_2xf64:
+; NOSIMD: .functype fmuladd_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $2, $4
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $6
+; NOSIMD-NEXT: f64.store 8($0), $pop1
+; NOSIMD-NEXT: f64.mul $push2=, $1, $3
+; NOSIMD-NEXT: f64.add $push3=, $pop2, $5
+; NOSIMD-NEXT: f64.store 0($0), $pop3
+; NOSIMD-NEXT: return
+ %fma = call <2 x double> @llvm.fmuladd(<2 x double> %a, <2 x double> %b, <2 x double> %c)
+ ret <2 x double> %fma
+}
+
define <4 x float> @fma_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; RELAXED-LABEL: fma_4xf32:
; RELAXED: .functype fma_4xf32 (v128, v128, v128) -> (v128)
@@ -167,6 +1283,44 @@ define <4 x float> @fma_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
; STRICT-NEXT: call $push18=, fmaf, $pop17, $pop16, $pop15
; STRICT-NEXT: f32x4.replace_lane $push19=, $pop14, 3, $pop18
; STRICT-NEXT: return $pop19
+;
+; NOFP16-LABEL: fma_4xf32:
+; NOFP16: .functype fma_4xf32 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.extract_lane $push2=, $0, 0
+; NOFP16-NEXT: f32x4.extract_lane $push1=, $1, 0
+; NOFP16-NEXT: f32x4.extract_lane $push0=, $2, 0
+; NOFP16-NEXT: call $push3=, fmaf, $pop2, $pop1, $pop0
+; NOFP16-NEXT: f32x4.splat $push4=, $pop3
+; NOFP16-NEXT: f32x4.extract_lane $push7=, $0, 1
+; NOFP16-NEXT: f32x4.extract_lane $push6=, $1, 1
+; NOFP16-NEXT: f32x4.extract_lane $push5=, $2, 1
+; NOFP16-NEXT: call $push8=, fmaf, $pop7, $pop6, $pop5
+; NOFP16-NEXT: f32x4.replace_lane $push9=, $pop4, 1, $pop8
+; NOFP16-NEXT: f32x4.extract_lane $push12=, $0, 2
+; NOFP16-NEXT: f32x4.extract_lane $push11=, $1, 2
+; NOFP16-NEXT: f32x4.extract_lane $push10=, $2, 2
+; NOFP16-NEXT: call $push13=, fmaf, $pop12, $pop11, $pop10
+; NOFP16-NEXT: f32x4.replace_lane $push14=, $pop9, 2, $pop13
+; NOFP16-NEXT: f32x4.extract_lane $push17=, $0, 3
+; NOFP16-NEXT: f32x4.extract_lane $push16=, $1, 3
+; NOFP16-NEXT: f32x4.extract_lane $push15=, $2, 3
+; NOFP16-NEXT: call $push18=, fmaf, $pop17, $pop16, $pop15
+; NOFP16-NEXT: f32x4.replace_lane $push19=, $pop14, 3, $pop18
+; NOFP16-NEXT: return $pop19
+;
+; NOSIMD-LABEL: fma_4xf32:
+; NOSIMD: .functype fma_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, fmaf, $4, $8, $12
+; NOSIMD-NEXT: f32.store 12($0), $pop0
+; NOSIMD-NEXT: call $push1=, fmaf, $3, $7, $11
+; NOSIMD-NEXT: f32.store 8($0), $pop1
+; NOSIMD-NEXT: call $push2=, fmaf, $2, $6, $10
+; NOSIMD-NEXT: f32.store 4($0), $pop2
+; NOSIMD-NEXT: call $push3=, fmaf, $1, $5, $9
+; NOSIMD-NEXT: f32.store 0($0), $pop3
+; NOSIMD-NEXT: return
%fma = call <4 x float> @llvm.fma(<4 x float> %a, <4 x float> %b, <4 x float> %c)
ret <4 x float> %fma
}
@@ -176,9 +1330,9 @@ define <8 x float> @fadd_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8
; RELAXED-LABEL: fadd_fmul_contract_8xf32:
; RELAXED: .functype fadd_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $6, $4, $2
+; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $4, $2, $6
; RELAXED-NEXT: v128.store 16($0), $pop0
-; RELAXED-NEXT: f32x4.relaxed_madd $push1=, $5, $3, $1
+; RELAXED-NEXT: f32x4.relaxed_madd $push1=, $3, $1, $5
; RELAXED-NEXT: v128.store 0($0), $pop1
; RELAXED-NEXT: return
;
@@ -192,17 +1346,56 @@ define <8 x float> @fadd_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8
; STRICT-NEXT: f32x4.add $push3=, $pop2, $5
; STRICT-NEXT: v128.store 0($0), $pop3
; STRICT-NEXT: return
+;
+; NOFP16-LABEL: fadd_fmul_contract_8xf32:
+; NOFP16: .functype fadd_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f32x4.mul $push0=, $4, $2
+; NOFP16-NEXT: f32x4.add $push1=, $pop0, $6
+; NOFP16-NEXT: v128.store 16($0), $pop1
+; NOFP16-NEXT: f32x4.mul $push2=, $3, $1
+; NOFP16-NEXT: f32x4.add $push3=, $pop2, $5
+; NOFP16-NEXT: v128.store 0($0), $pop3
+; NOFP16-NEXT: return
+;
+; NOSIMD-LABEL: fadd_fmul_contract_8xf32:
+; NOSIMD: .functype fadd_fmul_contract_8xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f32.mul $push0=, $16, $8
+; NOSIMD-NEXT: f32.add $push1=, $pop0, $24
+; NOSIMD-NEXT: f32.store 28($0), $pop1
+; NOSIMD-NEXT: f32.mul $push2=, $15, $7
+; NOSIMD-NEXT: f32.add $push3=, $pop2, $23
+; NOSIMD-NEXT: f32.store 24($0), $pop3
+; NOSIMD-NEXT: f32.mul $push4=, $14, $6
+; NOSIMD-NEXT: f32.add $push5=, $pop4, $22
+; NOSIMD-NEXT: f32.store 20($0), $pop5
+; NOSIMD-NEXT: f32.mul $push6=, $13, $5
+; NOSIMD-NEXT: f32.add $push7=, $pop6, $21
+; NOSIMD-NEXT: f32.store 16($0), $pop7
+; NOSIMD-NEXT: f32.mul $push8=, $12, $4
+; NOSIMD-NEXT: f32.add $push9=, $pop8, $20
+; NOSIMD-NEXT: f32.store 12($0), $pop9
+; NOSIMD-NEXT: f32.mul $push10=, $11, $3
+; NOSIMD-NEXT: f32.add $push11=, $pop10, $19
+; NOSIMD-NEXT: f32.store 8($0), $pop11
+; NOSIMD-NEXT: f32.mul $push12=, $10, $2
+; NOSIMD-NEXT: f32.add $push13=, $pop12, $18
+; NOSIMD-NEXT: f32.store 4($0), $pop13
+; NOSIMD-NEXT: f32.mul $push14=, $9, $1
+; NOSIMD-NEXT: f32.add $push15=, $pop14, $17
+; NOSIMD-NEXT: f32.store 0($0), $pop15
+; NOSIMD-NEXT: return
%mul = fmul contract <8 x float> %b, %a
%add = fadd contract <8 x float> %mul, %c
ret <8 x float> %add
}
-
define <2 x double> @fadd_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) {
; RELAXED-LABEL: fadd_fmul_contract_2xf64:
; RELAXED: .functype fadd_fmul_contract_2xf64 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $2, $1, $0
+; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fadd_fmul_contract_2xf64:
@@ -211,28 +1404,64 @@ define <2 x double> @fadd_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b,
; STRICT-NEXT: f64x2.mul $push0=, $1, $0
; STRICT-NEXT: f64x2.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
+;
+; NOFP16-LABEL: fadd_fmul_contract_2xf64:
+; NOFP16: .functype fadd_fmul_contract_2xf64 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64x2.mul $push0=, $1, $0
+; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_contract_2xf64:
+; NOSIMD: .functype fadd_fmul_contract_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $4, $2
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $6
+; NOSIMD-NEXT: f64.store 8($0), $pop1
+; NOSIMD-NEXT: f64.mul $push2=, $3, $1
+; NOSIMD-NEXT: f64.add $push3=, $pop2, $5
+; NOSIMD-NEXT: f64.store 0($0), $pop3
+; NOSIMD-NEXT: return
%mul = fmul contract <2 x double> %b, %a
%add = fadd contract <2 x double> %mul, %c
ret <2 x double> %add
}
-define float @fadd_fmul_contract_f32(float %a, float %b, float %c) {
-; RELAXED-LABEL: fadd_fmul_contract_f32:
-; RELAXED: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+define <2 x double> @fadd_fmul_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) {
+; RELAXED-LABEL: fadd_fmul_2xf64:
+; RELAXED: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32.mul $push0=, $1, $0
-; RELAXED-NEXT: f32.add $push1=, $pop0, $2
+; RELAXED-NEXT: f64x2.mul $push0=, $1, $0
+; RELAXED-NEXT: f64x2.add $push1=, $pop0, $2
; RELAXED-NEXT: return $pop1
;
-; STRICT-LABEL: fadd_fmul_contract_f32:
-; STRICT: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32)
+; STRICT-LABEL: fadd_fmul_2xf64:
+; STRICT: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128)
; STRICT-NEXT: # %bb.0:
-; STRICT-NEXT: f32.mul $push0=, $1, $0
-; STRICT-NEXT: f32.add $push1=, $pop0, $2
+; STRICT-NEXT: f64x2.mul $push0=, $1, $0
+; STRICT-NEXT: f64x2.add $push1=, $pop0, $2
; STRICT-NEXT: return $pop1
- %mul = fmul contract float %b, %a
- %add = fadd contract float %mul, %c
- ret float %add
+;
+; NOFP16-LABEL: fadd_fmul_2xf64:
+; NOFP16: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: f64x2.mul $push0=, $1, $0
+; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2
+; NOFP16-NEXT: return $pop1
+;
+; NOSIMD-LABEL: fadd_fmul_2xf64:
+; NOSIMD: .functype fadd_fmul_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> ()
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: f64.mul $push0=, $4, $2
+; NOSIMD-NEXT: f64.add $push1=, $pop0, $6
+; NOSIMD-NEXT: f64.store 8($0), $pop1
+; NOSIMD-NEXT: f64.mul $push2=, $3, $1
+; NOSIMD-NEXT: f64.add $push3=, $pop2, $5
+; NOSIMD-NEXT: f64.store 0($0), $pop3
+; NOSIMD-NEXT: return
+ %mul = fmul <2 x double> %b, %a
+ %add = fadd <2 x double> %mul, %c
+ ret <2 x double> %add
}
define float @fma_f32(float %a, float %b, float %c) {
@@ -247,6 +1476,18 @@ define float @fma_f32(float %a, float %b, float %c) {
; STRICT-NEXT: # %bb.0:
; STRICT-NEXT: call $push0=, fmaf, $0, $1, $2
; STRICT-NEXT: return $pop0
+;
+; NOFP16-LABEL: fma_f32:
+; NOFP16: .functype fma_f32 (f32, f32, f32) -> (f32)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, fmaf, $0, $1, $2
+; NOFP16-NEXT: return $pop0
+;
+; NOSIMD-LABEL: fma_f32:
+; NOSIMD: .functype fma_f32 (f32, f32, f32) -> (f32)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, fmaf, $0, $1, $2
+; NOSIMD-NEXT: return $pop0
%fma = call float @llvm.fma(float %a, float %b, float %c)
ret float %fma
}
@@ -263,6 +1504,18 @@ define double @fma_f64(double %a, double %b, double %c) {
; STRICT-NEXT: # %bb.0:
; STRICT-NEXT: call $push0=, fma, $0, $1, $2
; STRICT-NEXT: return $pop0
+;
+; NOFP16-LABEL: fma_f64:
+; NOFP16: .functype fma_f64 (f64, f64, f64) -> (f64)
+; NOFP16-NEXT: # %bb.0:
+; NOFP16-NEXT: call $push0=, fma, $0, $1, $2
+; NOFP16-NEXT: return $pop0
+;
+; NOSIMD-LABEL: fma_f64:
+; NOSIMD: .functype fma_f64 (f64, f64, f64) -> (f64)
+; NOSIMD-NEXT: # %bb.0:
+; NOSIMD-NEXT: call $push0=, fma, $0, $1, $2
+; NOSIMD-NEXT: return $pop0
%fma = call double @llvm.fma(double %a, double %b, double %c)
ret double %fma
}
diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll
index 6e2d860..b90c1da 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll
@@ -27,7 +27,7 @@ define <4 x float> @fsub_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4
; RELAXED-LABEL: fsub_fmul_contract_4xf32:
; RELAXED: .functype fsub_fmul_contract_4xf32 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $2, $1, $0
+; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fsub_fmul_contract_4xf32:
@@ -46,15 +46,14 @@ define <8 x half> @fsub_fmul_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x h
; RELAXED-LABEL: fsub_fmul_contract_8xf16:
; RELAXED: .functype fsub_fmul_contract_8xf16 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f16x8.relaxed_nmadd $push0=, $2, $1, $0
+; RELAXED-NEXT: f16x8.nmadd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fsub_fmul_contract_8xf16:
; STRICT: .functype fsub_fmul_contract_8xf16 (v128, v128, v128) -> (v128)
; STRICT-NEXT: # %bb.0:
-; STRICT-NEXT: f16x8.mul $push0=, $1, $0
-; STRICT-NEXT: f16x8.sub $push1=, $2, $pop0
-; STRICT-NEXT: return $pop1
+; STRICT-NEXT: f16x8.nmadd $push0=, $1, $0, $2
+; STRICT-NEXT: return $pop0
%mul = fmul contract <8 x half> %b, %a
%sub = fsub contract <8 x half> %c, %mul
ret <8 x half> %sub
@@ -84,9 +83,9 @@ define <8 x float> @fsub_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8
; RELAXED-LABEL: fsub_fmul_contract_8xf32:
; RELAXED: .functype fsub_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> ()
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $6, $4, $2
+; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $4, $2, $6
; RELAXED-NEXT: v128.store 16($0), $pop0
-; RELAXED-NEXT: f32x4.relaxed_nmadd $push1=, $5, $3, $1
+; RELAXED-NEXT: f32x4.relaxed_nmadd $push1=, $3, $1, $5
; RELAXED-NEXT: v128.store 0($0), $pop1
; RELAXED-NEXT: return
;
@@ -110,7 +109,7 @@ define <2 x double> @fsub_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b,
; RELAXED-LABEL: fsub_fmul_contract_2xf64:
; RELAXED: .functype fsub_fmul_contract_2xf64 (v128, v128, v128) -> (v128)
; RELAXED-NEXT: # %bb.0:
-; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $2, $1, $0
+; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $1, $0, $2
; RELAXED-NEXT: return $pop0
;
; STRICT-LABEL: fsub_fmul_contract_2xf64:
@@ -143,3 +142,55 @@ define float @fsub_fmul_contract_f32(float %a, float %b, float %c) {
ret float %sub
}
+define <8 x half> @fmuladd_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) {
+; RELAXED-LABEL: fmuladd_8xf16:
+; RELAXED: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f16x8.nmadd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_8xf16:
+; STRICT: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f16x8.nmadd $push0=, $0, $1, $2
+; STRICT-NEXT: return $pop0
+ %fneg = fneg <8 x half> %a
+ %fma = call <8 x half> @llvm.fmuladd(<8 x half> %fneg, <8 x half> %b, <8 x half> %c)
+ ret <8 x half> %fma
+}
+
+define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
+; RELAXED-LABEL: fmuladd_4xf32:
+; RELAXED: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_4xf32:
+; STRICT: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f32x4.mul $push0=, $0, $1
+; STRICT-NEXT: f32x4.sub $push1=, $2, $pop0
+; STRICT-NEXT: return $pop1
+ %fneg = fneg <4 x float> %a
+ %fma = call <4 x float> @llvm.fmuladd(<4 x float> %fneg, <4 x float> %b, <4 x float> %c)
+ ret <4 x float> %fma
+}
+
+define <2 x double> @fmuladd_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) {
+; RELAXED-LABEL: fmuladd_2xf64:
+; RELAXED: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128)
+; RELAXED-NEXT: # %bb.0:
+; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $0, $1, $2
+; RELAXED-NEXT: return $pop0
+;
+; STRICT-LABEL: fmuladd_2xf64:
+; STRICT: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128)
+; STRICT-NEXT: # %bb.0:
+; STRICT-NEXT: f64x2.mul $push0=, $0, $1
+; STRICT-NEXT: f64x2.sub $push1=, $2, $pop0
+; STRICT-NEXT: return $pop1
+ %fneg = fneg <2 x double> %a
+ %fma = call <2 x double> @llvm.fmuladd(<2 x double> %fneg, <2 x double> %b, <2 x double> %c)
+ ret <2 x double> %fma
+}
diff --git a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
index a0c243b..f3950b7 100644
--- a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
+++ b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll
@@ -1,16 +1,15 @@
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
-;; A minimal test case. llc will crash if global variables already has a section
-;; prefix. Subsequent PRs will expand on this test case to test the hotness
-;; reconciliation implementation.
-
-; RUN: not llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \
+;; A minimal test case. Subsequent PRs will expand on this test case
+;; (e.g., with more functions, variables and profiles) and test the hotness
+;; reconcillation implementation.
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \
; RUN: -partition-static-data-sections=true \
; RUN: -data-sections=true -unique-section-names=false \
-; RUN: %s -o - 2>&1 | FileCheck %s --check-prefix=ERR
+; RUN: %s -o - 2>&1 | FileCheck %s --check-prefix=IR
-; ERR: Global variable hot_bss already has a section prefix hot
+; IR: .section .bss.hot.,"aw"
@hot_bss = internal global i32 0, !section_prefix !17
diff --git a/llvm/test/CodeGen/X86/global-variable-partition.ll b/llvm/test/CodeGen/X86/global-variable-partition.ll
index ce06d17..604b4fd 100644
--- a/llvm/test/CodeGen/X86/global-variable-partition.ll
+++ b/llvm/test/CodeGen/X86/global-variable-partition.ll
@@ -106,23 +106,31 @@ target triple = "x86_64-unknown-linux-gnu"
; UNIQ-NEXT: .section .data.unlikely.,"aw",@progbits,unique,8
; AGG-NEXT: .section .data.unlikely.,"aw",@progbits
+;; The `.section` directive is omitted for .data with -unique-section-names=false.
+; See MCSectionELF::shouldOmitSectionDirective for the implementation details.
+
; For @data_with_unknown_hotness
; SYM: .type .Ldata_with_unknown_hotness,@object # @data_with_unknown_hotness
; SYM: .section .data..Ldata_with_unknown_hotness,"aw",@progbits
; UNIQ: .section .data,"aw",@progbits,unique,9
-; The `.section` directive is omitted for .data with -unique-section-names=false.
-; See MCSectionELF::shouldOmitSectionDirective for the implementation details.
+
; AGG: .data
; COMMON: .Ldata_with_unknown_hotness:
-; For @hot_data_custom_bar_section
-; It has an explicit section attribute 'var' and shouldn't have hot or unlikely suffix.
+; For variables that are not eligible for section prefix annotation
; COMMON: .type hot_data_custom_bar_section,@object
; SYM-NEXT: .section bar,"aw",@progbits
; SYM: hot_data_custom_bar_section
; UNIQ: .section bar,"aw",@progbits
; AGG: .section bar,"aw",@progbits
+; SYM: .section .data.llvm.fake_var,"aw"
+; UNIQ: .section .data,"aw"
+; AGG: .data
+
+;; No section for linker declaration
+; COMMON-NOT: qux
+
@.str = private unnamed_addr constant [5 x i8] c"hot\09\00", align 1
@.str.1 = private unnamed_addr constant [10 x i8] c"%d\09%d\09%d\0A\00", align 1
@hot_relro_array = internal constant [2 x ptr] [ptr @bss2, ptr @data3]
@@ -137,6 +145,8 @@ target triple = "x86_64-unknown-linux-gnu"
@data3 = internal global i32 3
@data_with_unknown_hotness = private global i32 5
@hot_data_custom_bar_section = internal global i32 101 #0
+@llvm.fake_var = internal global i32 123
+@qux = external global i64
define void @cold_func(i32 %0) !prof !15 {
%2 = load i32, ptr @cold_bss
diff --git a/llvm/test/CodeGen/X86/setcc-wide-types.ll b/llvm/test/CodeGen/X86/setcc-wide-types.ll
index 5aa266d..69abf6e 100644
--- a/llvm/test/CodeGen/X86/setcc-wide-types.ll
+++ b/llvm/test/CodeGen/X86/setcc-wide-types.ll
@@ -1447,3 +1447,158 @@ define i1 @eq_i512_load_arg(ptr%p, i512 %b) {
%r = icmp eq i512 %a, %b
ret i1 %r
}
+
+; Tests for any/allbits from memory.
+
+define i1 @anybits_i128_load_arg(ptr %w) {
+; ANY-LABEL: anybits_i128_load_arg:
+; ANY: # %bb.0:
+; ANY-NEXT: movq (%rdi), %rax
+; ANY-NEXT: orq 8(%rdi), %rax
+; ANY-NEXT: setne %al
+; ANY-NEXT: retq
+ %ld = load i128, ptr %w
+ %cmp = icmp ne i128 %ld, 0
+ ret i1 %cmp
+}
+
+define i1 @allbits_i128_load_arg(ptr %w) {
+; SSE2-LABEL: allbits_i128_load_arg:
+; SSE2: # %bb.0:
+; SSE2-NEXT: pcmpeqd %xmm0, %xmm0
+; SSE2-NEXT: pcmpeqb (%rdi), %xmm0
+; SSE2-NEXT: pmovmskb %xmm0, %eax
+; SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF
+; SSE2-NEXT: sete %al
+; SSE2-NEXT: retq
+;
+; SSE41-LABEL: allbits_i128_load_arg:
+; SSE41: # %bb.0:
+; SSE41-NEXT: movdqa (%rdi), %xmm0
+; SSE41-NEXT: pcmpeqd %xmm1, %xmm1
+; SSE41-NEXT: ptest %xmm1, %xmm0
+; SSE41-NEXT: setb %al
+; SSE41-NEXT: retq
+;
+; AVXANY-LABEL: allbits_i128_load_arg:
+; AVXANY: # %bb.0:
+; AVXANY-NEXT: vmovdqa (%rdi), %xmm0
+; AVXANY-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVXANY-NEXT: vptest %xmm1, %xmm0
+; AVXANY-NEXT: setb %al
+; AVXANY-NEXT: retq
+ %ld = load i128, ptr %w
+ %cmp = icmp eq i128 %ld, -1
+ ret i1 %cmp
+}
+
+define i1 @anybits_i256_load_arg(ptr %w) {
+; ANY-LABEL: anybits_i256_load_arg:
+; ANY: # %bb.0:
+; ANY-NEXT: movq (%rdi), %rax
+; ANY-NEXT: movq 8(%rdi), %rcx
+; ANY-NEXT: orq 24(%rdi), %rcx
+; ANY-NEXT: orq 16(%rdi), %rax
+; ANY-NEXT: orq %rcx, %rax
+; ANY-NEXT: setne %al
+; ANY-NEXT: retq
+ %ld = load i256, ptr %w
+ %cmp = icmp ne i256 %ld, 0
+ ret i1 %cmp
+}
+
+define i1 @allbits_i256_load_arg(ptr %w) {
+; SSE-LABEL: allbits_i256_load_arg:
+; SSE: # %bb.0:
+; SSE-NEXT: movq (%rdi), %rax
+; SSE-NEXT: movq 8(%rdi), %rcx
+; SSE-NEXT: andq 24(%rdi), %rcx
+; SSE-NEXT: andq 16(%rdi), %rax
+; SSE-NEXT: andq %rcx, %rax
+; SSE-NEXT: cmpq $-1, %rax
+; SSE-NEXT: sete %al
+; SSE-NEXT: retq
+;
+; AVX1-LABEL: allbits_i256_load_arg:
+; AVX1: # %bb.0:
+; AVX1-NEXT: vmovdqu (%rdi), %ymm0
+; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1
+; AVX1-NEXT: vcmptrueps %ymm1, %ymm1, %ymm1
+; AVX1-NEXT: vptest %ymm1, %ymm0
+; AVX1-NEXT: setb %al
+; AVX1-NEXT: vzeroupper
+; AVX1-NEXT: retq
+;
+; AVX2-LABEL: allbits_i256_load_arg:
+; AVX2: # %bb.0:
+; AVX2-NEXT: vmovdqu (%rdi), %ymm0
+; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1
+; AVX2-NEXT: vptest %ymm1, %ymm0
+; AVX2-NEXT: setb %al
+; AVX2-NEXT: vzeroupper
+; AVX2-NEXT: retq
+;
+; AVX512-LABEL: allbits_i256_load_arg:
+; AVX512: # %bb.0:
+; AVX512-NEXT: vmovdqu (%rdi), %ymm0
+; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1
+; AVX512-NEXT: vptest %ymm1, %ymm0
+; AVX512-NEXT: setb %al
+; AVX512-NEXT: vzeroupper
+; AVX512-NEXT: retq
+ %ld = load i256, ptr %w
+ %cmp = icmp eq i256 %ld, -1
+ ret i1 %cmp
+}
+
+define i1 @anybits_i512_load_arg(ptr %w) {
+; ANY-LABEL: anybits_i512_load_arg:
+; ANY: # %bb.0:
+; ANY-NEXT: movq 16(%rdi), %rax
+; ANY-NEXT: movq (%rdi), %rcx
+; ANY-NEXT: movq 8(%rdi), %rdx
+; ANY-NEXT: movq 24(%rdi), %rsi
+; ANY-NEXT: orq 56(%rdi), %rsi
+; ANY-NEXT: orq 40(%rdi), %rdx
+; ANY-NEXT: orq %rsi, %rdx
+; ANY-NEXT: orq 48(%rdi), %rax
+; ANY-NEXT: orq 32(%rdi), %rcx
+; ANY-NEXT: orq %rax, %rcx
+; ANY-NEXT: orq %rdx, %rcx
+; ANY-NEXT: setne %al
+; ANY-NEXT: retq
+ %ld = load i512, ptr %w
+ %cmp = icmp ne i512 %ld, 0
+ ret i1 %cmp
+}
+
+define i1 @allbits_i512_load_arg(ptr %w) {
+; NO512-LABEL: allbits_i512_load_arg:
+; NO512: # %bb.0:
+; NO512-NEXT: movq 16(%rdi), %rax
+; NO512-NEXT: movq (%rdi), %rcx
+; NO512-NEXT: movq 8(%rdi), %rdx
+; NO512-NEXT: movq 24(%rdi), %rsi
+; NO512-NEXT: andq 56(%rdi), %rsi
+; NO512-NEXT: andq 40(%rdi), %rdx
+; NO512-NEXT: andq %rsi, %rdx
+; NO512-NEXT: andq 48(%rdi), %rax
+; NO512-NEXT: andq 32(%rdi), %rcx
+; NO512-NEXT: andq %rax, %rcx
+; NO512-NEXT: andq %rdx, %rcx
+; NO512-NEXT: cmpq $-1, %rcx
+; NO512-NEXT: sete %al
+; NO512-NEXT: retq
+;
+; AVX512-LABEL: allbits_i512_load_arg:
+; AVX512: # %bb.0:
+; AVX512-NEXT: vpternlogd {{.*#+}} zmm0 = -1
+; AVX512-NEXT: vpcmpneqd (%rdi), %zmm0, %k0
+; AVX512-NEXT: kortestw %k0, %k0
+; AVX512-NEXT: sete %al
+; AVX512-NEXT: vzeroupper
+; AVX512-NEXT: retq
+ %ld = load i512, ptr %w
+ %cmp = icmp eq i512 %ld, -1
+ ret i1 %cmp
+}
diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s
index 48aec4b..57da338 100644
--- a/llvm/test/MC/WebAssembly/simd-encodings.s
+++ b/llvm/test/MC/WebAssembly/simd-encodings.s
@@ -917,11 +917,11 @@ main:
# CHECK: f16x8.nearest # encoding: [0xfd,0xb6,0x02]
f16x8.nearest
- # CHECK: f16x8.relaxed_madd # encoding: [0xfd,0xce,0x02]
- f16x8.relaxed_madd
+ # CHECK: f16x8.madd # encoding: [0xfd,0xce,0x02]
+ f16x8.madd
- # CHECK: f16x8.relaxed_nmadd # encoding: [0xfd,0xcf,0x02]
- f16x8.relaxed_nmadd
+ # CHECK: f16x8.nmadd # encoding: [0xfd,0xcf,0x02]
+ f16x8.nmadd
# CHECK: i16x8.trunc_sat_f16x8_s # encoding: [0xfd,0xc5,0x02]
i16x8.trunc_sat_f16x8_s
diff --git a/llvm/test/TableGen/listsplat.td b/llvm/test/TableGen/listsplat.td
index 5a93a4c..43803d6 100644
--- a/llvm/test/TableGen/listsplat.td
+++ b/llvm/test/TableGen/listsplat.td
@@ -1,4 +1,5 @@
// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
// CHECK: ------------- Classes -----------------
// CHECK-NEXT: class X<int X:a = ?, int X:b = ?> {
@@ -73,3 +74,8 @@ def DYa1 : Y<"a", 1>;
def DYa2 : Y<"a", 2>;
def DZ : X<42, !size([1, 2, 3])>;
+
+#ifdef ERROR1
+// ERROR1: !listsplat count -1 is negative
+defvar E = !listsplat("", -1);
+#endif
diff --git a/llvm/test/Transforms/PGOProfile/data-access-profile.ll b/llvm/test/Transforms/PGOProfile/data-access-profile.ll
index 29198f34..205184b 100644
--- a/llvm/test/Transforms/PGOProfile/data-access-profile.ll
+++ b/llvm/test/Transforms/PGOProfile/data-access-profile.ll
@@ -3,55 +3,72 @@
; RUN: rm -rf %t && split-file %s %t && cd %t
-;; Read a text profile and merge it into indexed profile.
+;; Read text profiles and merge them into indexed profiles.
; RUN: llvm-profdata merge --memprof-version=4 memprof.yaml -o memprof.profdata
+; RUN: llvm-profdata merge --memprof-version=4 memprof-no-dap.yaml -o memprof-no-dap.profdata
;; Run optimizer pass on an IR module without IR functions, and test that global
;; variables in the module could be annotated (i.e., no early return),
; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' -memprof-annotate-static-data-prefix \
-; RUN: -debug-only=memprof -stats -S funcless-module.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,PREFIX,STAT
+; RUN: -debug-only=memprof -stats -S funcless-module.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,IR,STAT
;; Run optimizer pass on the IR, and check the section prefix.
; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' -memprof-annotate-static-data-prefix \
-; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,PREFIX,STAT
+; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,IR,STAT
-;; Run optimizer pass without explicitly setting -memprof-annotate-static-data-prefix.
-;; The output text IR shouldn't have `section_prefix`
+;; Run memprof without providing memprof data. Test that IR has module flag
+;; `EnableDataAccessProf` as 0.
+; RUN: opt -passes='memprof-use<profile-filename=memprof-no-dap.profdata>' -memprof-annotate-static-data-prefix \
+; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefix=FLAG
+
+;; Run memprof without explicitly setting -memprof-annotate-static-data-prefix.
+;; The output text IR shouldn't have `section_prefix` or EnableDataAccessProf module flag.
; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' \
-; RUN: -debug-only=memprof -stats -S input.ll -o - | FileCheck %s --implicit-check-not="section_prefix"
+; RUN: -debug-only=memprof -stats -S input.ll -o - | FileCheck %s --check-prefix=FLAGLESS --implicit-check-not="section_prefix"
; LOG: Skip annotating string literal .str
; LOG: Global variable var1 is annotated as hot
; LOG: Global variable var2.llvm.125 is annotated as hot
; LOG: Global variable bar is not annotated
; LOG: Global variable foo is annotated as unlikely
-; LOG: Global variable var3 has explicit section name. Skip annotating.
-; LOG: Global variable var4 has explicit section name. Skip annotating.
+; LOG: Skip annotation for var3 due to explicit section name.
+; LOG: Skip annotation for var4 due to explicit section name.
+; LOG: Skip annotation for llvm.fake_var due to name starts with `llvm.`.
+; LOG: Skip annotation for qux due to linker declaration.
;; String literals are not annotated.
-; PREFIX: @.str = unnamed_addr constant [5 x i8] c"abcde"
-; PREFIX-NOT: section_prefix
-; PREFIX: @var1 = global i32 123, !section_prefix !0
+; IR: @.str = unnamed_addr constant [5 x i8] c"abcde"
+; IR-NOT: section_prefix
+; IR: @var1 = global i32 123, !section_prefix !0
;; @var.llvm.125 will be canonicalized to @var2 for profile look-up.
-; PREFIX-NEXT: @var2.llvm.125 = global i64 0, !section_prefix !0
+; IR-NEXT: @var2.llvm.125 = global i64 0, !section_prefix !0
;; @bar is not seen in hot symbol or known symbol set, so it won't get a section
;; prefix. Test this by testing that there is no section_prefix between @bar and
;; @foo.
-; PREFIX-NEXT: @bar = global i16 3
-; PREFIX-NOT: !section_prefix
+; IR-NEXT: @bar = global i16 3
+; IR-NOT: !section_prefix
;; @foo is unlikely.
-; PREFIX-NEXT: @foo = global i8 2, !section_prefix !1
+; IR-NEXT: @foo = global i8 2, !section_prefix !1
+
+; IR-NEXT: @var3 = constant [2 x i32] [i32 12345, i32 6789], section "sec1"
+; IR-NEXT: @var4 = constant [1 x i64] [i64 98765] #0
+
+; IR: @llvm.fake_var = global i32 123
+; IR-NOT: !section_prefix
+; IR: @qux = external global i64
+; IR-NOT: !section_prefix
-; PREFIX-NEXT: @var3 = constant [2 x i32] [i32 12345, i32 6789], section "sec1"
-; PREFIX-NEXT: @var4 = constant [1 x i64] [i64 98765] #0
+; IR: attributes #0 = { "rodata-section"="sec2" }
-; PREFIX: attributes #0 = { "rodata-section"="sec2" }
+; IR: !0 = !{!"section_prefix", !"hot"}
+; IR-NEXT: !1 = !{!"section_prefix", !"unlikely"}
+; IR-NEXT: !2 = !{i32 2, !"EnableDataAccessProf", i32 1}
-; PREFIX: !0 = !{!"section_prefix", !"hot"}
-; PREFIX-NEXT: !1 = !{!"section_prefix", !"unlikely"}
+; FLAG: !{i32 2, !"EnableDataAccessProf", i32 0}
+; FLAGLESS-NOT: EnableDataAccessProf
; STAT: 1 memprof - Number of global vars annotated with 'unlikely' section prefix.
; STAT: 2 memprof - Number of global vars with user-specified section (not annotated).
@@ -72,6 +89,24 @@ DataAccessProfiles:
- foo
KnownColdStrHashes: [ 999, 1001 ]
...
+;--- memprof-no-dap.yaml
+---
+# A memprof file with without data access profiles. The heap records are simplified
+# to pass profile parsing and don't need to match the IR.
+HeapProfileRecords:
+ - GUID: 0xdeadbeef12345678
+ AllocSites:
+ - Callstack:
+ - { Function: 0x1111111111111111, LineOffset: 11, Column: 10, IsInlineFrame: true }
+ MemInfoBlock:
+ AllocCount: 111
+ TotalSize: 222
+ TotalLifetime: 333
+ TotalLifetimeAccessDensity: 444
+ CallSites:
+ - Frames:
+ - { Function: 0x5555555555555555, LineOffset: 55, Column: 50, IsInlineFrame: true }
+...
;--- input.ll
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -84,11 +119,14 @@ target triple = "x86_64-unknown-linux-gnu"
@foo = global i8 2
@var3 = constant [2 x i32][i32 12345, i32 6789], section "sec1"
@var4 = constant [1 x i64][i64 98765] #0
+@llvm.fake_var = global i32 123
+@qux = external global i64
define i32 @func() {
%a = load i32, ptr @var1
%b = load i32, ptr @var2.llvm.125
- %ret = call i32 (...) @func_taking_arbitrary_param(i32 %a, i32 %b)
+ %c = load i32, ptr @llvm.fake_var
+ %ret = call i32 (...) @func_taking_arbitrary_param(i32 %a, i32 %b, i32 %c)
ret i32 %ret
}
@@ -108,5 +146,8 @@ target triple = "x86_64-unknown-linux-gnu"
@foo = global i8 2
@var3 = constant [2 x i32][i32 12345, i32 6789], section "sec1"
@var4 = constant [1 x i64][i64 98765] #0
+@llvm.fake_var = global i32 123
+@qux = external global i64
+
attributes #0 = { "rodata-section"="sec2" }
diff --git a/llvm/unittests/ADT/BitFieldsTest.cpp b/llvm/unittests/ADT/BitFieldsTest.cpp
index 3062d5d..ae541fe 100644
--- a/llvm/unittests/ADT/BitFieldsTest.cpp
+++ b/llvm/unittests/ADT/BitFieldsTest.cpp
@@ -247,8 +247,8 @@ TEST(BitfieldsTest, ValueTooBigBounded) {
Bitfield::set<A>(Storage, 0);
Bitfield::set<A>(Storage, -1);
Bitfield::set<A>(Storage, -2);
- EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is too big");
- EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -3), "value is too small");
+ EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is out of range");
+ EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -3), "value is out of range");
}
#endif
diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp
index 2431db9..67fee96 100644
--- a/llvm/unittests/IR/ConstantFPRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp
@@ -1066,6 +1066,115 @@ TEST_F(ConstantFPRangeTest, sub) {
#endif
}
+TEST_F(ConstantFPRangeTest, mul) {
+ EXPECT_EQ(Full.mul(Full), NonNaN.unionWith(QNaN));
+ EXPECT_EQ(Full.mul(Empty), Empty);
+ EXPECT_EQ(Empty.mul(Full), Empty);
+ EXPECT_EQ(Empty.mul(Empty), Empty);
+ EXPECT_EQ(One.mul(One), ConstantFPRange(APFloat(1.0)));
+ EXPECT_EQ(Some.mul(Some),
+ ConstantFPRange::getNonNaN(APFloat(-9.0), APFloat(9.0)));
+ EXPECT_EQ(SomePos.mul(SomeNeg),
+ ConstantFPRange::getNonNaN(APFloat(-9.0), APFloat(-0.0)));
+ EXPECT_EQ(PosInf.mul(PosInf), PosInf);
+ EXPECT_EQ(NegInf.mul(NegInf), PosInf);
+ EXPECT_EQ(PosInf.mul(Finite), NonNaN.unionWith(QNaN));
+ EXPECT_EQ(NegInf.mul(Finite), NonNaN.unionWith(QNaN));
+ EXPECT_EQ(PosInf.mul(NegInf), NegInf);
+ EXPECT_EQ(NegInf.mul(PosInf), NegInf);
+ EXPECT_EQ(PosZero.mul(NegZero), NegZero);
+ EXPECT_EQ(PosZero.mul(Zero), Zero);
+ EXPECT_EQ(NegZero.mul(NegZero), PosZero);
+ EXPECT_EQ(NegZero.mul(Zero), Zero);
+ EXPECT_EQ(NaN.mul(NaN), QNaN);
+ EXPECT_EQ(NaN.mul(Finite), QNaN);
+
+#if defined(EXPENSIVE_CHECKS)
+ EnumerateTwoInterestingConstantFPRanges(
+ [](const ConstantFPRange &LHS, const ConstantFPRange &RHS) {
+ ConstantFPRange Res = LHS.mul(RHS);
+ ConstantFPRange Expected =
+ ConstantFPRange::getEmpty(LHS.getSemantics());
+ EnumerateValuesInConstantFPRange(
+ LHS,
+ [&](const APFloat &LHSC) {
+ EnumerateValuesInConstantFPRange(
+ RHS,
+ [&](const APFloat &RHSC) {
+ APFloat Prod = LHSC * RHSC;
+ EXPECT_TRUE(Res.contains(Prod))
+ << "Wrong result for " << LHS << " * " << RHS
+ << ". The result " << Res << " should contain " << Prod;
+ if (!Expected.contains(Prod))
+ Expected = Expected.unionWith(ConstantFPRange(Prod));
+ },
+ /*IgnoreNaNPayload=*/true);
+ },
+ /*IgnoreNaNPayload=*/true);
+ EXPECT_EQ(Res, Expected)
+ << "Suboptimal result for " << LHS << " * " << RHS << ". Expected "
+ << Expected << ", but got " << Res;
+ },
+ SparseLevel::SpecialValuesOnly);
+#endif
+}
+
+TEST_F(ConstantFPRangeTest, div) {
+ EXPECT_EQ(Full.div(Full), NonNaN.unionWith(QNaN));
+ EXPECT_EQ(Full.div(Empty), Empty);
+ EXPECT_EQ(Empty.div(Full), Empty);
+ EXPECT_EQ(Empty.div(Empty), Empty);
+ EXPECT_EQ(One.div(One), ConstantFPRange(APFloat(1.0)));
+ EXPECT_EQ(Some.div(Some), NonNaN.unionWith(QNaN));
+ EXPECT_EQ(SomePos.div(SomeNeg),
+ ConstantFPRange(APFloat::getInf(Sem, /*Negative=*/true),
+ APFloat::getZero(Sem, /*Negative=*/true),
+ /*MayBeQNaN=*/true, /*MayBeSNaN=*/false));
+ EXPECT_EQ(PosInf.div(PosInf), QNaN);
+ EXPECT_EQ(NegInf.div(NegInf), QNaN);
+ EXPECT_EQ(PosInf.div(Finite), NonNaN);
+ EXPECT_EQ(NegInf.div(Finite), NonNaN);
+ EXPECT_EQ(PosInf.div(NegInf), QNaN);
+ EXPECT_EQ(NegInf.div(PosInf), QNaN);
+ EXPECT_EQ(Zero.div(Zero), QNaN);
+ EXPECT_EQ(SomePos.div(PosInf), PosZero);
+ EXPECT_EQ(SomeNeg.div(PosInf), NegZero);
+ EXPECT_EQ(PosInf.div(SomePos), PosInf);
+ EXPECT_EQ(NegInf.div(SomeNeg), PosInf);
+ EXPECT_EQ(NegInf.div(Some), NonNaN);
+ EXPECT_EQ(NaN.div(NaN), QNaN);
+ EXPECT_EQ(NaN.div(Finite), QNaN);
+
+#if defined(EXPENSIVE_CHECKS)
+ EnumerateTwoInterestingConstantFPRanges(
+ [](const ConstantFPRange &LHS, const ConstantFPRange &RHS) {
+ ConstantFPRange Res = LHS.div(RHS);
+ ConstantFPRange Expected =
+ ConstantFPRange::getEmpty(LHS.getSemantics());
+ EnumerateValuesInConstantFPRange(
+ LHS,
+ [&](const APFloat &LHSC) {
+ EnumerateValuesInConstantFPRange(
+ RHS,
+ [&](const APFloat &RHSC) {
+ APFloat Val = LHSC / RHSC;
+ EXPECT_TRUE(Res.contains(Val))
+ << "Wrong result for " << LHS << " / " << RHS
+ << ". The result " << Res << " should contain " << Val;
+ if (!Expected.contains(Val))
+ Expected = Expected.unionWith(ConstantFPRange(Val));
+ },
+ /*IgnoreNaNPayload=*/true);
+ },
+ /*IgnoreNaNPayload=*/true);
+ EXPECT_EQ(Res, Expected)
+ << "Suboptimal result for " << LHS << " / " << RHS << ". Expected "
+ << Expected << ", but got " << Res;
+ },
+ SparseLevel::SpecialValuesOnly);
+#endif
+}
+
TEST_F(ConstantFPRangeTest, flushDenormals) {
const fltSemantics &FP8Sem = APFloat::Float8E4M3();
APFloat NormalVal = APFloat::getSmallestNormalized(FP8Sem);
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index bdcb8a3..343c2bb71 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -1129,6 +1129,7 @@ Transforms/LowerIFunc/ifunc-alias.ll
Transforms/LowerIFunc/ifunc-nonsense-resolvers.ll
Transforms/LowerIFunc/ifunc-program-addrspace.ll
Transforms/LowerIFunc/lower-ifunc.ll
+Transforms/LowerMatrixIntrinsics/data-layout-multiply-fused.ll
Transforms/LowerMatrixIntrinsics/multiply-fused-dominance.ll
Transforms/LowerMatrixIntrinsics/multiply-fused.ll
Transforms/LowerMatrixIntrinsics/multiply-fused-loops.ll
@@ -1311,82 +1312,6 @@ Transforms/SimpleLoopUnswitch/pr60736.ll
Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll
Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll
-Transforms/SLPVectorizer/AArch64/gather-root.ll
-Transforms/SLPVectorizer/AArch64/horizontal.ll
-Transforms/SLPVectorizer/AArch64/loadi8.ll
-Transforms/SLPVectorizer/AArch64/phi-node-bitwidt-op-not.ll
-Transforms/SLPVectorizer/AArch64/uselistorder.ll
-Transforms/SLPVectorizer/AArch64/vec3-reorder-reshuffle.ll
-Transforms/SLPVectorizer/AArch64/vectorizable-selects-min-max.ll
-Transforms/SLPVectorizer/AArch64/vectorizable-selects-uniform-cmps.ll
-Transforms/SLPVectorizer/AMDGPU/horizontal-store.ll
-Transforms/SLPVectorizer/bool-logical-op-reduction-with-poison.ll
-Transforms/SLPVectorizer/call-arg-reduced-by-minbitwidth.ll
-Transforms/SLPVectorizer/const-bool-logical-or-reduction.ll
-Transforms/SLPVectorizer/extracts-with-undefs.ll
-Transforms/SLPVectorizer/freeze-signedness-missed.ll
-Transforms/SLPVectorizer/gathered-consecutive-loads-different-types.ll
-Transforms/SLPVectorizer/gather_extract_from_vectorbuild.ll
-Transforms/SLPVectorizer/insert-element-build-vector-const.ll
-Transforms/SLPVectorizer/insert-element-build-vector-inseltpoison.ll
-Transforms/SLPVectorizer/insert-element-build-vector.ll
-Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll
-Transforms/SLPVectorizer/minbitwidth-node-with-multi-users.ll
-Transforms/SLPVectorizer/minbitwidth-user-not-min.ll
-Transforms/SLPVectorizer/partial-register-extract.ll
-Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll
-Transforms/SLPVectorizer/reorder-node.ll
-Transforms/SLPVectorizer/reused-buildvector-matching-vectorized-node.ll
-Transforms/SLPVectorizer/revec.ll
-Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll
-Transforms/SLPVectorizer/RISCV/remarks-insert-into-small-vector.ll
-Transforms/SLPVectorizer/RISCV/reordered-interleaved-loads.ll
-Transforms/SLPVectorizer/RISCV/revec.ll
-Transforms/SLPVectorizer/RISCV/select-profitability.ll
-Transforms/SLPVectorizer/RISCV/shuffled-gather-casted.ll
-Transforms/SLPVectorizer/RISCV/unsigned-node-trunc-with-signed-users.ll
-Transforms/SLPVectorizer/slp-deleted-inst.ll
-Transforms/SLPVectorizer/SystemZ/cmp-ptr-minmax.ll
-Transforms/SLPVectorizer/SystemZ/ext-not-resized-op-resized.ll
-Transforms/SLPVectorizer/SystemZ/minbitwidth-trunc.ll
-Transforms/SLPVectorizer/X86/bool-mask.ll
-Transforms/SLPVectorizer/X86/bv-root-part-of-graph.ll
-Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll
-Transforms/SLPVectorizer/X86/cmp-as-alternate-ops.ll
-Transforms/SLPVectorizer/X86/cmp_sel.ll
-Transforms/SLPVectorizer/X86/crash_7zip.ll
-Transforms/SLPVectorizer/X86/crash_clear_undefs.ll
-Transforms/SLPVectorizer/X86/crash_cmpop.ll
-Transforms/SLPVectorizer/X86/debug-counter.ll
-Transforms/SLPVectorizer/X86/debug-info-salvage.ll
-Transforms/SLPVectorizer/X86/extractelement-single-use-many-nodes.ll
-Transforms/SLPVectorizer/X86/extracts-non-extendable.ll
-Transforms/SLPVectorizer/X86/ext-used-scalar-different-bitwidth.ll
-Transforms/SLPVectorizer/X86/gather-node-same-as-vect-but-order.ll
-Transforms/SLPVectorizer/X86/horizontal-minmax.ll
-Transforms/SLPVectorizer/X86/insert-after-bundle.ll
-Transforms/SLPVectorizer/X86/jumbled-load-multiuse.ll
-Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll
-Transforms/SLPVectorizer/X86/minbw-user-non-sizable.ll
-Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll
-Transforms/SLPVectorizer/X86/ordering-bug.ll
-Transforms/SLPVectorizer/X86/phi-node-bitwidt-op-not.ll
-Transforms/SLPVectorizer/X86/phi-node-reshuffled-part.ll
-Transforms/SLPVectorizer/X86/pr46983.ll
-Transforms/SLPVectorizer/X86/pr49933.ll
-Transforms/SLPVectorizer/X86/propagate_ir_flags.ll
-Transforms/SLPVectorizer/X86/reduction-bool-logic-op-inside.ll
-Transforms/SLPVectorizer/X86/reduction-logical.ll
-Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll
-Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll
-Transforms/SLPVectorizer/X86/select-reduction-op.ll
-Transforms/SLPVectorizer/X86/shrink_after_reorder.ll
-Transforms/SLPVectorizer/X86/subvector-minbitwidth-unsigned-value.ll
-Transforms/SLPVectorizer/X86/undef_vect.ll
-Transforms/SLPVectorizer/X86/used-reduced-op.ll
-Transforms/SLPVectorizer/X86/vec3-reorder-reshuffle.ll
-Transforms/SLPVectorizer/X86/vectorize-widest-phis.ll
-Transforms/SLPVectorizer/X86/whole-registers-compare.ll
Transforms/SROA/addrspacecast.ll
Transforms/SROA/phi-and-select.ll
Transforms/SROA/phi-gep.ll
diff --git a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
index 8d9474b..c301e0b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt
@@ -48,6 +48,10 @@ mlir_tablegen(LLVMIntrinsicFromLLVMIRConversions.inc -gen-intr-from-llvmir-conve
mlir_tablegen(LLVMConvertibleLLVMIRIntrinsics.inc -gen-convertible-llvmir-intrinsics)
add_mlir_dialect_tablegen_target(MLIRLLVMIntrinsicConversionsIncGen)
+set(LLVM_TARGET_DEFINITIONS LLVMDialectBytecode.td)
+mlir_tablegen(LLVMDialectBytecode.cpp.inc -gen-bytecode -bytecode-dialect="LLVM")
+add_public_tablegen_target(MLIRLLVMDialectBytecodeIncGen)
+
set(LLVM_TARGET_DEFINITIONS BasicPtxBuilderInterface.td)
mlir_tablegen(BasicPtxBuilderInterface.h.inc -gen-op-interface-decls)
mlir_tablegen(BasicPtxBuilderInterface.cpp.inc -gen-op-interface-defs)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
new file mode 100644
index 0000000..e7b202c
--- /dev/null
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td
@@ -0,0 +1,353 @@
+//===-- LLVMDialectBytecode.td - LLVM bytecode defs --------*- tablegen -*-===//
+//
+// 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 is the LLVM bytecode reader/writer definition file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DIALECT_BYTECODE
+#define LLVM_DIALECT_BYTECODE
+
+include "mlir/IR/BytecodeBase.td"
+
+//===----------------------------------------------------------------------===//
+// Bytecode classes for attributes and types.
+//===----------------------------------------------------------------------===//
+
+def String :
+ WithParser <"succeeded($_reader.readString($_var))",
+ WithBuilder<"$_args",
+ WithPrinter<"$_writer.writeOwnedString($_getter)",
+ WithType <"StringRef">>>>;
+
+class Attr<string type> : WithType<type, Attribute>;
+
+class OptionalAttribute<string type> :
+ WithParser <"succeeded($_reader.readOptionalAttribute($_var))",
+ WithPrinter<"$_writer.writeOptionalAttribute($_getter)",
+ WithType<type, Attribute>>>;
+
+class OptionalInt<string type> :
+ WithParser <"succeeded(readOptionalInt($_reader, $_var))",
+ WithPrinter<"writeOptionalInt($_writer, $_getter)",
+ WithType<"std::optional<" # type # ">", VarInt>>>;
+
+class OptionalArrayRef<string eltType> :
+ WithParser <"succeeded(readOptionalArrayRef<"
+ # eltType # ">($_reader, $_var))",
+ WithPrinter<"writeOptionalArrayRef<"
+ # eltType # ">($_writer, $_getter)",
+ WithType<"SmallVector<"
+ # eltType # ">", Attribute>>>;
+
+class EnumClassFlag<string flag, string getter> :
+ WithParser<"succeeded($_reader.readVarInt($_var))",
+ WithBuilder<"(" # flag # ")$_args",
+ WithPrinter<"$_writer.writeVarInt((uint64_t)$_name." # getter # ")",
+ WithType<"uint64_t", VarInt>>>>;
+
+//===----------------------------------------------------------------------===//
+// General notes
+// - For each attribute or type entry, the argument names should match
+// LLVMAttrDefs.td
+// - The mnemonics are either LLVM or builtin MLIR attributes and types, but
+// regular C++ types are also allowed to match builders and parsers.
+// - DIScopeAttr and DINodeAttr are empty base classes, custom encoding not
+// needed.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// DIBasicTypeAttr
+//===----------------------------------------------------------------------===//
+
+def DIBasicTypeAttr : DialectAttribute<(attr
+ VarInt:$tag,
+ String:$name,
+ VarInt:$sizeInBits,
+ VarInt:$encoding
+)>;
+
+//===----------------------------------------------------------------------===//
+// DIExpressionAttr, DIExpressionElemAttr
+//===----------------------------------------------------------------------===//
+
+def DIExpressionElemAttr : DialectAttribute<(attr
+ VarInt:$opcode,
+ OptionalArrayRef<"uint64_t">:$arguments
+)>;
+
+def DIExpressionAttr : DialectAttribute<(attr
+ OptionalArrayRef<"DIExpressionElemAttr">:$operations
+)>;
+
+//===----------------------------------------------------------------------===//
+// DIFileAttr
+//===----------------------------------------------------------------------===//
+
+def DIFileAttr : DialectAttribute<(attr
+ String:$name,
+ String:$directory
+)>;
+
+//===----------------------------------------------------------------------===//
+// DILocalVariableAttr
+//===----------------------------------------------------------------------===//
+
+def DILocalVariableAttr : DialectAttribute<(attr
+ Attr<"DIScopeAttr">:$scope,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line,
+ VarInt:$arg,
+ VarInt:$alignInBits,
+ OptionalAttribute<"DITypeAttr">:$type,
+ EnumClassFlag<"DIFlags", "getFlags()">:$_rawflags,
+ LocalVar<"DIFlags", "(DIFlags)_rawflags">:$flags
+)> {
+ // DILocalVariableAttr direct getter uses a `StringRef` for `name`. Since the
+ // more direct getter is prefered during bytecode reading, force the base one
+ // and prevent crashes for empty `StringAttr`.
+ let cBuilder = "$_resultType::get(context, $_args)";
+}
+
+//===----------------------------------------------------------------------===//
+// DISubroutineTypeAttr
+//===----------------------------------------------------------------------===//
+
+def DISubroutineTypeAttr : DialectAttribute<(attr
+ VarInt:$callingConvention,
+ OptionalArrayRef<"DITypeAttr">:$types
+)>;
+
+//===----------------------------------------------------------------------===//
+// DICompileUnitAttr
+//===----------------------------------------------------------------------===//
+
+def DICompileUnitAttr : DialectAttribute<(attr
+ Attr<"DistinctAttr">:$id,
+ VarInt:$sourceLanguage,
+ Attr<"DIFileAttr">:$file,
+ OptionalAttribute<"StringAttr">:$producer,
+ Bool:$isOptimized,
+ EnumClassFlag<"DIEmissionKind", "getEmissionKind()">:$_rawEmissionKind,
+ LocalVar<"DIEmissionKind", "(DIEmissionKind)_rawEmissionKind">:$emissionKind,
+ EnumClassFlag<"DINameTableKind", "getNameTableKind()">:$_rawNameTableKind,
+ LocalVar<"DINameTableKind",
+ "(DINameTableKind)_rawNameTableKind">:$nameTableKind
+)>;
+
+//===----------------------------------------------------------------------===//
+// DISubprogramAttr
+//===----------------------------------------------------------------------===//
+
+def DISubprogramAttr : DialectAttribute<(attr
+ OptionalAttribute<"DistinctAttr">:$recId,
+ Bool:$isRecSelf,
+ OptionalAttribute<"DistinctAttr">:$id,
+ OptionalAttribute<"DICompileUnitAttr">:$compileUnit,
+ OptionalAttribute<"DIScopeAttr">:$scope,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"StringAttr">:$linkageName,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line,
+ VarInt:$scopeLine,
+ EnumClassFlag<"DISubprogramFlags", "getSubprogramFlags()">:$_rawflags,
+ LocalVar<"DISubprogramFlags", "(DISubprogramFlags)_rawflags">:$subprogramFlags,
+ OptionalAttribute<"DISubroutineTypeAttr">:$type,
+ OptionalArrayRef<"DINodeAttr">:$retainedNodes,
+ OptionalArrayRef<"DINodeAttr">:$annotations
+)>;
+
+//===----------------------------------------------------------------------===//
+// DICompositeTypeAttr
+//===----------------------------------------------------------------------===//
+
+def DICompositeTypeAttr : DialectAttribute<(attr
+ OptionalAttribute<"DistinctAttr">:$recId,
+ Bool:$isRecSelf,
+ VarInt:$tag,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line,
+ OptionalAttribute<"DIScopeAttr">:$scope,
+ OptionalAttribute<"DITypeAttr">:$baseType,
+ EnumClassFlag<"DIFlags", "getFlags()">:$_rawflags,
+ LocalVar<"DIFlags", "(DIFlags)_rawflags">:$flags,
+ VarInt:$sizeInBits,
+ VarInt:$alignInBits,
+ OptionalAttribute<"DIExpressionAttr">:$dataLocation,
+ OptionalAttribute<"DIExpressionAttr">:$rank,
+ OptionalAttribute<"DIExpressionAttr">:$allocated,
+ OptionalAttribute<"DIExpressionAttr">:$associated,
+ OptionalArrayRef<"DINodeAttr">:$elements
+)>;
+
+//===----------------------------------------------------------------------===//
+// DIDerivedTypeAttr
+//===----------------------------------------------------------------------===//
+
+def DIDerivedTypeAttr : DialectAttribute<(attr
+ VarInt:$tag,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"DITypeAttr">:$baseType,
+ VarInt:$sizeInBits,
+ VarInt:$alignInBits,
+ VarInt:$offsetInBits,
+ OptionalInt<"unsigned">:$dwarfAddressSpace,
+ OptionalAttribute<"DINodeAttr">:$extraData
+)>;
+
+//===----------------------------------------------------------------------===//
+// DIImportedEntityAttr
+//===----------------------------------------------------------------------===//
+
+def DIImportedEntityAttr : DialectAttribute<(attr
+ VarInt:$tag,
+ Attr<"DIScopeAttr">:$scope,
+ Attr<"DINodeAttr">:$entity,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalArrayRef<"DINodeAttr">:$elements
+)>;
+
+//===----------------------------------------------------------------------===//
+// DIGlobalVariableAttr, DIGlobalVariableExpressionAttr
+//===----------------------------------------------------------------------===//
+
+def DIGlobalVariableAttr : DialectAttribute<(attr
+ OptionalAttribute<"DIScopeAttr">:$scope,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"StringAttr">:$linkageName,
+ Attr<"DIFileAttr">:$file,
+ VarInt:$line,
+ Attr<"DITypeAttr">:$type,
+ Bool:$isLocalToUnit,
+ Bool:$isDefined,
+ VarInt:$alignInBits
+)>;
+
+def DIGlobalVariableExpressionAttr : DialectAttribute<(attr
+ Attr<"DIGlobalVariableAttr">:$var,
+ OptionalAttribute<"DIExpressionAttr">:$expr
+)>;
+
+//===----------------------------------------------------------------------===//
+// DILabelAttr
+//===----------------------------------------------------------------------===//
+
+def DILabelAttr : DialectAttribute<(attr
+ Attr<"DIScopeAttr">:$scope,
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line
+)> {
+ // DILabelAttr direct getter uses a `StringRef` for `name`. Since the
+ // more direct getter is prefered during bytecode reading, force the base one
+ // and prevent crashes for empty `StringAttr`.
+ let cBuilder = "$_resultType::get(context, $_args)";
+}
+
+//===----------------------------------------------------------------------===//
+// DILexicalBlockAttr, DILexicalBlockFileAttr
+//===----------------------------------------------------------------------===//
+
+def DILexicalBlockAttr : DialectAttribute<(attr
+ Attr<"DIScopeAttr">:$scope,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$line,
+ VarInt:$column
+)>;
+
+def DILexicalBlockFileAttr : DialectAttribute<(attr
+ Attr<"DIScopeAttr">:$scope,
+ OptionalAttribute<"DIFileAttr">:$file,
+ VarInt:$discriminator
+)>;
+
+//===----------------------------------------------------------------------===//
+// DINamespaceAttr
+//===----------------------------------------------------------------------===//
+
+def DINamespaceAttr : DialectAttribute<(attr
+ OptionalAttribute<"StringAttr">:$name,
+ OptionalAttribute<"DIScopeAttr">:$scope,
+ Bool:$exportSymbols
+)>;
+
+//===----------------------------------------------------------------------===//
+// DISubrangeAttr
+//===----------------------------------------------------------------------===//
+
+def DISubrangeAttr : DialectAttribute<(attr
+ OptionalAttribute<"Attribute">:$count,
+ OptionalAttribute<"Attribute">:$lowerBound,
+ OptionalAttribute<"Attribute">:$upperBound,
+ OptionalAttribute<"Attribute">:$stride
+)>;
+
+//===----------------------------------------------------------------------===//
+// LoopAnnotationAttr
+//===----------------------------------------------------------------------===//
+
+def LoopAnnotationAttr : DialectAttribute<(attr
+ OptionalAttribute<"BoolAttr">:$disableNonforced,
+ OptionalAttribute<"LoopVectorizeAttr">:$vectorize,
+ OptionalAttribute<"LoopInterleaveAttr">:$interleave,
+ OptionalAttribute<"LoopUnrollAttr">:$unroll,
+ OptionalAttribute<"LoopUnrollAndJamAttr">:$unrollAndJam,
+ OptionalAttribute<"LoopLICMAttr">:$licm,
+ OptionalAttribute<"LoopDistributeAttr">:$distribute,
+ OptionalAttribute<"LoopPipelineAttr">:$pipeline,
+ OptionalAttribute<"LoopPeeledAttr">:$peeled,
+ OptionalAttribute<"LoopUnswitchAttr">:$unswitch,
+ OptionalAttribute<"BoolAttr">:$mustProgress,
+ OptionalAttribute<"BoolAttr">:$isVectorized,
+ OptionalAttribute<"FusedLoc">:$startLoc,
+ OptionalAttribute<"FusedLoc">:$endLoc,
+ OptionalArrayRef<"AccessGroupAttr">:$parallelAccesses
+)>;
+
+//===----------------------------------------------------------------------===//
+// Attributes & Types with custom bytecode handling.
+//===----------------------------------------------------------------------===//
+
+// All the attributes with custom bytecode handling.
+def LLVMDialectAttributes : DialectAttributes<"LLVM"> {
+ let elems = [
+ DIBasicTypeAttr,
+ DICompileUnitAttr,
+ DICompositeTypeAttr,
+ DIDerivedTypeAttr,
+ DIExpressionElemAttr,
+ DIExpressionAttr,
+ DIFileAttr,
+ DIGlobalVariableAttr,
+ DIGlobalVariableExpressionAttr,
+ DIImportedEntityAttr,
+ DILabelAttr,
+ DILexicalBlockAttr,
+ DILexicalBlockFileAttr,
+ DILocalVariableAttr,
+ DINamespaceAttr,
+ DISubprogramAttr,
+ DISubrangeAttr,
+ DISubroutineTypeAttr,
+ LoopAnnotationAttr
+ // Referenced attributes currently missing support:
+ // AccessGroupAttr, LoopVectorizeAttr, LoopInterleaveAttr, LoopUnrollAttr,
+ // LoopUnrollAndJamAttr, LoopLICMAttr, LoopDistributeAttr, LoopPipelineAttr,
+ // LoopPeeledAttr, LoopUnswitchAttr
+ ];
+}
+
+def LLVMDialectTypes : DialectTypes<"LLVM"> {
+ let elems = [];
+}
+
+#endif // LLVM_DIALECT_BYTECODE
diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
index 40b7d7e..89bd0f1 100644
--- a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
+++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
@@ -184,6 +184,7 @@ def AssumeAlignmentOp : MemRef_Op<"assume_alignment", [
def DistinctObjectsOp : MemRef_Op<"distinct_objects", [
Pure,
+ DistinctObjectsTrait,
DeclareOpInterfaceMethods<InferTypeOpInterface>
// ViewLikeOpInterface TODO: ViewLikeOpInterface only supports a single argument
]> {
diff --git a/mlir/include/mlir/Interfaces/ViewLikeInterface.h b/mlir/include/mlir/Interfaces/ViewLikeInterface.h
index db9c37f..c1c2269 100644
--- a/mlir/include/mlir/Interfaces/ViewLikeInterface.h
+++ b/mlir/include/mlir/Interfaces/ViewLikeInterface.h
@@ -230,6 +230,22 @@ LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name,
ArrayRef<int64_t> attr,
ValueRange values);
+namespace OpTrait {
+/// This trai indicates that pointer-like objects (such as memrefs) returned
+/// from this operation will never alias with each other. This provides a
+/// guarantee to optimization passes that accesses through different results
+/// of this operation can be safely reordered, as they will never reference
+/// overlapping memory locations.
+///
+/// Operations with this trait take multiple pointer-like operands
+/// and return the same operands with additional non-aliasing guarantees.
+/// If the access to the results of this operation aliases at runtime, the
+/// behavior of such access is undefined.
+template <typename ConcreteType>
+class DistinctObjectsTrait
+ : public TraitBase<ConcreteType, DistinctObjectsTrait> {};
+} // namespace OpTrait
+
} // namespace mlir
#endif // MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
diff --git a/mlir/include/mlir/Interfaces/ViewLikeInterface.td b/mlir/include/mlir/Interfaces/ViewLikeInterface.td
index ed213bf..131c1a0 100644
--- a/mlir/include/mlir/Interfaces/ViewLikeInterface.td
+++ b/mlir/include/mlir/Interfaces/ViewLikeInterface.td
@@ -414,4 +414,16 @@ def OffsetSizeAndStrideOpInterface : OpInterface<"OffsetSizeAndStrideOpInterface
}];
}
+// This trai indicates that pointer-like objects (such as memrefs) returned
+// from this operation will never alias with each other. This provides a
+// guarantee to optimization passes that accesses through different results
+// of this operation can be safely reordered, as they will never reference
+// overlapping memory locations.
+//
+// Operations with this trait take multiple pointer-like operands
+// and return the same operands with additional non-aliasing guarantees.
+// If the access to the results of this operation aliases at runtime, the
+// behavior of such access is undefined.
+def DistinctObjectsTrait : NativeOpTrait<"DistinctObjectsTrait">;
+
#endif // MLIR_INTERFACES_VIEWLIKEINTERFACE
diff --git a/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp b/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp
index 8062b474..a84d10d 100644
--- a/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp
+++ b/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp
@@ -258,6 +258,39 @@ getAllocEffectFor(Value value,
return success();
}
+static Operation *isDistinctObjectsOp(Operation *op) {
+ if (op && op->hasTrait<OpTrait::DistinctObjectsTrait>())
+ return op;
+
+ return nullptr;
+}
+
+static Value getDistinctObjectsOperand(Operation *op, Value value) {
+ unsigned argNumber = cast<OpResult>(value).getResultNumber();
+ return op->getOperand(argNumber);
+}
+
+static std::optional<AliasResult> checkDistinctObjects(Value lhs, Value rhs) {
+ // We should already checked that lhs and rhs are different.
+ assert(lhs != rhs && "lhs and rhs must be different");
+
+ // Result and corresponding operand must alias.
+ auto lhsOp = isDistinctObjectsOp(lhs.getDefiningOp());
+ if (lhsOp && getDistinctObjectsOperand(lhsOp, lhs) == rhs)
+ return AliasResult::MustAlias;
+
+ auto rhsOp = isDistinctObjectsOp(rhs.getDefiningOp());
+ if (rhsOp && getDistinctObjectsOperand(rhsOp, rhs) == lhs)
+ return AliasResult::MustAlias;
+
+ // If two different values come from the same `DistinctObjects` operation,
+ // they don't alias.
+ if (lhsOp && lhsOp == rhsOp)
+ return AliasResult::NoAlias;
+
+ return std::nullopt;
+}
+
/// Given the two values, return their aliasing behavior.
AliasResult LocalAliasAnalysis::aliasImpl(Value lhs, Value rhs) {
if (lhs == rhs)
@@ -289,6 +322,9 @@ AliasResult LocalAliasAnalysis::aliasImpl(Value lhs, Value rhs) {
: AliasResult::MayAlias;
}
+ if (std::optional<AliasResult> result = checkDistinctObjects(lhs, rhs))
+ return *result;
+
// Otherwise, neither of the values are constant so check to see if either has
// an allocation effect.
bool lhsHasAlloc = succeeded(getAllocEffectFor(lhs, lhsAlloc, lhsAllocScope));
diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
index ec581ac..cc66fac 100644
--- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
@@ -8,11 +8,13 @@ add_mlir_dialect_library(MLIRLLVMDialect
IR/LLVMMemorySlot.cpp
IR/LLVMTypes.cpp
IR/LLVMTypeSyntax.cpp
+ IR/LLVMDialectBytecode.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/LLVMIR
DEPENDS
+ MLIRLLVMDialectBytecodeIncGen
MLIRLLVMOpsIncGen
MLIRLLVMTypesIncGen
MLIRLLVMIntrinsicOpsIncGen
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 5d08ccc..7ca09d9 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -29,6 +29,8 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/Support/Error.h"
+#include "LLVMDialectBytecode.h"
+
#include <numeric>
#include <optional>
@@ -4237,6 +4239,7 @@ void LLVMDialect::initialize() {
// Support unknown operations because not all LLVM operations are registered.
allowUnknownOperations();
declarePromisedInterface<DialectInlinerInterface, LLVMDialect>();
+ detail::addBytecodeInterface(this);
}
#define GET_OP_CLASSES
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp
new file mode 100644
index 0000000..41d1f80
--- /dev/null
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp
@@ -0,0 +1,154 @@
+//===- LLVMDialectBytecode.cpp - LLVM Bytecode Implementation -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLVMDialectBytecode.h"
+#include "mlir/Bytecode/BytecodeImplementation.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
+#include "mlir/IR/Diagnostics.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include <type_traits>
+
+using namespace mlir;
+using namespace mlir::LLVM;
+
+namespace {
+
+// Provide some forward declarations of the functions that will be generated by
+// the include below.
+static void write(DIExpressionElemAttr attribute,
+ DialectBytecodeWriter &writer);
+static LogicalResult writeAttribute(Attribute attribute,
+ DialectBytecodeWriter &writer);
+
+//===--------------------------------------------------------------------===//
+// Optional ArrayRefs
+//
+// Note that both the writer and reader functions consider attributes to be
+// optional. This is because the attribute may be present or empty.
+//===--------------------------------------------------------------------===//
+
+template <class EntryTy>
+static void writeOptionalArrayRef(DialectBytecodeWriter &writer,
+ ArrayRef<EntryTy> storage) {
+ if (storage.empty()) {
+ writer.writeOwnedBool(false);
+ return;
+ }
+
+ writer.writeOwnedBool(true);
+ writer.writeList(storage, [&](EntryTy val) {
+ if constexpr (std::is_base_of_v<Attribute, EntryTy>) {
+ (void)writer.writeOptionalAttribute(val);
+ } else if constexpr (std::is_integral_v<EntryTy>) {
+ (void)writer.writeVarInt(val);
+ } else {
+ static_assert(true, "EntryTy not supported");
+ }
+ });
+}
+
+template <class EntryTy>
+static LogicalResult readOptionalArrayRef(DialectBytecodeReader &reader,
+ SmallVectorImpl<EntryTy> &storage) {
+ bool isPresent = false;
+ if (failed(reader.readBool(isPresent)))
+ return failure();
+ // Nothing to do here, the array is empty.
+ if (!isPresent)
+ return success();
+
+ auto readEntry = [&]() -> FailureOr<EntryTy> {
+ EntryTy temp;
+ if constexpr (std::is_base_of_v<Attribute, EntryTy>) {
+ if (succeeded(reader.readOptionalAttribute(temp)))
+ return temp;
+ } else if constexpr (std::is_integral_v<EntryTy>) {
+ if (succeeded(reader.readVarInt(temp)))
+ return temp;
+ } else {
+ static_assert(true, "EntryTy not supported");
+ }
+ return failure();
+ };
+
+ return reader.readList(storage, readEntry);
+}
+
+//===--------------------------------------------------------------------===//
+// Optional integral types
+//===--------------------------------------------------------------------===//
+
+template <class EntryTy>
+static void writeOptionalInt(DialectBytecodeWriter &writer,
+ std::optional<EntryTy> storage) {
+ static_assert(std::is_integral_v<EntryTy>,
+ "EntryTy must be an integral type");
+ EntryTy val = storage.value_or(0);
+ writer.writeVarIntWithFlag(val, storage.has_value());
+}
+
+template <class EntryTy>
+static LogicalResult readOptionalInt(DialectBytecodeReader &reader,
+ std::optional<EntryTy> &storage) {
+ static_assert(std::is_integral_v<EntryTy>,
+ "EntryTy must be an integral type");
+ uint64_t result = 0;
+ bool flag = false;
+ if (failed(reader.readVarIntWithFlag(result, flag)))
+ return failure();
+ if (flag)
+ storage = static_cast<EntryTy>(result);
+ else
+ storage = std::nullopt;
+ return success();
+}
+
+//===--------------------------------------------------------------------===//
+// Tablegen generated bytecode functions
+//===--------------------------------------------------------------------===//
+
+#include "mlir/Dialect/LLVMIR/LLVMDialectBytecode.cpp.inc"
+
+//===--------------------------------------------------------------------===//
+// LLVMDialectBytecodeInterface
+//===--------------------------------------------------------------------===//
+
+/// This class implements the bytecode interface for the LLVM dialect.
+struct LLVMDialectBytecodeInterface : public BytecodeDialectInterface {
+ LLVMDialectBytecodeInterface(Dialect *dialect)
+ : BytecodeDialectInterface(dialect) {}
+
+ // Attributes
+ Attribute readAttribute(DialectBytecodeReader &reader) const override {
+ return ::readAttribute(getContext(), reader);
+ }
+
+ LogicalResult writeAttribute(Attribute attr,
+ DialectBytecodeWriter &writer) const override {
+ return ::writeAttribute(attr, writer);
+ }
+
+ // Types
+ Type readType(DialectBytecodeReader &reader) const override {
+ return ::readType(getContext(), reader);
+ }
+
+ LogicalResult writeType(Type type,
+ DialectBytecodeWriter &writer) const override {
+ return ::writeType(type, writer);
+ }
+};
+} // namespace
+
+void LLVM::detail::addBytecodeInterface(LLVMDialect *dialect) {
+ dialect->addInterfaces<LLVMDialectBytecodeInterface>();
+}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h
new file mode 100644
index 0000000..1a17cb4
--- /dev/null
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h
@@ -0,0 +1,27 @@
+//===- LLVMDialectBytecode.h - LLVM Bytecode Implementation -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines hooks into the LLVM dialect bytecode
+// implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H
+#define LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H
+
+namespace mlir::LLVM {
+class LLVMDialect;
+
+namespace detail {
+/// Add the interfaces necessary for encoding the LLVM dialect components in
+/// bytecode.
+void addBytecodeInterface(LLVMDialect *dialect);
+} // namespace detail
+} // namespace mlir::LLVM
+
+#endif // LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp
index 36c498e..f77784a 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp
@@ -161,11 +161,24 @@ XeGPUBlockingPass::getTileShape(Operation *op) const {
xegpu::UpdateOffsetOp, xegpu::LoadMatrixOp>(op))
return getTileShape(op->getOpResult(0));
if (isa<xegpu::PrefetchNdOp, xegpu::LoadNdOp, xegpu::PrefetchOp,
- xegpu::LoadGatherOp, xegpu::StoreMatrixOp>(op))
+ xegpu::StoreMatrixOp>(op))
return getTileShape(op->getOpOperand(0));
- if (isa<xegpu::StoreNdOp, xegpu::StoreScatterOp>(op))
+ if (isa<xegpu::StoreNdOp>(op))
return getTileShape(op->getOpOperand(1));
+ // Handle LoadGatherOp and StoreScatterOp (with and without offset)
+ if (auto loadGatherOp = dyn_cast<xegpu::LoadGatherOp>(op)) {
+ if (loadGatherOp.getOffsets())
+ return getTileShape(loadGatherOp->getOpResult(0));
+ else
+ return getTileShape(loadGatherOp->getOpOperand(0));
+ }
+
+ if (auto storeScatterOp = dyn_cast<xegpu::StoreScatterOp>(op))
+ return getTileShape(storeScatterOp.getOffsets()
+ ? storeScatterOp->getOpOperand(0)
+ : storeScatterOp->getOpOperand(1));
+
if (isa<xegpu::DpasOp>(op)) {
std::optional<SmallVector<int64_t>> aTile =
getTileShape(op->getOpOperand(0));
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index 3d19c5a..9b23dd6 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -2200,10 +2200,9 @@ void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty,
os << '>';
}
os << '[';
- interleave(
- loc.getLocations(),
- [&](Location loc) { printLocationInternal(loc, pretty); },
- [&]() { os << ", "; });
+ interleaveComma(loc.getLocations(), [&](Location loc) {
+ printLocationInternal(loc, pretty);
+ });
os << ']';
})
.Default([&](LocationAttr loc) {
diff --git a/mlir/test/Analysis/test-alias-analysis.mlir b/mlir/test/Analysis/test-alias-analysis.mlir
index 8cbee61..d71adee 100644
--- a/mlir/test/Analysis/test-alias-analysis.mlir
+++ b/mlir/test/Analysis/test-alias-analysis.mlir
@@ -256,3 +256,19 @@ func.func @constants(%arg: memref<2xf32>) attributes {test.ptr = "func"} {
return
}
+
+// -----
+
+// CHECK-LABEL: Testing : "distinct_objects"
+// CHECK-DAG: func.region0#0 <-> func.region0#1: MayAlias
+
+// CHECK-DAG: distinct#0 <-> distinct#1: NoAlias
+// CHECK-DAG: distinct#0 <-> func.region0#0: MustAlias
+// CHECK-DAG: distinct#1 <-> func.region0#0: MayAlias
+// CHECK-DAG: distinct#0 <-> func.region0#1: MayAlias
+// CHECK-DAG: distinct#1 <-> func.region0#1: MustAlias
+
+func.func @distinct_objects(%arg: memref<?xf32>, %arg1: memref<?xf32>) attributes {test.ptr = "func"} {
+ %0, %1 = memref.distinct_objects %arg, %arg1 {test.ptr = "distinct"} : memref<?xf32>, memref<?xf32>
+ return
+}
diff --git a/mlir/test/Dialect/LLVMIR/bytecode.mlir b/mlir/test/Dialect/LLVMIR/bytecode.mlir
new file mode 100644
index 0000000..821b0ac
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/bytecode.mlir
@@ -0,0 +1,35 @@
+// RUN: mlir-opt -verify-roundtrip %s
+
+#access_group = #llvm.access_group<id = distinct[0]<>>
+#access_group1 = #llvm.access_group<id = distinct[1]<>>
+#di_subprogram = #llvm.di_subprogram<recId = distinct[2]<>>
+#loc1 = loc("test.f90":12:14)
+#loc2 = loc("test":4:3)
+#loc6 = loc(fused<#di_subprogram>[#loc1])
+#loc7 = loc(fused<#di_subprogram>[#loc2])
+#loop_annotation = #llvm.loop_annotation<disableNonforced = false, mustProgress = true, startLoc = #loc6, endLoc = #loc7, parallelAccesses = #access_group, #access_group1>
+module {
+ llvm.func @imp_fn() {
+ llvm.return loc(#loc2)
+ } loc(#loc8)
+ llvm.func @loop_annotation_with_locs() {
+ llvm.br ^bb1 {loop_annotation = #loop_annotation} loc(#loc4)
+ ^bb1: // pred: ^bb0
+ llvm.return loc(#loc5)
+ } loc(#loc3)
+} loc(#loc)
+#di_file = #llvm.di_file<"test.f90" in "">
+#di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_program>
+#loc = loc("test":0:0)
+#loc3 = loc("test-path":36:3)
+#loc4 = loc("test-path":37:5)
+#loc5 = loc("test-path":39:5)
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[3]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full>
+#di_compile_unit1 = #llvm.di_compile_unit<id = distinct[4]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full>
+#di_compile_unit2 = #llvm.di_compile_unit<id = distinct[5]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full>
+#di_module = #llvm.di_module<file = #di_file, scope = #di_compile_unit1, name = "mod1">
+#di_module1 = #llvm.di_module<file = #di_file, scope = #di_compile_unit2, name = "mod2">
+#di_imported_entity = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #di_subprogram, entity = #di_module, file = #di_file, line = 1>
+#di_imported_entity1 = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #di_subprogram, entity = #di_module1, file = #di_file, line = 1>
+#di_subprogram1 = #llvm.di_subprogram<recId = distinct[2]<>, id = distinct[6]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "imp_fn", file = #di_file, subprogramFlags = Definition, type = #di_subroutine_type, retainedNodes = #di_imported_entity, #di_imported_entity1>
+#loc8 = loc(fused<#di_subprogram1>[#loc1])
diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
index 1834b0a..d7bf99b 100644
--- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir
+++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+// RUN: mlir-opt -emit-bytecode %s | mlir-opt | FileCheck %s
// CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"debuginfo.mlir" in "/test/">
#file = #llvm.di_file<"debuginfo.mlir" in "/test/">
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 7344797..00e763a 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+// RUN: mlir-opt -verify-roundtrip %s
// CHECK-LABEL: func @baz
@@ -757,7 +757,7 @@ llvm.func @stackrestore(%arg0: !llvm.ptr) {
// CHECK-LABEL: @experimental_noalias_scope_decl
llvm.func @experimental_noalias_scope_decl() {
- // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}}
+ // CHECK: llvm.intr.experimental.noalias.scope.decl #alias_scope{{.*}}
llvm.intr.experimental.noalias.scope.decl #alias_scope
llvm.return
}
@@ -767,7 +767,7 @@ llvm.func @experimental_noalias_scope_decl() {
// CHECK-LABEL: @experimental_noalias_scope_with_string_id
llvm.func @experimental_noalias_scope_with_string_id() {
- // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}}
+ // CHECK: llvm.intr.experimental.noalias.scope.decl #alias_scope{{.*}}
llvm.intr.experimental.noalias.scope.decl #alias_scope2
llvm.return
}
diff --git a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
index 9d63c2d..fe4f44c 100644
--- a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
+++ b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir
@@ -584,3 +584,101 @@ gpu.module @test_kernel {
gpu.return
}
}
+
+// -----
+gpu.module @test_kernel {
+ // CHECK-LABEL: load_with_offsets
+ // CHECK-COUNT-2: xegpu.load {{.*}}[{{.*}}], {{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint<cached>}> : ui64, vector<16xindex>, vector<16xi1> -> vector<16xf32>
+ gpu.func @load_with_offsets(%src: ui64) -> vector<32xf32> {
+ %cst = arith.constant dense<[
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 96, 104, 112, 120,
+ 128, 136, 144, 152, 160, 168, 176, 184,
+ 192, 200, 208, 216, 224, 232, 240, 248
+ ]> : vector<32xindex>
+
+ %c17 = arith.constant 17: index
+ %mask = vector.create_mask %c17: vector<32xi1>
+ %ld = xegpu.load %src[%cst], %mask {chunk_size = 1, layout_result_0 = #xegpu.layout<inst_data = [16]>, l1_hint = #xegpu.cache_hint<cached>} : ui64, vector<32xindex>, vector<32xi1> -> vector<32xf32>
+
+ gpu.return %ld : vector<32xf32>
+ }
+}
+
+// -----
+gpu.module @test_kernel {
+ // CHECK-LABEL: store_with_offsets
+ // CHECK-COUNT-2: xegpu.store {{.*}}[{{.*}}], {{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint<cached>}> : vector<16xf32>, ui64, vector<16xindex>, vector<16xi1>
+ gpu.func @store_with_offsets(%src: ui64) {
+ %cst = arith.constant dense<[
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 96, 104, 112, 120,
+ 128, 136, 144, 152, 160, 168, 176, 184,
+ 192, 200, 208, 216, 224, 232, 240, 248
+ ]> : vector<32xindex>
+
+ %c17 = arith.constant 17: index
+ %mask = vector.create_mask %c17: vector<32xi1>
+
+ %st_vec = arith.constant dense<1023.0>: vector<32xf32>
+ xegpu.store %st_vec, %src[%cst], %mask {chunk_size = 1, layout_operand_0 = #xegpu.layout<inst_data = [16]>,
+ layout_operand_2 = #xegpu.layout<inst_data = [16]>,
+ layout_operand_3 = #xegpu.layout<inst_data = [16]>,
+ l1_hint = #xegpu.cache_hint<cached>} : vector<32xf32>, ui64, vector<32xindex>, vector<32xi1>
+
+ gpu.return
+ }
+}
+
+// -----
+gpu.module @test_kernel {
+ // CHECK-LABEL: load_with_offsets_chunk
+ // CHECK: [[cst:%.+]] = arith.constant dense<0.000000e+00> : vector<32x4xf32>
+ // CHECK: [[cst0:%.+]] = arith.constant dense<[130, 138, 146, 154, 162, 170, 178, 186, 194, 202, 210, 218, 226, 234, 242, 250]> : vector<16xindex>
+ // CHECK: [[cst1:%.+]] = arith.constant dense<[2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122]> : vector<16xindex>
+ // CHECK: [[cst2:%.+]] = arith.constant dense<[128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248]> : vector<16xindex>
+ // CHECK: [[cst3:%.+]] = arith.constant dense<[0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120]> : vector<16xindex>
+ // CHECK-COUNT-4: xegpu.load {{.*}}[{{.*}}], {{.*}} <{chunk_size = 2 : i64, l1_hint = #xegpu.cache_hint<cached>}> : ui64, vector<16xindex>, vector<16xi1> -> vector<16x2xf32>
+ gpu.func @load_with_offsets_chunk(%src: ui64) -> vector<32x4xf32> {
+ %cst = arith.constant dense<[
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 96, 104, 112, 120,
+ 128, 136, 144, 152, 160, 168, 176, 184,
+ 192, 200, 208, 216, 224, 232, 240, 248
+ ]> : vector<32xindex>
+
+ %c17 = arith.constant 17: index
+ %mask = vector.create_mask %c17: vector<32xi1>
+ %ld = xegpu.load %src[%cst], %mask {chunk_size = 4, layout_result_0 = #xegpu.layout<inst_data = [16, 2]>, l1_hint = #xegpu.cache_hint<cached>} : ui64, vector<32xindex>, vector<32xi1> -> vector<32x4xf32>
+ gpu.return %ld : vector<32x4xf32>
+ }
+}
+
+// -----
+gpu.module @test_kernel {
+ // CHECK-LABEL: store_with_offsets_chunk
+ // CHECK: [[cst:%.+]] = arith.constant dense<1.023000e+03> : vector<16x2xf32
+ // CHECK: [[cst0:%.+]] = arith.constant dense<[130, 138, 146, 154, 162, 170, 178, 186, 194, 202, 210, 218, 226, 234, 242, 250]> : vector<16xindex>
+ // CHECK: [[cst1:%.+]] = arith.constant dense<[2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122]> : vector<16xindex>
+ // CHECK: [[cst2:%.+]] = arith.constant dense<[128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248]> : vector<16xindex>
+ // CHECK: [[cst3:%.+]] = arith.constant dense<[0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120]> : vector<16xindex>
+ // CHECK-COUNT-4: xegpu.store {{.*}}[{{.*}}], {{.*}} <{chunk_size = 2 : i64, l1_hint = #xegpu.cache_hint<cached>}> : vector<16x2xf32>, ui64, vector<16xindex>, vector<16xi1>
+ gpu.func @store_with_offsets_chunk(%src: ui64) {
+ %cst = arith.constant dense<[
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 96, 104, 112, 120,
+ 128, 136, 144, 152, 160, 168, 176, 184,
+ 192, 200, 208, 216, 224, 232, 240, 248
+ ]> : vector<32xindex>
+
+ %c17 = arith.constant 17: index
+ %mask = vector.create_mask %c17: vector<32xi1>
+
+ %st_vec = arith.constant dense<1023.>: vector<32x4xf32>
+ xegpu.store %st_vec, %src[%cst], %mask {chunk_size = 4, layout_operand_0 = #xegpu.layout<inst_data = [16, 2]>,
+ layout_operand_2 = #xegpu.layout<inst_data = [16, 2]>,
+ layout_operand_3 = #xegpu.layout<inst_data = [16, 2]>,
+ l1_hint = #xegpu.cache_hint<cached>} : vector<32x4xf32>, ui64, vector<32xindex>, vector<32xi1>
+ gpu.return
+ }
+}