summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
Diffstat (limited to 'flang')
-rw-r--r--flang/cmake/modules/AddFlang.cmake21
-rw-r--r--flang/docs/Directives.md59
-rw-r--r--flang/docs/Extensions.md3
-rw-r--r--flang/docs/Intrinsics.md19
-rw-r--r--flang/examples/FlangOmpReport/yaml_summarizer.py2
-rw-r--r--flang/include/flang/Common/Fortran.h8
-rw-r--r--flang/include/flang/Evaluate/characteristics.h21
-rw-r--r--flang/include/flang/Evaluate/check-expression.h23
-rw-r--r--flang/include/flang/Evaluate/common.h6
-rw-r--r--flang/include/flang/Evaluate/shape.h13
-rw-r--r--flang/include/flang/Evaluate/target.h15
-rw-r--r--flang/include/flang/Evaluate/tools.h26
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.h4
-rw-r--r--flang/include/flang/Frontend/FrontendActions.h5
-rw-r--r--flang/include/flang/Lower/AbstractConverter.h5
-rw-r--r--flang/include/flang/Lower/BoxAnalyzer.h2
-rw-r--r--flang/include/flang/Lower/ConvertConstant.h3
-rw-r--r--flang/include/flang/Lower/DumpEvaluateExpr.h2
-rw-r--r--flang/include/flang/Lower/PFTBuilder.h26
-rw-r--r--flang/include/flang/Lower/Support/Utils.h42
-rw-r--r--flang/include/flang/Optimizer/Builder/IntrinsicCall.h4
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/Assign.h16
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/Inquiry.h14
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/Numeric.h4
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h207
-rw-r--r--flang/include/flang/Optimizer/Builder/Runtime/Reduction.h23
-rw-r--r--flang/include/flang/Optimizer/CodeGen/DescriptorModel.h (renamed from flang/lib/Optimizer/CodeGen/DescriptorModel.h)24
-rw-r--r--flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h13
-rw-r--r--flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td23
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIROps.h1
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIROps.td3
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIROpsSupport.h12
-rw-r--r--flang/include/flang/Optimizer/Dialect/FIRType.h6
-rw-r--r--flang/include/flang/Optimizer/HLFIR/HLFIROps.td18
-rw-r--r--flang/include/flang/Optimizer/Support/Matcher.h5
-rw-r--r--flang/include/flang/Optimizer/Transforms/Passes.h15
-rw-r--r--flang/include/flang/Optimizer/Transforms/Passes.td19
-rw-r--r--flang/include/flang/Parser/dump-parse-tree.h3
-rw-r--r--flang/include/flang/Parser/parse-tree.h12
-rw-r--r--flang/include/flang/Parser/preprocessor.h1
-rw-r--r--flang/include/flang/Parser/provenance.h5
-rw-r--r--flang/include/flang/Parser/token-sequence.h3
-rw-r--r--flang/include/flang/Runtime/assign.h12
-rw-r--r--flang/include/flang/Runtime/inquiry.h7
-rw-r--r--flang/include/flang/Runtime/numeric.h14
-rw-r--r--flang/include/flang/Runtime/pointer.h5
-rw-r--r--flang/include/flang/Runtime/reduce.h425
-rw-r--r--flang/include/flang/Semantics/openmp-directive-sets.h1
-rw-r--r--flang/include/flang/Semantics/symbol.h4
-rw-r--r--flang/include/flang/Tools/CLOptions.inc27
-rw-r--r--flang/lib/Evaluate/characteristics.cpp35
-rw-r--r--flang/lib/Evaluate/check-expression.cpp169
-rw-r--r--flang/lib/Evaluate/fold-integer.cpp30
-rw-r--r--flang/lib/Evaluate/fold-logical.cpp69
-rw-r--r--flang/lib/Evaluate/fold-real.cpp79
-rw-r--r--flang/lib/Evaluate/intrinsics.cpp32
-rw-r--r--flang/lib/Evaluate/shape.cpp2
-rw-r--r--flang/lib/Evaluate/tools.cpp41
-rw-r--r--flang/lib/Frontend/CMakeLists.txt1
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp5
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp68
-rw-r--r--flang/lib/Lower/Allocatable.cpp23
-rw-r--r--flang/lib/Lower/Bridge.cpp365
-rw-r--r--flang/lib/Lower/CallInterface.cpp43
-rw-r--r--flang/lib/Lower/ComponentPath.cpp2
-rw-r--r--flang/lib/Lower/ConvertArrayConstructor.cpp37
-rw-r--r--flang/lib/Lower/ConvertCall.cpp110
-rw-r--r--flang/lib/Lower/ConvertConstant.cpp31
-rw-r--r--flang/lib/Lower/ConvertExpr.cpp243
-rw-r--r--flang/lib/Lower/ConvertExprToHLFIR.cpp23
-rw-r--r--flang/lib/Lower/ConvertType.cpp9
-rw-r--r--flang/lib/Lower/ConvertVariable.cpp17
-rw-r--r--flang/lib/Lower/DirectivesCommon.h8
-rw-r--r--flang/lib/Lower/HostAssociations.cpp10
-rw-r--r--flang/lib/Lower/IO.cpp16
-rw-r--r--flang/lib/Lower/IterationSpace.cpp39
-rw-r--r--flang/lib/Lower/Mangler.cpp2
-rw-r--r--flang/lib/Lower/OpenACC.cpp41
-rw-r--r--flang/lib/Lower/OpenMP/ClauseProcessor.cpp101
-rw-r--r--flang/lib/Lower/OpenMP/ClauseProcessor.h5
-rw-r--r--flang/lib/Lower/OpenMP/Clauses.cpp26
-rw-r--r--flang/lib/Lower/OpenMP/OpenMP.cpp144
-rw-r--r--flang/lib/Lower/OpenMP/ReductionProcessor.cpp128
-rw-r--r--flang/lib/Lower/OpenMP/Utils.cpp2
-rw-r--r--flang/lib/Lower/PFTBuilder.cpp200
-rw-r--r--flang/lib/Lower/VectorSubscripts.cpp95
-rw-r--r--flang/lib/Optimizer/Builder/HLFIRTools.cpp13
-rw-r--r--flang/lib/Optimizer/Builder/IntrinsicCall.cpp280
-rw-r--r--flang/lib/Optimizer/Builder/MutableBox.cpp29
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Assign.cpp24
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Inquiry.cpp28
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Numeric.cpp46
-rw-r--r--flang/lib/Optimizer/Builder/Runtime/Reduction.cpp800
-rw-r--r--flang/lib/Optimizer/CodeGen/CMakeLists.txt1
-rw-r--r--flang/lib/Optimizer/CodeGen/CodeGen.cpp51
-rw-r--r--flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp48
-rw-r--r--flang/lib/Optimizer/CodeGen/TypeConverter.cpp2
-rw-r--r--flang/lib/Optimizer/Dialect/CUF/CUFOps.cpp19
-rw-r--r--flang/lib/Optimizer/Dialect/FIROps.cpp19
-rw-r--r--flang/lib/Optimizer/Dialect/FIRType.cpp20
-rw-r--r--flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp12
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp84
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/InlineElementals.cpp3
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp3
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp3
-rw-r--r--flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp16
-rw-r--r--flang/lib/Optimizer/Transforms/AssumedRankOpConversion.cpp7
-rw-r--r--flang/lib/Optimizer/Transforms/CMakeLists.txt2
-rw-r--r--flang/lib/Optimizer/Transforms/ConstantArgumentGlobalisation.cpp185
-rw-r--r--flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp6
-rw-r--r--flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp221
-rw-r--r--flang/lib/Optimizer/Transforms/DebugTypeGenerator.h25
-rw-r--r--flang/lib/Optimizer/Transforms/FunctionAttr.cpp20
-rw-r--r--flang/lib/Optimizer/Transforms/StackArrays.cpp2
-rw-r--r--flang/lib/Optimizer/Transforms/StackReclaim.cpp52
-rw-r--r--flang/lib/Parser/Fortran-parsers.cpp6
-rw-r--r--flang/lib/Parser/expr-parsers.cpp3
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp5
-rw-r--r--flang/lib/Parser/prescan.cpp149
-rw-r--r--flang/lib/Parser/prescan.h9
-rw-r--r--flang/lib/Parser/program-parsers.cpp24
-rw-r--r--flang/lib/Parser/provenance.cpp10
-rw-r--r--flang/lib/Parser/token-parsers.h28
-rw-r--r--flang/lib/Parser/token-sequence.cpp17
-rw-r--r--flang/lib/Parser/unparse.cpp23
-rw-r--r--flang/lib/Semantics/CMakeLists.txt1
-rw-r--r--flang/lib/Semantics/canonicalize-directives.cpp124
-rw-r--r--flang/lib/Semantics/canonicalize-directives.h22
-rw-r--r--flang/lib/Semantics/check-acc-structure.cpp14
-rw-r--r--flang/lib/Semantics/check-allocate.cpp2
-rw-r--r--flang/lib/Semantics/check-call.cpp29
-rw-r--r--flang/lib/Semantics/check-coarray.cpp2
-rw-r--r--flang/lib/Semantics/check-cuda.cpp4
-rw-r--r--flang/lib/Semantics/check-declarations.cpp177
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp95
-rw-r--r--flang/lib/Semantics/expression.cpp27
-rw-r--r--flang/lib/Semantics/pointer-assignment.cpp7
-rw-r--r--flang/lib/Semantics/resolve-directives.cpp10
-rw-r--r--flang/lib/Semantics/resolve-names.cpp170
-rw-r--r--flang/lib/Semantics/runtime-type-info.cpp5
-rw-r--r--flang/lib/Semantics/scope.cpp2
-rw-r--r--flang/lib/Semantics/semantics.cpp2
-rw-r--r--flang/lib/Semantics/symbol.cpp13
-rw-r--r--flang/module/__fortran_builtins.f9051
-rw-r--r--flang/module/__fortran_ieee_exceptions.f9053
-rw-r--r--flang/module/ieee_arithmetic.f9048
-rw-r--r--flang/runtime/ISO_Fortran_binding.cpp10
-rw-r--r--flang/runtime/assign.cpp32
-rw-r--r--flang/runtime/complex-reduction.c34
-rw-r--r--flang/runtime/complex-reduction.h96
-rw-r--r--flang/runtime/descriptor.cpp11
-rw-r--r--flang/runtime/execute.cpp121
-rw-r--r--flang/runtime/external-unit.cpp18
-rw-r--r--flang/runtime/inquiry.cpp38
-rw-r--r--flang/runtime/numeric-templates.h104
-rw-r--r--flang/runtime/numeric.cpp21
-rw-r--r--flang/runtime/pointer.cpp67
-rw-r--r--flang/runtime/pseudo-unit.cpp2
-rw-r--r--flang/runtime/reduce.cpp615
-rw-r--r--flang/runtime/unit.h2
-rw-r--r--flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir54
-rw-r--r--flang/test/Driver/Inputs/libfun.f904
-rw-r--r--flang/test/Driver/bbc-mlir-pass-pipeline.f904
-rw-r--r--flang/test/Driver/mlink-builtin-bc.f9015
-rw-r--r--flang/test/Driver/mlir-debug-pass-pipeline.f904
-rw-r--r--flang/test/Driver/mlir-pass-pipeline.f904
-rw-r--r--flang/test/Driver/mllvm_vs_mmlir.f902
-rw-r--r--flang/test/Driver/print-resource-dir.F904
-rw-r--r--flang/test/Driver/target-cpu-features.f904
-rw-r--r--flang/test/Evaluate/fold-ieee.f9064
-rw-r--r--flang/test/Evaluate/fold-nearest.f906
-rw-r--r--flang/test/Evaluate/folding04.f9013
-rw-r--r--flang/test/Evaluate/rewrite06.f906
-rw-r--r--flang/test/Fir/alloc.fir12
-rw-r--r--flang/test/Fir/basic-program.fir4
-rw-r--r--flang/test/Fir/boxproc.fir14
-rw-r--r--flang/test/Fir/convert-to-llvm-openmp-and-fir.fir200
-rw-r--r--flang/test/Fir/convert-to-llvm.fir57
-rw-r--r--flang/test/Fir/rebox_assumed_rank_codegen.fir13
-rw-r--r--flang/test/Fir/tbaa.fir19
-rw-r--r--flang/test/Fir/vector-always-cfg.fir32
-rw-r--r--flang/test/Fir/vector-always.fir21
-rw-r--r--flang/test/HLFIR/assumed-type-actual-args.f9039
-rw-r--r--flang/test/HLFIR/assumed_shape_with_value_keyword.f9032
-rw-r--r--flang/test/HLFIR/copy-in-out-codegen.fir188
-rw-r--r--flang/test/HLFIR/copy-in-out.fir25
-rw-r--r--flang/test/HLFIR/memory-effects.fir128
-rw-r--r--flang/test/Integration/OpenMP/copyprivate.f902
-rw-r--r--flang/test/Integration/OpenMP/map-types-and-sizes.f9041
-rw-r--r--flang/test/Integration/debug-allocatable-1.f9024
-rw-r--r--flang/test/Integration/debug-assumed-shape-array.f9013
-rw-r--r--flang/test/Integration/debug-char-type-1.f9025
-rw-r--r--flang/test/Integration/debug-local-var-2.f90110
-rw-r--r--flang/test/Integration/debug-ptr-type.f9048
-rw-r--r--flang/test/Integration/vector-always.f9014
-rw-r--r--flang/test/Lower/CUDA/cuda-data-attribute.cuf17
-rw-r--r--flang/test/Lower/CUDA/cuda-data-transfer.cuf43
-rw-r--r--flang/test/Lower/CUDA/cuda-kernel-do-reduction.cuf37
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-calls.f90118
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-entry.f9028
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f9012
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-inquiries-3.f90194
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-inquiries.f9046
-rw-r--r--flang/test/Lower/HLFIR/assumed-rank-internal-proc.f90128
-rw-r--r--flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f9016
-rw-r--r--flang/test/Lower/HLFIR/calls-assumed-shape.f908
-rw-r--r--flang/test/Lower/HLFIR/calls-constant-expr-arg.f904
-rw-r--r--flang/test/Lower/HLFIR/calls-optional.f9013
-rw-r--r--flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f904
-rw-r--r--flang/test/Lower/HLFIR/convert-variable-assumed-rank.f904
-rw-r--r--flang/test/Lower/HLFIR/elemental-result-length.f9025
-rw-r--r--flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f908
-rw-r--r--flang/test/Lower/HLFIR/select-rank.f9030
-rw-r--r--flang/test/Lower/Intrinsics/Todo/reduce.f9013
-rw-r--r--flang/test/Lower/Intrinsics/erfc_scaled.f9023
-rw-r--r--flang/test/Lower/Intrinsics/ieee_femodes.f9060
-rw-r--r--flang/test/Lower/Intrinsics/ieee_festatus.f9052
-rw-r--r--flang/test/Lower/Intrinsics/ieee_flag.f90193
-rw-r--r--flang/test/Lower/Intrinsics/ieee_logb.f9012
-rw-r--r--flang/test/Lower/Intrinsics/ieee_max_min.f9068
-rw-r--r--flang/test/Lower/Intrinsics/ieee_operator_eq.f9036
-rw-r--r--flang/test/Lower/Intrinsics/ieee_rounding.f9034
-rw-r--r--flang/test/Lower/Intrinsics/reduce.f90877
-rw-r--r--flang/test/Lower/Intrinsics/ubound01.f902
-rw-r--r--flang/test/Lower/OpenMP/Todo/loop-directive.f9015
-rw-r--r--flang/test/Lower/OpenMP/Todo/reduction-array-intrinsic.f9011
-rw-r--r--flang/test/Lower/OpenMP/Todo/reduction-derived-type-field.f903
-rw-r--r--flang/test/Lower/OpenMP/common-block-map.f9083
-rw-r--r--flang/test/Lower/OpenMP/copyprivate2.f9056
-rw-r--r--flang/test/Lower/OpenMP/declare-target-func-and-subr.f904
-rw-r--r--flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f904
-rw-r--r--flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f904
-rw-r--r--flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f902
-rw-r--r--flang/test/Lower/OpenMP/distribute.f90114
-rw-r--r--flang/test/Lower/OpenMP/function-filtering-2.f906
-rw-r--r--flang/test/Lower/OpenMP/if-clause.f90229
-rw-r--r--flang/test/Lower/OpenMP/loop-compound.f90 (renamed from flang/test/Lower/OpenMP/loop-combined.f90)38
-rw-r--r--flang/test/Lower/OpenMP/order-clause.f9076
-rw-r--r--flang/test/Lower/OpenMP/parallel-reduction-mixed.f9048
-rw-r--r--flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90131
-rw-r--r--flang/test/Lower/OpenMP/reduction-array-intrinsic.f9096
-rw-r--r--flang/test/Lower/OpenMP/simd.f9041
-rw-r--r--flang/test/Lower/OpenMP/simd_aarch64.f9016
-rw-r--r--flang/test/Lower/OpenMP/simd_x86_64.f9048
-rw-r--r--flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90299
-rw-r--r--flang/test/Lower/OpenMP/wsloop-reduction-pointer.f90110
-rw-r--r--flang/test/Lower/PowerPC/ppc-mma-assemble-disassemble.f90761
-rw-r--r--flang/test/Lower/PowerPC/ppc-mma-outer-product-1.f901512
-rw-r--r--flang/test/Lower/PowerPC/ppc-mma-outer-product-2.f90754
-rw-r--r--flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f908
-rw-r--r--flang/test/Lower/PowerPC/ppc-vector-types.f908
-rw-r--r--flang/test/Lower/call-copy-in-out.f9024
-rw-r--r--flang/test/Lower/character-local-variables.f905
-rw-r--r--flang/test/Lower/dummy-argument-assumed-shape-optional.f906
-rw-r--r--flang/test/Lower/dummy-argument-optional-2.f9010
-rw-r--r--flang/test/Lower/func-attrs.f9031
-rw-r--r--flang/test/Lower/host-associated.f902
-rw-r--r--flang/test/Lower/loops3.f9023
-rw-r--r--flang/test/Lower/optional-value-caller.f9010
-rw-r--r--flang/test/Lower/pre-fir-tree09.f90100
-rw-r--r--flang/test/Lower/vector-always.f9026
-rw-r--r--flang/test/Parser/OpenMP/target-loop-unparse.f9053
-rw-r--r--flang/test/Parser/compiler-directives.f909
-rw-r--r--flang/test/Parser/recovery01.f9010
-rw-r--r--flang/test/Parser/recovery02.f908
-rw-r--r--flang/test/Preprocessing/cond-contin.F9021
-rw-r--r--flang/test/Preprocessing/directive-contin-with-pp.F9063
-rw-r--r--flang/test/Preprocessing/ff-args.h1
-rw-r--r--flang/test/Preprocessing/ff-include-args.F14
-rw-r--r--flang/test/Preprocessing/inc-contin-1.F6
-rw-r--r--flang/test/Preprocessing/inc-contin-1.h1
-rw-r--r--flang/test/Preprocessing/inc-contin-2.F909
-rw-r--r--flang/test/Preprocessing/inc-contin-2a.h1
-rw-r--r--flang/test/Preprocessing/inc-contin-2b.h1
-rw-r--r--flang/test/Preprocessing/include-args.F902
-rw-r--r--flang/test/Preprocessing/multi-cont.F906
-rw-r--r--flang/test/Semantics/OpenMP/reduction09.f9010
-rw-r--r--flang/test/Semantics/OpenMP/reduction14.f9097
-rw-r--r--flang/test/Semantics/bind-c15.f907
-rw-r--r--flang/test/Semantics/bind-c16.f905
-rw-r--r--flang/test/Semantics/c_loc01.f9013
-rw-r--r--flang/test/Semantics/call05.f906
-rw-r--r--flang/test/Semantics/call10.f904
-rw-r--r--flang/test/Semantics/cuf16.cuf95
-rw-r--r--flang/test/Semantics/declarations02.f906
-rw-r--r--flang/test/Semantics/elemental01.f9038
-rw-r--r--flang/test/Semantics/loop-directives.f9019
-rw-r--r--flang/test/Semantics/null01.f908
-rw-r--r--flang/test/Semantics/select-rank03.f9010
-rw-r--r--flang/test/Transforms/constant-argument-globalisation-2.fir98
-rw-r--r--flang/test/Transforms/constant-argument-globalisation.fir67
-rw-r--r--flang/test/Transforms/debug-90683.fir2
-rw-r--r--flang/test/Transforms/debug-allocatable-1.fir26
-rw-r--r--flang/test/Transforms/debug-assumed-shape-array.fir16
-rw-r--r--flang/test/Transforms/debug-char-type-1.fir26
-rw-r--r--flang/test/Transforms/debug-complex-1.fir2
-rw-r--r--flang/test/Transforms/debug-fixed-array-type.fir2
-rw-r--r--flang/test/Transforms/debug-fn-info.f9045
-rw-r--r--flang/test/Transforms/debug-fn-info.fir75
-rw-r--r--flang/test/Transforms/debug-line-table-existing.fir2
-rw-r--r--flang/test/Transforms/debug-line-table-inc-file.fir4
-rw-r--r--flang/test/Transforms/debug-line-table-inc-same-file.fir2
-rw-r--r--flang/test/Transforms/debug-line-table.fir2
-rw-r--r--flang/test/Transforms/debug-local-var-2.f9094
-rw-r--r--flang/test/Transforms/debug-local-var.f9054
-rw-r--r--flang/test/Transforms/debug-local-var.fir100
-rw-r--r--flang/test/Transforms/debug-module-1.fir2
-rw-r--r--flang/test/Transforms/debug-ptr-type.fir40
-rw-r--r--flang/test/Transforms/stack-reclaime.fir14
-rw-r--r--flang/unittests/Evaluate/intrinsics.cpp1
-rw-r--r--flang/unittests/Frontend/FrontendActionTest.cpp2
-rw-r--r--flang/unittests/Runtime/CommandTest.cpp82
-rw-r--r--flang/unittests/Runtime/Inquiry.cpp103
-rw-r--r--flang/unittests/Runtime/Numeric.cpp8
-rw-r--r--flang/unittests/Runtime/Reduction.cpp9
315 files changed, 12822 insertions, 4449 deletions
diff --git a/flang/cmake/modules/AddFlang.cmake b/flang/cmake/modules/AddFlang.cmake
index 3a5119b83831..aeb4d862cf78 100644
--- a/flang/cmake/modules/AddFlang.cmake
+++ b/flang/cmake/modules/AddFlang.cmake
@@ -51,19 +51,28 @@ function(add_flang_library name)
endif()
- if (ARG_SHARED)
+ if(ARG_SHARED AND ARG_STATIC)
+ set(LIBTYPE SHARED STATIC)
+ elseif(ARG_SHARED)
set(LIBTYPE SHARED)
else()
# llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set,
# so we need to handle it here.
- if (BUILD_SHARED_LIBS AND NOT ARG_STATIC)
- set(LIBTYPE SHARED OBJECT)
+ if(BUILD_SHARED_LIBS)
+ set(LIBTYPE SHARED)
else()
- set(LIBTYPE STATIC OBJECT)
+ set(LIBTYPE STATIC)
endif()
- set_property(GLOBAL APPEND PROPERTY FLANG_STATIC_LIBS ${name})
+ if(NOT XCODE AND NOT MSVC_IDE)
+ # The Xcode generator doesn't handle object libraries correctly.
+ # The Visual Studio CMake generator does handle object libraries
+ # correctly, but it is preferable to list the libraries with their
+ # source files (instead of the object files and the source files in
+ # a separate target in the "Object Libraries" folder)
+ list(APPEND LIBTYPE OBJECT)
+ endif()
+ set_property(GLOBAL APPEND PROPERTY CLANG_STATIC_LIBS ${name})
endif()
-
llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
clang_target_link_libraries(${name} PRIVATE ${ARG_CLANG_LIBS})
diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md
index fe08b4f855f2..f356f762b13a 100644
--- a/flang/docs/Directives.md
+++ b/flang/docs/Directives.md
@@ -36,3 +36,62 @@ A list of non-standard directives supported by Flang
and is limited to 256.
[This directive is currently recognised by the parser, but not
handled by the other parts of the compiler].
+* `!dir$ vector always` forces vectorization on the following loop regardless
+ of cost model decisions. The loop must still be vectorizable.
+ [This directive currently only works on plain do loops without labels].
+
+# Directive Details
+
+## Introduction
+Directives are commonly used in Fortran programs to specify additional actions
+to be performed by the compiler. The directives are always specified with the
+`!dir$` or `cdir$` prefix.
+
+## Loop Directives
+Some directives are associated with the following construct, for example loop
+directives. Directives on loops are used to specify additional transformation to
+be performed by the compiler like enabling vectorisation, unrolling, interchange
+etc.
+
+Currently loop directives are not accepted in the presence of OpenMP or OpenACC
+constructs on the loop. This should be implemented as it is used in some
+applications.
+
+### Array Expressions
+It is to be decided whether loop directives should also be able to be associated
+with array expressions.
+
+## Semantics
+Directives that are associated with constructs must appear in the same section
+as the construct they are associated with, for example loop directives must
+appear in the executable section as the loops appear there. To facilitate this
+the parse tree is corrected to move such directives that appear in the
+specification part into the execution part.
+
+When a directive that must be associated with a construct appears, a search
+forward from that directive to the next non-directive construct is performed to
+check that that construct matches the expected construct for the directive.
+Skipping other intermediate directives allows multiple directives to appear on
+the same construct.
+
+## Lowering
+Evaluation is extended with a new field called dirs for representing directives
+associated with that Evaluation. When lowering loop directives, the associated
+Do Loop's evaluation is found and the directive is added to it. This information
+is used only during the lowering of the loop.
+
+### Representation in LLVM
+The `llvm.loop` metadata is used in LLVM to provide information to the optimizer
+about the loop. For example, the `llvm.loop.vectorize.enable` metadata informs
+the optimizer that a loop can be vectorized without considering its cost-model.
+This attribute is added to the loop condition branch.
+
+### Representation in MLIR
+The MLIR LLVM dialect models this by an attribute called LoopAnnotation
+Attribute. The attribute can be added to the latch of the loop in the cf
+dialect and is then carried through lowering to the LLVM dialect.
+
+## Testing
+Since directives must maintain a flow from source to LLVM IR, an integration
+test is provided that tests the `vector always` directive, as well as individual
+lit tests for each of the parsing, semantics and lowering stages.
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 14410f17ab8a..82f9a021c14e 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -374,6 +374,9 @@ end
required, with warnings, even if it lacks the BIND(C) attribute.
* A "mult-operand" in an expression can be preceded by a unary
`+` or `-` operator.
+* `BIND(C, NAME="...", CDEFINED)` signifies that the storage for an
+ interoperable variable will be allocated outside of Fortran,
+ probably by a C or C++ external definition.
### Extensions supported when enabled by options
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 8853d4d9e1c7..d1f7cd8372e2 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -893,16 +893,17 @@ used in constant expressions have currently no folding support at all.
##### `CMDSTAT`:
- Synchronous execution:
- - -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
- - -1: The processor does not support command line execution.
+ - -2: `ASYNC_NO_SUPPORT_ERR` - No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
+ - -1: `NO_SUPPORT_ERR` - The processor does not support command line execution. (system returns -1 with errno `ENOENT`)
+ - 0: `CMD_EXECUTED` - Command executed with no error.
- \+ (positive value): An error condition occurs.
- - 1: Fork Error (occurs only on POSIX-compatible systems).
- - 2: Execution Error (command exits with status -1).
- - 3: Invalid Command Error (determined by the exit code depending on the system).
- - On Windows: exit code is 1.
- - On POSIX-compatible systems: exit code is 127 or 126.
- - 4: Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
- - 0: Otherwise.
+ - 1: `FORK_ERR` - Fork Error (occurs only on POSIX-compatible systems).
+ - 2: `EXECL_ERR` - Execution Error (system returns -1 with other errno).
+ - 3: `COMMAND_EXECUTION_ERR` - Invalid Command Error (exit code 1).
+ - 4: `COMMAND_CANNOT_EXECUTE_ERR` - Command Cannot Execute Error (Linux exit code 126).
+ - 5: `COMMAND_NOT_FOUND_ERR` - Command Not Found Error (Linux exit code 127).
+ - 6: `INVALID_CL_ERR` - Invalid Command Line Error (covers all other non-zero exit codes).
+ - 7: `SIGNAL_ERR` - Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
- Asynchronous execution:
- 0 will always be assigned.
diff --git a/flang/examples/FlangOmpReport/yaml_summarizer.py b/flang/examples/FlangOmpReport/yaml_summarizer.py
index 5726ff8da77f..1e522c00aab8 100644
--- a/flang/examples/FlangOmpReport/yaml_summarizer.py
+++ b/flang/examples/FlangOmpReport/yaml_summarizer.py
@@ -21,7 +21,7 @@ stdout. It can be ran as:
Parameters:
-d --directory Specify which directory to scan. Multiple directories can be searched by
- providing a semicolon seperated list of directories.
+ providing a semicolon separated list of directories.
-l --log Combine all yaml files into one log (instead of generating a summary)
diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h
index 0701e3e8b64c..5b2ed43a8f99 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -67,12 +67,14 @@ ENUM_CLASS(
const char *AsFortran(DefinedIo);
// Floating-point rounding modes; these are packed into a byte to save
-// room in the runtime's format processing context structure.
+// room in the runtime's format processing context structure. These
+// enumerators are defined with the corresponding values returned from
+// llvm.get.rounding.
enum class RoundingMode : std::uint8_t {
- TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
ToZero, // ROUND=ZERO, RZ - truncation
- Down, // ROUND=DOWN, RD
+ TiesToEven, // ROUND=NEAREST, RN - default IEEE rounding
Up, // ROUND=UP, RU
+ Down, // ROUND=DOWN, RD
TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
};
diff --git a/flang/include/flang/Evaluate/characteristics.h b/flang/include/flang/Evaluate/characteristics.h
index 9695c665d0cb..11533a7259b0 100644
--- a/flang/include/flang/Evaluate/characteristics.h
+++ b/flang/include/flang/Evaluate/characteristics.h
@@ -55,8 +55,8 @@ std::optional<bool> DistinguishableOpOrAssign(
// Shapes of function results and dummy arguments have to have
// the same rank, the same deferred dimensions, and the same
// values for explicit dimensions when constant.
-bool ShapesAreCompatible(
- const Shape &, const Shape &, bool *possibleWarning = nullptr);
+bool ShapesAreCompatible(const std::optional<Shape> &,
+ const std::optional<Shape> &, bool *possibleWarning = nullptr);
class TypeAndShape {
public:
@@ -64,17 +64,17 @@ public:
Attr, AssumedRank, AssumedShape, AssumedSize, DeferredShape, Coarray)
using Attrs = common::EnumSet<Attr, Attr_enumSize>;
- explicit TypeAndShape(DynamicType t) : type_{t} { AcquireLEN(); }
- TypeAndShape(DynamicType t, int rank) : type_{t}, shape_(rank) {
+ explicit TypeAndShape(DynamicType t) : type_{t}, shape_{Shape{}} {
+ AcquireLEN();
+ }
+ TypeAndShape(DynamicType t, int rank) : type_{t}, shape_{Shape(rank)} {
AcquireLEN();
}
TypeAndShape(DynamicType t, Shape &&s) : type_{t}, shape_{std::move(s)} {
AcquireLEN();
}
TypeAndShape(DynamicType t, std::optional<Shape> &&s) : type_{t} {
- if (s) {
- shape_ = std::move(*s);
- }
+ shape_ = std::move(s);
AcquireLEN();
}
DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(TypeAndShape)
@@ -172,11 +172,12 @@ public:
LEN_ = std::move(len);
return *this;
}
- const Shape &shape() const { return shape_; }
+ const std::optional<Shape> &shape() const { return shape_; }
const Attrs &attrs() const { return attrs_; }
int corank() const { return corank_; }
- int Rank() const { return GetRank(shape_); }
+ // Return -1 for assumed-rank as a safety.
+ int Rank() const { return shape_ ? GetRank(*shape_) : -1; }
// Can sequence association apply to this argument?
bool CanBeSequenceAssociated() const {
@@ -211,7 +212,7 @@ private:
protected:
DynamicType type_;
std::optional<Expr<SubscriptInteger>> LEN_;
- Shape shape_;
+ std::optional<Shape> shape_;
Attrs attrs_;
int corank_{0};
};
diff --git a/flang/include/flang/Evaluate/check-expression.h b/flang/include/flang/Evaluate/check-expression.h
index e942ad7ebfc4..b711d289ba52 100644
--- a/flang/include/flang/Evaluate/check-expression.h
+++ b/flang/include/flang/Evaluate/check-expression.h
@@ -77,23 +77,26 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &,
// specification expressions.
template <typename A>
-void CheckSpecificationExpr(
- const A &, const semantics::Scope &, FoldingContext &);
-extern template void CheckSpecificationExpr(
- const Expr<SomeType> &x, const semantics::Scope &, FoldingContext &);
-extern template void CheckSpecificationExpr(
- const Expr<SomeInteger> &x, const semantics::Scope &, FoldingContext &);
+void CheckSpecificationExpr(const A &, const semantics::Scope &,
+ FoldingContext &, bool forElementalFunctionResult);
+extern template void CheckSpecificationExpr(const Expr<SomeType> &x,
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
+extern template void CheckSpecificationExpr(const Expr<SomeInteger> &x,
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
extern template void CheckSpecificationExpr(const Expr<SubscriptInteger> &x,
- const semantics::Scope &, FoldingContext &);
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SomeType>> &x, const semantics::Scope &,
- FoldingContext &);
+ FoldingContext &, bool forElementalFunctionResult);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SomeInteger>> &x, const semantics::Scope &,
- FoldingContext &);
+ FoldingContext &, bool forElementalFunctionResult);
extern template void CheckSpecificationExpr(
const std::optional<Expr<SubscriptInteger>> &x, const semantics::Scope &,
- FoldingContext &);
+ FoldingContext &, bool forElementalFunctionResult);
// Contiguity & "simple contiguity" (9.5.4)
template <typename A>
diff --git a/flang/include/flang/Evaluate/common.h b/flang/include/flang/Evaluate/common.h
index c2c7711c4684..d493e5fe0441 100644
--- a/flang/include/flang/Evaluate/common.h
+++ b/flang/include/flang/Evaluate/common.h
@@ -128,9 +128,9 @@ static constexpr bool Satisfies(RelationalOperator op, Relation relation) {
return false; // silence g++ warning
}
-ENUM_CLASS(
- RealFlag, Overflow, DivideByZero, InvalidArgument, Underflow, Inexact)
-
+// These are ordered like the bits in a common fenv.h header file.
+ENUM_CLASS(RealFlag, InvalidArgument, Denorm, DivideByZero, Overflow, Underflow,
+ Inexact)
using RealFlags = common::EnumSet<RealFlag, RealFlag_enumSize>;
template <typename A> struct ValueWithRealFlags {
diff --git a/flang/include/flang/Evaluate/shape.h b/flang/include/flang/Evaluate/shape.h
index 1294c92a01ab..e33044c0d34e 100644
--- a/flang/include/flang/Evaluate/shape.h
+++ b/flang/include/flang/Evaluate/shape.h
@@ -46,6 +46,13 @@ Constant<ExtentType> AsConstantShape(const ConstantSubscripts &);
ConstantSubscripts AsConstantExtents(const Constant<ExtentType> &);
std::optional<ConstantSubscripts> AsConstantExtents(
FoldingContext &, const Shape &);
+inline std::optional<ConstantSubscripts> AsConstantExtents(
+ FoldingContext &foldingContext, const std::optional<Shape> &maybeShape) {
+ if (maybeShape) {
+ return AsConstantExtents(foldingContext, *maybeShape);
+ }
+ return std::nullopt;
+}
Shape AsShape(const ConstantSubscripts &);
std::optional<Shape> AsShape(const std::optional<ConstantSubscripts> &);
@@ -121,6 +128,12 @@ MaybeExtentExpr CountTrips(
// Computes SIZE() == PRODUCT(shape)
MaybeExtentExpr GetSize(Shape &&);
ConstantSubscript GetSize(const ConstantSubscripts &);
+inline MaybeExtentExpr GetSize(const std::optional<Shape> &maybeShape) {
+ if (maybeShape) {
+ return GetSize(Shape(*maybeShape));
+ }
+ return std::nullopt;
+}
// Utility predicate: does an expression reference any implied DO index?
bool ContainsAnyImpliedDoIndex(const ExtentExpr &);
diff --git a/flang/include/flang/Evaluate/target.h b/flang/include/flang/Evaluate/target.h
index 10033d02a540..d076fcbf0830 100644
--- a/flang/include/flang/Evaluate/target.h
+++ b/flang/include/flang/Evaluate/target.h
@@ -13,6 +13,8 @@
#define FORTRAN_EVALUATE_TARGET_H_
#include "flang/Common/Fortran.h"
+#include "flang/Common/enum-class.h"
+#include "flang/Common/enum-set.h"
#include "flang/Evaluate/common.h"
#include <cstdint>
@@ -32,6 +34,11 @@ struct Rounding {
#endif
};
+ENUM_CLASS(IeeeFeature, Denormal, Divide, Flags, Halting, Inf, Io, NaN,
+ Rounding, Sqrt, Standard, Subnormal, UnderflowControl)
+
+using IeeeFeatures = common::EnumSet<IeeeFeature, 16>;
+
class TargetCharacteristics {
public:
TargetCharacteristics();
@@ -95,6 +102,9 @@ public:
bool isPPC() const { return isPPC_; }
void set_isPPC(bool isPPC = false);
+ IeeeFeatures &ieeeFeatures() { return ieeeFeatures_; }
+ const IeeeFeatures &ieeeFeatures() const { return ieeeFeatures_; }
+
private:
static constexpr int maxKind{32};
std::uint8_t byteSize_[common::TypeCategory_enumSize][maxKind]{};
@@ -110,6 +120,11 @@ private:
std::size_t maxAlignment_{8 /*at least*/};
std::string compilerOptionsString_;
std::string compilerVersionString_;
+ IeeeFeatures ieeeFeatures_{IeeeFeature::Denormal, IeeeFeature::Divide,
+ IeeeFeature::Flags, IeeeFeature::Halting, IeeeFeature::Inf,
+ IeeeFeature::Io, IeeeFeature::NaN, IeeeFeature::Rounding,
+ IeeeFeature::Sqrt, IeeeFeature::Standard, IeeeFeature::Subnormal,
+ IeeeFeature::UnderflowControl};
};
} // namespace Fortran::evaluate
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index 378a5fca0326..625f9e5f6576 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -98,6 +98,9 @@ template <typename T> bool IsAssumedRank(const Expr<T> &expr) {
template <typename A> bool IsAssumedRank(const std::optional<A> &x) {
return x && IsAssumedRank(*x);
}
+template <typename A> bool IsAssumedRank(const A *x) {
+ return x && IsAssumedRank(*x);
+}
// Predicate: true when an expression is a coarray (corank > 0)
bool IsCoarray(const ActualArgument &);
@@ -450,12 +453,12 @@ struct ExtractSubstringHelper {
template <typename T>
static std::optional<Substring> visit(const Designator<T> &e) {
- return std::visit([](auto &&s) { return visit(s); }, e.u);
+ return common::visit([](auto &&s) { return visit(s); }, e.u);
}
template <typename T>
static std::optional<Substring> visit(const Expr<T> &e) {
- return std::visit([](auto &&s) { return visit(s); }, e.u);
+ return common::visit([](auto &&s) { return visit(s); }, e.u);
}
};
@@ -1231,12 +1234,13 @@ bool CheckForCoindexedObject(parser::ContextualMessages &,
const std::string &argName);
// Get the number of distinct symbols with CUDA attribute in the expression.
-template <typename A> inline int GetNbOfCUDASymbols(const A &expr) {
+template <typename A> inline int GetNbOfCUDADeviceSymbols(const A &expr) {
semantics::UnorderedSymbolSet symbols;
for (const Symbol &sym : CollectSymbols(expr)) {
if (const auto *details =
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
- if (details->cudaDataAttr()) {
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != common::CUDADataAttr::Pinned) {
symbols.insert(sym);
}
}
@@ -1246,8 +1250,8 @@ template <typename A> inline int GetNbOfCUDASymbols(const A &expr) {
// Check if any of the symbols part of the expression has a CUDA data
// attribute.
-template <typename A> inline bool HasCUDAAttrs(const A &expr) {
- return GetNbOfCUDASymbols(expr) > 0;
+template <typename A> inline bool HasCUDADeviceAttrs(const A &expr) {
+ return GetNbOfCUDADeviceSymbols(expr) > 0;
}
/// Check if the expression is a mix of host and device variables that require
@@ -1258,7 +1262,8 @@ inline bool HasCUDAImplicitTransfer(const Expr<SomeType> &expr) {
for (const Symbol &sym : CollectSymbols(expr)) {
if (const auto *details =
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
- if (details->cudaDataAttr()) {
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != common::CUDADataAttr::Pinned) {
++deviceSymbols;
} else {
if (sym.owner().IsDerivedType()) {
@@ -1267,7 +1272,8 @@ inline bool HasCUDAImplicitTransfer(const Expr<SomeType> &expr) {
.GetSymbol()
->GetUltimate()
.detailsIf<semantics::ObjectEntityDetails>()) {
- if (details->cudaDataAttr()) {
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != common::CUDADataAttr::Pinned) {
++deviceSymbols;
}
}
@@ -1320,6 +1326,10 @@ bool IsBuiltinCPtr(const Symbol &);
bool IsEventType(const DerivedTypeSpec *);
bool IsLockType(const DerivedTypeSpec *);
bool IsNotifyType(const DerivedTypeSpec *);
+// Is this derived type IEEE_FLAG_TYPE from module ISO_IEEE_EXCEPTIONS?
+bool IsIeeeFlagType(const DerivedTypeSpec *);
+// Is this derived type IEEE_ROUND_TYPE from module ISO_IEEE_ARITHMETIC?
+bool IsIeeeRoundType(const DerivedTypeSpec *);
// Is this derived type TEAM_TYPE from module ISO_FORTRAN_ENV?
bool IsTeamType(const DerivedTypeSpec *);
// Is this derived type TEAM_TYPE, C_PTR, or C_FUNPTR?
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 918192abae72..3bc5d93c4c43 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -56,6 +56,10 @@ public:
/// are offloading binaries containing device images and metadata.
std::vector<std::string> OffloadObjects;
+ /// List of filenames passed in using the -mlink-builtin-bitcode. These
+ /// are bc libraries that should be linked in and internalized;
+ std::vector<std::string> BuiltinBCLibs;
+
/// The directory where temp files are stored if specified by -save-temps
std::optional<std::string> SaveTempsDir;
diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
index 7823565eb815..374fd76c8ae1 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -223,9 +223,12 @@ protected:
std::unique_ptr<llvm::LLVMContext> llvmCtx;
std::unique_ptr<llvm::Module> llvmModule;
- /// Embeds offload objects given with specified with -fembed-offload-object
+ /// Embeds offload objects specified with -fembed-offload-object
void embedOffloadObjects();
+ /// Links in BC libraries spefified with -mlink-builtin-bitcode
+ void linkBuiltinBCLibs();
+
/// Runs pass pipeline to lower HLFIR into FIR
void lowerHLFIRToFIR();
diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index f43dfd8343ec..daded9091780 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -17,6 +17,7 @@
#include "flang/Lower/LoweringOptions.h"
#include "flang/Lower/PFTDefs.h"
#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Semantics/symbol.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
@@ -126,8 +127,8 @@ public:
const Fortran::semantics::Symbol &sym,
mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) = 0;
- virtual void copyVar(mlir::Location loc, mlir::Value dst,
- mlir::Value src) = 0;
+ virtual void copyVar(mlir::Location loc, mlir::Value dst, mlir::Value src,
+ fir::FortranVariableFlagsEnum attrs) = 0;
/// For a given symbol, check if it is present in the inner-most
/// level of the symbol map.
diff --git a/flang/include/flang/Lower/BoxAnalyzer.h b/flang/include/flang/Lower/BoxAnalyzer.h
index 3b8e2455ff27..8eca7d66a71b 100644
--- a/flang/include/flang/Lower/BoxAnalyzer.h
+++ b/flang/include/flang/Lower/BoxAnalyzer.h
@@ -97,7 +97,7 @@ struct ScalarDynamicDerived : ScalarSym {
: ScalarSym{sym}, lens{std::move(lens)} {}
private:
- llvm::SmallVector<Fortran::lower::SomeExpr> lens;
+ llvm::SmallVector<Fortran::lower::SomeExpr, 1> lens;
};
struct LBoundsAndShape {
diff --git a/flang/include/flang/Lower/ConvertConstant.h b/flang/include/flang/Lower/ConvertConstant.h
index c49cbbc6e742..1bd11e9bacd6 100644
--- a/flang/include/flang/Lower/ConvertConstant.h
+++ b/flang/include/flang/Lower/ConvertConstant.h
@@ -64,7 +64,8 @@ fir::GlobalOp tryCreatingDenseGlobal(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
mlir::StringAttr linkage, bool isConst,
- const Fortran::lower::SomeExpr &initExpr);
+ const Fortran::lower::SomeExpr &initExpr,
+ cuf::DataAttributeAttr dataAttr = {});
/// Lower a StructureConstructor that must be lowered in read only data although
/// it may not be wrapped into a Constant<T> (this may be the case for derived
diff --git a/flang/include/flang/Lower/DumpEvaluateExpr.h b/flang/include/flang/Lower/DumpEvaluateExpr.h
index c67df245359e..88f53e96a81c 100644
--- a/flang/include/flang/Lower/DumpEvaluateExpr.h
+++ b/flang/include/flang/Lower/DumpEvaluateExpr.h
@@ -68,7 +68,7 @@ private:
}
template <typename... A>
void show(const std::variant<A...> &u) {
- std::visit([&](const auto &v) { show(v); }, u);
+ Fortran::common::visit([&](const auto &v) { show(v); }, u);
}
template <typename A>
void show(const std::vector<A> &x) {
diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h
index 9913f584133f..7f1b93c564b4 100644
--- a/flang/include/flang/Lower/PFTBuilder.h
+++ b/flang/include/flang/Lower/PFTBuilder.h
@@ -31,11 +31,14 @@
namespace Fortran::lower::pft {
+struct CompilerDirectiveUnit;
struct Evaluation;
-struct Program;
-struct ModuleLikeUnit;
struct FunctionLikeUnit;
+struct ModuleLikeUnit;
+struct Program;
+using ContainedUnit = std::variant<CompilerDirectiveUnit, FunctionLikeUnit>;
+using ContainedUnitList = std::list<ContainedUnit>;
using EvaluationList = std::list<Evaluation>;
/// Provide a variant like container that can hold references. It can hold
@@ -73,7 +76,7 @@ public:
}
template <typename VISITOR>
constexpr auto visit(VISITOR &&visitor) const {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{[&visitor](auto ref) { return visitor(ref.get()); }},
u);
}
@@ -347,6 +350,8 @@ struct Evaluation : EvaluationVariant {
parser::CharBlock position{};
std::optional<parser::Label> label{};
std::unique_ptr<EvaluationList> evaluationList; // nested evaluations
+ // associated compiler directives
+ llvm::SmallVector<const parser::CompilerDirective *, 1> dirs;
Evaluation *parentConstruct{nullptr}; // set for nodes below the top level
Evaluation *lexicalSuccessor{nullptr}; // set for leaf nodes, some directives
Evaluation *controlSuccessor{nullptr}; // set for some leaf nodes
@@ -489,7 +494,8 @@ struct Variable {
/// Is this variable a global?
bool isGlobal() const {
- return std::visit([](const auto &x) { return x.isGlobal(); }, var);
+ return Fortran::common::visit([](const auto &x) { return x.isGlobal(); },
+ var);
}
/// Is this a module or submodule variable?
@@ -499,7 +505,7 @@ struct Variable {
}
const Fortran::semantics::Scope *getOwningScope() const {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[](const Nominal &x) { return &x.symbol->GetUltimate().owner(); },
[](const AggregateStore &agg) { return &agg.getOwningScope(); }},
@@ -594,8 +600,8 @@ VariableList getDependentVariableList(const Fortran::semantics::Symbol &);
void dump(VariableList &, std::string s = {}); // `s` is an optional dump label
-/// Function-like units may contain evaluations (executable statements) and
-/// nested function-like units (internal procedures and function statements).
+/// Function-like units may contain evaluations (executable statements),
+/// directives, and internal (nested) function-like units.
struct FunctionLikeUnit : public ProgramUnit {
// wrapper statements for function-like syntactic structures
using FunctionStatement =
@@ -697,10 +703,10 @@ struct FunctionLikeUnit : public ProgramUnit {
std::optional<FunctionStatement> beginStmt;
FunctionStatement endStmt;
const semantics::Scope *scope;
- EvaluationList evaluationList;
LabelEvalMap labelEvaluationMap;
SymbolLabelMap assignSymbolLabelMap;
- std::list<FunctionLikeUnit> nestedFunctions;
+ ContainedUnitList containedUnitList;
+ EvaluationList evaluationList;
/// <Symbol, Evaluation> pairs for each entry point. The pair at index 0
/// is the primary entry point; remaining pairs are alternate entry points.
/// The primary entry point symbol is Null for an anonymous program.
@@ -746,7 +752,7 @@ struct ModuleLikeUnit : public ProgramUnit {
ModuleStatement beginStmt;
ModuleStatement endStmt;
- std::list<FunctionLikeUnit> nestedFunctions;
+ ContainedUnitList containedUnitList;
EvaluationList evaluationList;
};
diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h
index 64641ab4b6ca..1cc74521e22d 100644
--- a/flang/include/flang/Lower/Support/Utils.h
+++ b/flang/include/flang/Lower/Support/Utils.h
@@ -69,7 +69,8 @@ static Fortran::lower::SomeExpr ignoreEvConvert(const A &x) {
inline Fortran::lower::SomeExpr
ignoreEvConvert(const Fortran::evaluate::Expr<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Integer, 8>> &x) {
- return std::visit([](const auto &v) { return ignoreEvConvert(v); }, x.u);
+ return Fortran::common::visit(
+ [](const auto &v) { return ignoreEvConvert(v); }, x.u);
}
/// Zip two containers of the same size together and flatten the pairs. `flatZip
@@ -119,7 +120,8 @@ public:
return 0u;
}
static unsigned getHashValue(const Fortran::evaluate::Subscript &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
static unsigned getHashValue(const Fortran::evaluate::Triplet &x) {
return getHashValue(x.lower()) - getHashValue(x.upper()) * 5u -
@@ -154,7 +156,8 @@ public:
return getHashValue(x.GetComponent()) * 13u;
}
static unsigned getHashValue(const Fortran::evaluate::DataRef &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
static unsigned getHashValue(const Fortran::evaluate::ComplexPart &x) {
return getHashValue(x.complex()) - static_cast<unsigned>(x.part());
@@ -247,8 +250,9 @@ public:
return getHashValue(sym.get());
}
static unsigned getHashValue(const Fortran::evaluate::Substring &x) {
- return 61u * std::visit([&](const auto &p) { return getHashValue(p); },
- x.parent()) -
+ return 61u *
+ Fortran::common::visit(
+ [&](const auto &p) { return getHashValue(p); }, x.parent()) -
getHashValue(x.lower()) - (getHashValue(x.lower()) + 1u);
}
static unsigned
@@ -270,7 +274,8 @@ public:
}
static unsigned
getHashValue(const Fortran::evaluate::ProcedureDesignator &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
static unsigned getHashValue(const Fortran::evaluate::ProcedureRef &x) {
unsigned args = 13u;
@@ -321,15 +326,18 @@ public:
}
template <typename A>
static unsigned getHashValue(const Fortran::evaluate::Expr<A> &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
static unsigned getHashValue(
const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
template <typename A>
static unsigned getHashValue(const Fortran::evaluate::Designator<A> &x) {
- return std::visit([&](const auto &v) { return getHashValue(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return getHashValue(v); }, x.u);
}
template <int BITS>
static unsigned
@@ -378,7 +386,7 @@ public:
}
static bool isEqual(const Fortran::evaluate::Subscript &x,
const Fortran::evaluate::Subscript &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
static bool isEqual(const Fortran::evaluate::Triplet &x,
@@ -411,7 +419,7 @@ public:
}
static bool isEqual(const Fortran::evaluate::DataRef &x,
const Fortran::evaluate::DataRef &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
static bool isEqual(const Fortran::evaluate::ComplexPart &x,
@@ -499,10 +507,10 @@ public:
}
static bool isEqual(const Fortran::evaluate::Substring &x,
const Fortran::evaluate::Substring &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &p, const auto &q) { return isEqual(p, q); },
x.parent(), y.parent()) &&
- isEqual(x.lower(), y.lower()) && isEqual(x.lower(), y.lower());
+ isEqual(x.lower(), y.lower()) && isEqual(x.upper(), y.upper());
}
static bool isEqual(const Fortran::evaluate::StaticDataObject::Pointer &x,
const Fortran::evaluate::StaticDataObject::Pointer &y) {
@@ -529,7 +537,7 @@ public:
}
static bool isEqual(const Fortran::evaluate::ProcedureDesignator &x,
const Fortran::evaluate::ProcedureDesignator &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
static bool isEqual(const Fortran::evaluate::ProcedureRef &x,
@@ -591,19 +599,19 @@ public:
template <typename A>
static bool isEqual(const Fortran::evaluate::Expr<A> &x,
const Fortran::evaluate::Expr<A> &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
static bool
isEqual(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &x,
const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
template <typename A>
static bool isEqual(const Fortran::evaluate::Designator<A> &x,
const Fortran::evaluate::Designator<A> &y) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &v, const auto &w) { return isEqual(v, w); }, x.u, y.u);
}
template <int BITS>
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 8ef5d59b92f0..ec1fb411ff0e 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -204,6 +204,8 @@ struct IntrinsicLibrary {
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCAssociatedCPtr(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genErfcScaled(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args);
void genCFPointer(llvm::ArrayRef<fir::ExtendedValue>);
void genCFProcPointer(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCFunLoc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -328,6 +330,8 @@ struct IntrinsicLibrary {
void genRandomNumber(llvm::ArrayRef<fir::ExtendedValue>);
void genRandomSeed(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genReduce(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ fir::ExtendedValue genReduceDim(mlir::Type,
+ llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genRepeat(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genReshape(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genRRSpacing(mlir::Type resultType,
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Assign.h b/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
index 14d338b7093e..52a6a1d8e5a0 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
@@ -56,18 +56,12 @@ void genAssignExplicitLengthCharacter(fir::FirOpBuilder &builder,
void genAssignTemporary(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value destBox, mlir::Value sourceBox);
-/// Generate runtime call to CopyOutAssign to assign \p sourceBox to
-/// \p destBox. This call implements the copy-out of a temporary
-/// (\p sourceBox) to the actual argument (\p destBox) passed to a procedure,
-/// after the procedure returns to the caller.
-/// If \p skipToInit is false, then \p destBox will be initialized before
-/// the assignment, otherwise, it is assumed to be already initialized.
-/// The runtime makes sure that there is no reallocation of the top-level
-/// entity represented by \p destBox. If reallocation is required
-/// for the components of \p destBox, then it is done without finalization.
+/// Generate runtime call to "CopyInAssign" runtime API.
+void genCopyInAssign(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value tempBoxAddr, mlir::Value varBoxAddr);
+/// Generate runtime call to "CopyOutAssign" runtime API.
void genCopyOutAssign(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value destBox, mlir::Value sourceBox,
- bool skipToInit);
+ mlir::Value varBoxAddr, mlir::Value tempBoxAddr);
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_ASSIGN_H
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Inquiry.h b/flang/include/flang/Optimizer/Builder/Runtime/Inquiry.h
index 132592a0197f..3707273e0cbd 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Inquiry.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Inquiry.h
@@ -20,18 +20,26 @@ class FirOpBuilder;
namespace fir::runtime {
-/// Generate call to general `LboundDim` runtime routine. Calls to LBOUND
-/// without a DIM argument get transformed into descriptor inquiries so they're
-/// not handled in the runtime.
+/// Generate call to `LboundDim` runtime routine.
mlir::Value genLboundDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value array, mlir::Value dim);
+/// Generate call to Lbound` runtime routine.
+void genLbound(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultAddr, mlir::Value arrayt, mlir::Value kind);
+
/// Generate call to general `Ubound` runtime routine. Calls to UBOUND
/// with a DIM argument get transformed into an expression equivalent to
/// SIZE() + LBOUND() - 1, so they don't have an intrinsic in the runtime.
void genUbound(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value array, mlir::Value kind);
+/// Generate call to `Shape` runtime routine.
+/// First argument is a raw pointer to the result array storage that
+/// must be allocated by the caller.
+void genShape(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultAddr, mlir::Value arrayt, mlir::Value kind);
+
/// Generate call to `Size` runtime routine. This routine is a specialized
/// version when the DIM argument is not specified by the user.
mlir::Value genSize(fir::FirOpBuilder &builder, mlir::Location loc,
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h b/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h
index 558358257b51..6857650ce52b 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Numeric.h
@@ -18,6 +18,10 @@ class FirOpBuilder;
namespace fir::runtime {
+/// Generate call to ErfcScaled intrinsic runtime routine.
+mlir::Value genErfcScaled(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value x);
+
/// Generate call to Exponent intrinsic runtime routine.
mlir::Value genExponent(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type resultType, mlir::Value x);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
index 575746374fcc..845ba385918d 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
@@ -22,6 +22,7 @@
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Runtime/reduce.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "llvm/ADT/SmallVector.h"
@@ -52,6 +53,46 @@ namespace fir::runtime {
using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *);
using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *);
+#define REDUCTION_REF_OPERATION_MODEL(T) \
+ template <> \
+ constexpr TypeBuilderFunc \
+ getModel<Fortran::runtime::ReferenceReductionOperation<T>>() { \
+ return [](mlir::MLIRContext *context) -> mlir::Type { \
+ TypeBuilderFunc f{getModel<T>()}; \
+ auto refTy = fir::ReferenceType::get(f(context)); \
+ return mlir::FunctionType::get(context, {refTy, refTy}, refTy); \
+ }; \
+ }
+
+#define REDUCTION_VALUE_OPERATION_MODEL(T) \
+ template <> \
+ constexpr TypeBuilderFunc \
+ getModel<Fortran::runtime::ValueReductionOperation<T>>() { \
+ return [](mlir::MLIRContext *context) -> mlir::Type { \
+ TypeBuilderFunc f{getModel<T>()}; \
+ auto refTy = fir::ReferenceType::get(f(context)); \
+ return mlir::FunctionType::get(context, {f(context), f(context)}, \
+ refTy); \
+ }; \
+ }
+
+#define REDUCTION_CHAR_OPERATION_MODEL(T) \
+ template <> \
+ constexpr TypeBuilderFunc \
+ getModel<Fortran::runtime::ReductionCharOperation<T>>() { \
+ return [](mlir::MLIRContext *context) -> mlir::Type { \
+ TypeBuilderFunc f{getModel<T>()}; \
+ auto voidTy = fir::LLVMPointerType::get( \
+ context, mlir::IntegerType::get(context, 8)); \
+ auto size_tTy = \
+ mlir::IntegerType::get(context, 8 * sizeof(std::size_t)); \
+ auto refTy = fir::ReferenceType::get(f(context)); \
+ return mlir::FunctionType::get( \
+ context, {refTy, size_tTy, refTy, refTy, size_tTy, size_tTy}, \
+ voidTy); \
+ }; \
+ }
+
//===----------------------------------------------------------------------===//
// Type builder models
//===----------------------------------------------------------------------===//
@@ -75,7 +116,6 @@ constexpr TypeBuilderFunc getModel<unsigned int>() {
return mlir::IntegerType::get(context, 8 * sizeof(unsigned int));
};
}
-
template <>
constexpr TypeBuilderFunc getModel<short int>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
@@ -83,6 +123,17 @@ constexpr TypeBuilderFunc getModel<short int>() {
};
}
template <>
+constexpr TypeBuilderFunc getModel<short int *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<short int>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<const short int *>() {
+ return getModel<short int *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<int>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 8 * sizeof(int));
@@ -96,6 +147,17 @@ constexpr TypeBuilderFunc getModel<int &>() {
};
}
template <>
+constexpr TypeBuilderFunc getModel<int *>() {
+ return getModel<int &>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<const int *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<int>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
constexpr TypeBuilderFunc getModel<char *>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return fir::ReferenceType::get(mlir::IntegerType::get(context, 8));
@@ -130,6 +192,43 @@ constexpr TypeBuilderFunc getModel<signed char>() {
};
}
template <>
+constexpr TypeBuilderFunc getModel<signed char *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<signed char>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<const signed char *>() {
+ return getModel<signed char *>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<char16_t>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ return mlir::IntegerType::get(context, 8 * sizeof(char16_t));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<char16_t *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<char16_t>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<char32_t>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ return mlir::IntegerType::get(context, 8 * sizeof(char32_t));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<char32_t *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<char32_t>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
constexpr TypeBuilderFunc getModel<unsigned char>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 8 * sizeof(unsigned char));
@@ -175,6 +274,10 @@ constexpr TypeBuilderFunc getModel<long *>() {
return getModel<long &>();
}
template <>
+constexpr TypeBuilderFunc getModel<const long *>() {
+ return getModel<long *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<long long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 8 * sizeof(long long));
@@ -199,6 +302,10 @@ constexpr TypeBuilderFunc getModel<long long *>() {
return getModel<long long &>();
}
template <>
+constexpr TypeBuilderFunc getModel<const long long *>() {
+ return getModel<long long *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<unsigned long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 8 * sizeof(unsigned long));
@@ -228,6 +335,27 @@ constexpr TypeBuilderFunc getModel<double *>() {
return getModel<double &>();
}
template <>
+constexpr TypeBuilderFunc getModel<const double *>() {
+ return getModel<double *>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<long double>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ return mlir::FloatType::getF80(context);
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<long double *>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ TypeBuilderFunc f{getModel<long double>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<const long double *>() {
+ return getModel<long double *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<float>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::FloatType::getF32(context);
@@ -245,6 +373,10 @@ constexpr TypeBuilderFunc getModel<float *>() {
return getModel<float &>();
}
template <>
+constexpr TypeBuilderFunc getModel<const float *>() {
+ return getModel<float *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<bool>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 1);
@@ -258,20 +390,48 @@ constexpr TypeBuilderFunc getModel<bool &>() {
};
}
template <>
+constexpr TypeBuilderFunc getModel<std::complex<float>>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ return mlir::ComplexType::get(mlir::FloatType::getF32(context));
+ };
+}
+template <>
constexpr TypeBuilderFunc getModel<std::complex<float> &>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
- auto ty = mlir::ComplexType::get(mlir::FloatType::getF32(context));
- return fir::ReferenceType::get(ty);
+ TypeBuilderFunc f{getModel<std::complex<float>>()};
+ return fir::ReferenceType::get(f(context));
+ };
+}
+template <>
+constexpr TypeBuilderFunc getModel<std::complex<float> *>() {
+ return getModel<std::complex<float> &>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<const std::complex<float> *>() {
+ return getModel<std::complex<float> *>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<std::complex<double>>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ return mlir::ComplexType::get(mlir::FloatType::getF64(context));
};
}
template <>
constexpr TypeBuilderFunc getModel<std::complex<double> &>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
- auto ty = mlir::ComplexType::get(mlir::FloatType::getF64(context));
- return fir::ReferenceType::get(ty);
+ TypeBuilderFunc f{getModel<std::complex<double>>()};
+ return fir::ReferenceType::get(f(context));
};
}
template <>
+constexpr TypeBuilderFunc getModel<std::complex<double> *>() {
+ return getModel<std::complex<double> &>();
+}
+template <>
+constexpr TypeBuilderFunc getModel<const std::complex<double> *>() {
+ return getModel<std::complex<double> *>();
+}
+template <>
constexpr TypeBuilderFunc getModel<c_float_complex_t>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return fir::ComplexType::get(context, sizeof(float));
@@ -332,6 +492,43 @@ constexpr TypeBuilderFunc getModel<void>() {
};
}
+REDUCTION_REF_OPERATION_MODEL(std::int8_t)
+REDUCTION_VALUE_OPERATION_MODEL(std::int8_t)
+REDUCTION_REF_OPERATION_MODEL(std::int16_t)
+REDUCTION_VALUE_OPERATION_MODEL(std::int16_t)
+REDUCTION_REF_OPERATION_MODEL(std::int32_t)
+REDUCTION_VALUE_OPERATION_MODEL(std::int32_t)
+REDUCTION_REF_OPERATION_MODEL(std::int64_t)
+REDUCTION_VALUE_OPERATION_MODEL(std::int64_t)
+REDUCTION_REF_OPERATION_MODEL(Fortran::common::int128_t)
+REDUCTION_VALUE_OPERATION_MODEL(Fortran::common::int128_t)
+
+REDUCTION_REF_OPERATION_MODEL(float)
+REDUCTION_VALUE_OPERATION_MODEL(float)
+REDUCTION_REF_OPERATION_MODEL(double)
+REDUCTION_VALUE_OPERATION_MODEL(double)
+REDUCTION_REF_OPERATION_MODEL(long double)
+REDUCTION_VALUE_OPERATION_MODEL(long double)
+
+REDUCTION_REF_OPERATION_MODEL(std::complex<float>)
+REDUCTION_VALUE_OPERATION_MODEL(std::complex<float>)
+REDUCTION_REF_OPERATION_MODEL(std::complex<double>)
+REDUCTION_VALUE_OPERATION_MODEL(std::complex<double>)
+
+REDUCTION_CHAR_OPERATION_MODEL(char)
+REDUCTION_CHAR_OPERATION_MODEL(char16_t)
+REDUCTION_CHAR_OPERATION_MODEL(char32_t)
+
+template <>
+constexpr TypeBuilderFunc
+getModel<Fortran::runtime::ReductionDerivedTypeOperation>() {
+ return [](mlir::MLIRContext *context) -> mlir::Type {
+ auto voidTy =
+ fir::LLVMPointerType::get(context, mlir::IntegerType::get(context, 8));
+ return mlir::FunctionType::get(context, {voidTy, voidTy, voidTy}, voidTy);
+ };
+}
+
template <typename...>
struct RuntimeTableKey;
template <typename RT, typename... ATs>
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h
index 667ea9081a89..2a40cddc0cc2 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Reduction.h
@@ -224,6 +224,29 @@ void genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
mlir::Value maskBox);
+/// Generate call to `Reduce` intrinsic runtime routine. This is the version
+/// that does not take a dim argument and store the result in the provided
+/// result value. This is used for COMPLEX, CHARACTER and DERIVED TYPES.
+void genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value arrayBox, mlir::Value operation, mlir::Value maskBox,
+ mlir::Value identity, mlir::Value ordered, mlir::Value resultBox,
+ bool argByRef);
+
+/// Generate call to `Reduce` intrinsic runtime routine. This is the version
+/// that does not take a dim argument and return a scalare result. This is used
+/// for REAL, INTEGER and LOGICAL TYPES.
+mlir::Value genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value arrayBox, mlir::Value operation,
+ mlir::Value maskBox, mlir::Value identity,
+ mlir::Value ordered, bool argByRef);
+
+/// Generate call to `Reduce` intrinsic runtime routine. This is the version
+/// that takes arrays of any rank with a dim argument specified.
+void genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value arrayBox, mlir::Value operation, mlir::Value dim,
+ mlir::Value maskBox, mlir::Value identity,
+ mlir::Value ordered, mlir::Value resultBox, bool argByRef);
+
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H
diff --git a/flang/lib/Optimizer/CodeGen/DescriptorModel.h b/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h
index ed35caef9301..ff0cf29e8073 100644
--- a/flang/lib/Optimizer/CodeGen/DescriptorModel.h
+++ b/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h
@@ -35,73 +35,73 @@ using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *);
/// Get the LLVM IR dialect model for building a particular C++ type, `T`.
template <typename T>
-TypeBuilderFunc getModel();
+static TypeBuilderFunc getModel();
template <>
-TypeBuilderFunc getModel<void *>() {
+constexpr TypeBuilderFunc getModel<void *>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::LLVM::LLVMPointerType::get(context);
};
}
template <>
-TypeBuilderFunc getModel<unsigned>() {
+constexpr TypeBuilderFunc getModel<unsigned>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(unsigned) * 8);
};
}
template <>
-TypeBuilderFunc getModel<int>() {
+constexpr TypeBuilderFunc getModel<int>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(int) * 8);
};
}
template <>
-TypeBuilderFunc getModel<unsigned long>() {
+constexpr TypeBuilderFunc getModel<unsigned long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(unsigned long) * 8);
};
}
template <>
-TypeBuilderFunc getModel<unsigned long long>() {
+constexpr TypeBuilderFunc getModel<unsigned long long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(unsigned long long) * 8);
};
}
template <>
-TypeBuilderFunc getModel<long long>() {
+constexpr TypeBuilderFunc getModel<long long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(long long) * 8);
};
}
template <>
-TypeBuilderFunc getModel<Fortran::ISO::CFI_rank_t>() {
+constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_rank_t>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context,
sizeof(Fortran::ISO::CFI_rank_t) * 8);
};
}
template <>
-TypeBuilderFunc getModel<Fortran::ISO::CFI_type_t>() {
+constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_type_t>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context,
sizeof(Fortran::ISO::CFI_type_t) * 8);
};
}
template <>
-TypeBuilderFunc getModel<long>() {
+constexpr TypeBuilderFunc getModel<long>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, sizeof(long) * 8);
};
}
template <>
-TypeBuilderFunc getModel<Fortran::ISO::CFI_dim_t>() {
+constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_dim_t>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
auto indexTy = getModel<Fortran::ISO::CFI_index_t>()(context);
return mlir::LLVM::LLVMArrayType::get(indexTy, 3);
};
}
template <>
-TypeBuilderFunc
+constexpr TypeBuilderFunc
getModel<Fortran::ISO::cfi_internal::FlexibleArray<Fortran::ISO::CFI_dim_t>>() {
return getModel<Fortran::ISO::CFI_dim_t>();
}
diff --git a/flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h b/flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h
index 211acdc8a38e..ac095664f618 100644
--- a/flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h
+++ b/flang/include/flang/Optimizer/CodeGen/FIROpPatterns.h
@@ -51,7 +51,9 @@ protected:
/// appropriate reified structures.
mlir::Value integerCast(mlir::Location loc,
mlir::ConversionPatternRewriter &rewriter,
- mlir::Type ty, mlir::Value val) const;
+ mlir::Type ty, mlir::Value val,
+ bool fold = false) const;
+
struct TypePair {
mlir::Type fir;
mlir::Type llvm;
@@ -144,9 +146,12 @@ protected:
// Find the Block in which the alloca should be inserted.
// The order to recursively find the proper block:
// 1. An OpenMP Op that will be outlined.
- // 2. A LLVMFuncOp
- // 3. The first ancestor that is an OpenMP Op or a LLVMFuncOp
- mlir::Block *getBlockForAllocaInsert(mlir::Operation *op) const;
+ // 2. An OpenMP or OpenACC Op with one or more regions holding executable
+ // code.
+ // 3. A LLVMFuncOp
+ // 4. The first ancestor that is one of the above.
+ mlir::Block *getBlockForAllocaInsert(mlir::Operation *op,
+ mlir::Region *parentRegion) const;
// Generate an alloca of size 1 for an object of type \p llvmObjectTy in the
// allocation address space provided for the architecture in the DataLayout
diff --git a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td
index 37b8da018195..b6e08d32a6ac 100644
--- a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td
@@ -17,6 +17,7 @@
include "flang/Optimizer/Dialect/CUF/CUFDialect.td"
include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.td"
include "flang/Optimizer/Dialect/FIRTypes.td"
+include "flang/Optimizer/Dialect/FIRAttr.td"
include "mlir/Interfaces/LoopLikeInterface.td"
include "mlir/IR/BuiltinAttributes.td"
@@ -249,7 +250,9 @@ def cuf_KernelOp : cuf_Op<"kernel", [AttrSizedOperandSegments,
Variadic<Index>:$lowerbound,
Variadic<Index>:$upperbound,
Variadic<Index>:$step,
- OptionalAttr<I64Attr>:$n
+ OptionalAttr<I64Attr>:$n,
+ Variadic<AnyType>:$reduceOperands,
+ OptionalAttr<ArrayAttr>:$reduceAttrs
);
let regions = (region AnyRegion:$region);
@@ -258,11 +261,29 @@ def cuf_KernelOp : cuf_Op<"kernel", [AttrSizedOperandSegments,
`<` `<` `<` custom<CUFKernelValues>($grid, type($grid)) `,`
custom<CUFKernelValues>($block, type($block))
( `,` `stream` `=` $stream^ )? `>` `>` `>`
+ ( `reduce` `(` $reduceOperands^ `:` type($reduceOperands) `:` $reduceAttrs `)` )?
custom<CUFKernelLoopControl>($region, $lowerbound, type($lowerbound),
$upperbound, type($upperbound), $step, type($step))
attr-dict
}];
+ let extraClassDeclaration = [{
+ /// Get Number of variadic operands
+ unsigned getNumOperands(unsigned idx) {
+ auto segments = (*this)->getAttrOfType<mlir::DenseI32ArrayAttr>(
+ getOperandSegmentSizeAttr());
+ return static_cast<unsigned>(segments[idx]);
+ }
+ // Get Number of reduction operands
+ unsigned getNumReduceOperands() {
+ return getNumOperands(7);
+ }
+ /// Does the operation hold operands for reduction variables
+ bool hasReduceOperands() {
+ return getNumReduceOperands() > 0;
+ }
+ }];
+
let hasVerifier = 1;
}
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.h b/flang/include/flang/Optimizer/Dialect/FIROps.h
index 9f07364ddb62..a21f8bbe1768 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.h
@@ -16,6 +16,7 @@
#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Interfaces/LoopLikeInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index e7da3af5485c..baf095263479 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2160,7 +2160,8 @@ def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
Variadic<AnyType>:$initArgs,
OptionalAttr<UnitAttr>:$unordered,
OptionalAttr<UnitAttr>:$finalValue,
- OptionalAttr<ArrayAttr>:$reduceAttrs
+ OptionalAttr<ArrayAttr>:$reduceAttrs,
+ OptionalAttr<LoopAnnotationAttr>:$loopAnnotation
);
let results = (outs Variadic<AnyType>:$results);
let regions = (region SizedRegion<1>:$region);
diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
index 47b80cca5d64..50e18792a167 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
+++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
@@ -148,6 +148,18 @@ static constexpr llvm::StringRef getAdaptToByRefAttrName() {
return "adapt.valuebyref";
}
+static constexpr llvm::StringRef getFuncPureAttrName() {
+ return "fir.func_pure";
+}
+
+static constexpr llvm::StringRef getFuncElementalAttrName() {
+ return "fir.func_elemental";
+}
+
+static constexpr llvm::StringRef getFuncRecursiveAttrName() {
+ return "fir.func_recursive";
+}
+
// Attribute for an alloca that is a trivial adaptor for converting a value to
// pass-by-ref semantics for a VALUE parameter. The optimizer may be able to
// eliminate these.
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 0aeb29a93d71..3498a329ced3 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -41,6 +41,9 @@ class BaseBoxType : public mlir::Type {
public:
using mlir::Type::Type;
+ /// Box attributes.
+ enum class Attribute { None, Allocatable, Pointer };
+
/// Returns the element type of this box type.
mlir::Type getEleTy() const;
@@ -55,6 +58,9 @@ public:
BaseBoxType getBoxTypeWithNewShape(mlir::Type shapeMold) const;
BaseBoxType getBoxTypeWithNewShape(int rank) const;
+ /// Return the same type, except for the attribute (fir.heap/fir.ptr).
+ BaseBoxType getBoxTypeWithNewAttr(Attribute attr) const;
+
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(mlir::Type type);
};
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index b537d9e11ef8..e9915e899c2c 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -1091,9 +1091,12 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]>]> {
potentially absent variable storage. The second result indicates if a copy
was made.
+ A descriptor address must be provided for the temporary. This descriptor will
+ be set if a temporary copy was made.
+
This operation is meant to be used in combination with the hlfir.copy_out
- operation that deletes the temporary if it was created and copies the data
- back if needed.
+ operation that takes the address of the descriptor for the temporary, deletes
+ the temporary if it was created, and copies the data back if needed.
This operation allows passing non contiguous arrays to contiguous dummy
arguments, which is possible in Fortran procedure references.
@@ -1103,17 +1106,19 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]>]> {
}];
let arguments = (ins Arg<fir_BaseBoxType, "", [MemRead]>:$var,
- Optional<I1>:$var_is_present);
+ Arg<AnyReferenceLike, "", [MemWrite]>:$tempBox,
+ Optional<I1>:$var_is_present);
let results = (outs fir_BaseBoxType, I1);
let assemblyFormat = [{
- $var (`handle_optional` $var_is_present^)?
+ $var `to` $tempBox (`handle_optional` $var_is_present^)?
attr-dict `:` functional-type(operands, results)
}];
let builders = [
- OpBuilder<(ins "mlir::Value":$var, "mlir::Value":$var_is_present)>
+ OpBuilder<(ins "mlir::Value":$var, "mlir::Value":$temp_box,
+ "mlir::Value":$var_is_present)>
];
let extraClassDeclaration = [{
@@ -1138,9 +1143,10 @@ def hlfir_CopyOutOp : hlfir_Op<"copy_out", [MemoryEffects<[MemFree]>]> {
the temporary.
The copy back is done if $var is provided and $was_copied is true.
The deallocation of $temp is done if $was_copied is true.
+ $temp must be the descriptor address that was provided to hlfir.copy_in.
}];
- let arguments = (ins Arg<fir_BaseBoxType, "", [MemRead]>:$temp,
+ let arguments = (ins Arg<AnyReferenceLike, "", [MemRead]>:$temp,
I1:$was_copied,
Arg<Optional<fir_BaseBoxType>, "", [MemWrite]>:$var);
diff --git a/flang/include/flang/Optimizer/Support/Matcher.h b/flang/include/flang/Optimizer/Support/Matcher.h
index da1d7c21f42c..44672d3c0a07 100644
--- a/flang/include/flang/Optimizer/Support/Matcher.h
+++ b/flang/include/flang/Optimizer/Support/Matcher.h
@@ -13,6 +13,7 @@
#ifndef FORTRAN_OPTIMIZER_SUPPORT_MATCHER_H
#define FORTRAN_OPTIMIZER_SUPPORT_MATCHER_H
+#include "flang/Common/idioms.h"
#include <variant>
// Boilerplate CRTP class for a simplified type-casing syntactic sugar. This
@@ -23,10 +24,10 @@ template<class... Ts> struct matches : Ts... { using Ts::operator()...; };
template<class... Ts> matches(Ts...) -> matches<Ts...>;
template<typename N> struct matcher {
template<typename... Ts> auto match(Ts... ts) {
- return std::visit(matches{ts...}, static_cast<N*>(this)->matchee());
+ return Fortran::common::visit(matches{ts...}, static_cast<N*>(this)->matchee());
}
template<typename... Ts> auto match(Ts... ts) const {
- return std::visit(matches{ts...}, static_cast<N const*>(this)->matchee());
+ return Fortran::common::visit(matches{ts...}, static_cast<N const*>(this)->matchee());
}
};
// clang-format on
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index 4e978e6c9cde..df709645c01b 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -49,12 +49,16 @@ namespace fir {
#define GEN_PASS_DECL_OPENACCDATAOPERANDCONVERSION
#define GEN_PASS_DECL_ADDDEBUGINFO
#define GEN_PASS_DECL_STACKARRAYS
+#define GEN_PASS_DECL_STACKRECLAIM
#define GEN_PASS_DECL_LOOPVERSIONING
#define GEN_PASS_DECL_ADDALIASTAGS
#define GEN_PASS_DECL_OMPMAPINFOFINALIZATIONPASS
#define GEN_PASS_DECL_OMPMARKDECLARETARGETPASS
#define GEN_PASS_DECL_OMPFUNCTIONFILTERING
#define GEN_PASS_DECL_VSCALEATTR
+#define GEN_PASS_DECL_FUNCTIONATTR
+#define GEN_PASS_DECL_CONSTANTARGUMENTGLOBALISATIONOPT
+
#include "flang/Optimizer/Transforms/Passes.h.inc"
std::unique_ptr<mlir::Pass> createAffineDemotionPass();
@@ -75,17 +79,6 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass();
std::unique_ptr<mlir::Pass>
createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr);
-struct FunctionAttrTypes {
- mlir::LLVM::framePointerKind::FramePointerKind framePointerKind =
- mlir::LLVM::framePointerKind::FramePointerKind::None;
-};
-
-std::unique_ptr<mlir::Pass> createFunctionAttrPass();
-std::unique_ptr<mlir::Pass>
-createFunctionAttrPass(FunctionAttrTypes &functionAttr, bool noInfsFPMath,
- bool noNaNsFPMath, bool approxFuncFPMath,
- bool noSignedZerosFPMath, bool unsafeFPMath);
-
void populateCfgConversionRewrites(mlir::RewritePatternSet &patterns,
bool forceLoopToExecuteOnce = false,
bool setNSW = false);
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 4e281e2846c5..b3ed9acad36d 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -251,6 +251,15 @@ def MemoryAllocationOpt : Pass<"memory-allocation-opt", "mlir::func::FuncOp"> {
];
}
+// This needs to be a "mlir::ModuleOp" pass, because it inserts global constants
+def ConstantArgumentGlobalisationOpt : Pass<"constant-argument-globalisation-opt", "mlir::ModuleOp"> {
+ let summary = "Convert constant function arguments to global constants.";
+ let description = [{
+ Convert scalar literals of function arguments to global constants.
+ }];
+ let dependentDialects = [ "fir::FIROpsDialect" ];
+}
+
def StackArrays : Pass<"stack-arrays", "mlir::ModuleOp"> {
let summary = "Move local array allocations from heap memory into stack memory";
let description = [{
@@ -260,6 +269,15 @@ def StackArrays : Pass<"stack-arrays", "mlir::ModuleOp"> {
let dependentDialects = [ "fir::FIROpsDialect" ];
}
+def StackReclaim : Pass<"stack-reclaim"> {
+ let summary = "Insert stacksave/stackrestore in region with allocas";
+ let description = [{
+ Insert stacksave/stackrestore in loop region to reclaim alloca done in its
+ scope.
+ }];
+ let dependentDialects = [ "mlir::LLVM::LLVMDialect" ];
+}
+
def AddAliasTags : Pass<"fir-add-alias-tags", "mlir::ModuleOp"> {
let summary = "Add tbaa tags to operations that implement FirAliasAnalysisOpInterface";
let description = [{
@@ -394,7 +412,6 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> {
"bool", /*default=*/"false",
"Set the unsafe-fp-math attribute on functions in the module.">,
];
- let constructor = "::fir::createFunctionAttrPass()";
}
def AssumedRankOpConversion : Pass<"fir-assumed-rank-op", "mlir::ModuleOp"> {
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 4232e85a6e59..37c3370b48a0 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -201,11 +201,12 @@ public:
NODE(parser, CommonStmt)
NODE(CommonStmt, Block)
NODE(parser, CompilerDirective)
+ NODE(CompilerDirective, AssumeAligned)
NODE(CompilerDirective, IgnoreTKR)
NODE(CompilerDirective, LoopCount)
- NODE(CompilerDirective, AssumeAligned)
NODE(CompilerDirective, NameValue)
NODE(CompilerDirective, Unrecognized)
+ NODE(CompilerDirective, VectorAlways)
NODE(parser, ComplexLiteralConstant)
NODE(parser, ComplexPart)
NODE(parser, ComponentArraySpec)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 12e35075d2a6..548fcc81984b 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -1296,10 +1296,13 @@ struct AcImpliedDo {
};
// R808 language-binding-spec ->
-// BIND ( C [, NAME = scalar-default-char-constant-expr] )
+// BIND ( C [, NAME = scalar-default-char-constant-expr ]
+// [, CDEFINED ] )
// R1528 proc-language-binding-spec -> language-binding-spec
-WRAPPER_CLASS(
- LanguageBindingSpec, std::optional<ScalarDefaultCharConstantExpr>);
+struct LanguageBindingSpec {
+ TUPLE_CLASS_BOILERPLATE(LanguageBindingSpec);
+ std::tuple<std::optional<ScalarDefaultCharConstantExpr>, bool> t;
+};
// R852 named-constant-def -> named-constant = constant-expr
struct NamedConstantDef {
@@ -3334,6 +3337,7 @@ struct CompilerDirective {
TUPLE_CLASS_BOILERPLATE(AssumeAligned);
std::tuple<common::Indirection<Designator>, uint64_t> t;
};
+ EMPTY_CLASS(VectorAlways);
struct NameValue {
TUPLE_CLASS_BOILERPLATE(NameValue);
std::tuple<Name, std::optional<std::uint64_t>> t;
@@ -3341,7 +3345,7 @@ struct CompilerDirective {
EMPTY_CLASS(Unrecognized);
CharBlock source;
std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
- std::list<NameValue>, Unrecognized>
+ VectorAlways, std::list<NameValue>, Unrecognized>
u;
};
diff --git a/flang/include/flang/Parser/preprocessor.h b/flang/include/flang/Parser/preprocessor.h
index c3076435be5f..57690dd226f6 100644
--- a/flang/include/flang/Parser/preprocessor.h
+++ b/flang/include/flang/Parser/preprocessor.h
@@ -82,6 +82,7 @@ public:
bool IsNameDefined(const CharBlock &);
bool IsFunctionLikeDefinition(const CharBlock &);
bool AnyDefinitions() const { return !definitions_.empty(); }
+ bool InConditional() const { return !ifStack_.empty(); }
// When called with partialFunctionLikeMacro not null, MacroReplacement()
// and ReplaceMacros() handle an unclosed function-like macro reference
diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h
index 73d500f32831..42c5b3de2cbe 100644
--- a/flang/include/flang/Parser/provenance.h
+++ b/flang/include/flang/Parser/provenance.h
@@ -257,6 +257,10 @@ public:
provenanceMap_.Put(pm);
}
+ void MarkPossibleFixedFormContinuation() {
+ possibleFixedFormContinuations_.push_back(BufferedBytes());
+ }
+
std::size_t BufferedBytes() const;
void Marshal(AllCookedSources &); // marshals text into one contiguous block
void CompileProvenanceRangeToOffsetMappings(AllSources &);
@@ -269,6 +273,7 @@ private:
std::string data_; // all of it, prescanned and preprocessed
OffsetToProvenanceMappings provenanceMap_;
ProvenanceRangeToOffsetMappings invertedMap_;
+ std::list<std::size_t> possibleFixedFormContinuations_;
};
class AllCookedSources {
diff --git a/flang/include/flang/Parser/token-sequence.h b/flang/include/flang/Parser/token-sequence.h
index 849240d8ec62..1f82a3c1a203 100644
--- a/flang/include/flang/Parser/token-sequence.h
+++ b/flang/include/flang/Parser/token-sequence.h
@@ -124,7 +124,8 @@ public:
TokenSequence &RemoveRedundantBlanks(std::size_t firstChar = 0);
TokenSequence &ClipComment(const Prescanner &, bool skipFirst = false);
const TokenSequence &CheckBadFortranCharacters(
- Messages &, const Prescanner &) const;
+ Messages &, const Prescanner &, bool allowAmpersand) const;
+ bool BadlyNestedParentheses() const;
const TokenSequence &CheckBadParentheses(Messages &) const;
void Emit(CookedSource &) const;
llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
diff --git a/flang/include/flang/Runtime/assign.h b/flang/include/flang/Runtime/assign.h
index b19c02f44c73..a1cc9eaf4355 100644
--- a/flang/include/flang/Runtime/assign.h
+++ b/flang/include/flang/Runtime/assign.h
@@ -36,8 +36,16 @@ void RTDECL(Assign)(Descriptor &to, const Descriptor &from,
// reallocation.
void RTDECL(AssignTemporary)(Descriptor &to, const Descriptor &from,
const char *sourceFile = nullptr, int sourceLine = 0);
-void RTDECL(CopyOutAssign)(Descriptor &to, const Descriptor &from,
- bool skipToInit, const char *sourceFile = nullptr, int sourceLine = 0);
+
+// Establish "temp" descriptor as an allocatable descriptor with the same type,
+// rank, and length parameters as "var" and copy "var" to it using
+// AssignTemporary.
+void RTDECL(CopyInAssign)(Descriptor &temp, const Descriptor &var,
+ const char *sourceFile = nullptr, int sourceLine = 0);
+// When "var" is provided, copy "temp" to it assuming "var" is already
+// initialized. Destroy and deallocate "temp" in all cases.
+void RTDECL(CopyOutAssign)(Descriptor *var, Descriptor &temp,
+ const char *sourceFile = nullptr, int sourceLine = 0);
// This variant is for assignments to explicit-length CHARACTER left-hand
// sides that might need to handle truncation or blank-fill, and
// must maintain the character length even if an allocatable array
diff --git a/flang/include/flang/Runtime/inquiry.h b/flang/include/flang/Runtime/inquiry.h
index 7161d1e41c4b..c7a7487f1a1b 100644
--- a/flang/include/flang/Runtime/inquiry.h
+++ b/flang/include/flang/Runtime/inquiry.h
@@ -24,15 +24,18 @@ extern "C" {
std::int64_t RTDECL(LboundDim)(const Descriptor &array, int dim,
const char *sourceFile = nullptr, int line = 0);
-void RTDECL(Shape)(void *result, const Descriptor &array, int kind);
+void RTDECL(Lbound)(void *result, const Descriptor &array, int kind,
+ const char *sourceFile = nullptr, int line = 0);
+void RTDECL(Shape)(void *result, const Descriptor &array, int kind,
+ const char *sourceFile = nullptr, int line = 0);
std::int64_t RTDECL(Size)(
const Descriptor &array, const char *sourceFile = nullptr, int line = 0);
std::int64_t RTDECL(SizeDim)(const Descriptor &array, int dim,
const char *sourceFile = nullptr, int line = 0);
-void RTDECL(Ubound)(Descriptor &result, const Descriptor &array, int kind,
+void RTDECL(Ubound)(void *result, const Descriptor &array, int kind,
const char *sourceFile = nullptr, int line = 0);
} // extern "C"
diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index 7d3f91360c8c..e051e8643166 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -73,6 +73,20 @@ CppTypeFor<TypeCategory::Integer, 16> RTDECL(Ceiling16_16)(
#endif
#endif
+// ERFC_SCALED
+CppTypeFor<TypeCategory::Real, 4> RTDECL(ErfcScaled4)(
+ CppTypeFor<TypeCategory::Real, 4>);
+CppTypeFor<TypeCategory::Real, 8> RTDECL(ErfcScaled8)(
+ CppTypeFor<TypeCategory::Real, 8>);
+#if LDBL_MANT_DIG == 64
+CppTypeFor<TypeCategory::Real, 10> RTDECL(ErfcScaled10)(
+ CppTypeFor<TypeCategory::Real, 10>);
+#endif
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppTypeFor<TypeCategory::Real, 16> RTDECL(ErfcScaled16)(
+ CppTypeFor<TypeCategory::Real, 16>);
+#endif
+
// EXPONENT is defined to return default INTEGER; support INTEGER(4 & 8)
CppTypeFor<TypeCategory::Integer, 4> RTDECL(Exponent4_4)(
CppTypeFor<TypeCategory::Real, 4>);
diff --git a/flang/include/flang/Runtime/pointer.h b/flang/include/flang/Runtime/pointer.h
index 6ceb70ebb676..704144f08114 100644
--- a/flang/include/flang/Runtime/pointer.h
+++ b/flang/include/flang/Runtime/pointer.h
@@ -115,6 +115,11 @@ bool RTDECL(PointerIsAssociated)(const Descriptor &);
bool RTDECL(PointerIsAssociatedWith)(
const Descriptor &, const Descriptor *target);
+// Fortran POINTERs are allocated with an extra validation word after their
+// payloads in order to detect erroneous deallocations later.
+RT_API_ATTRS void *AllocateValidatedPointerPayload(std::size_t);
+RT_API_ATTRS bool ValidatePointerPayload(const ISO::CFI_cdesc_t &);
+
} // extern "C"
} // namespace Fortran::runtime
#endif // FORTRAN_RUNTIME_POINTER_H_
diff --git a/flang/include/flang/Runtime/reduce.h b/flang/include/flang/Runtime/reduce.h
index 975aa6dea305..60f54c393b4b 100644
--- a/flang/include/flang/Runtime/reduce.h
+++ b/flang/include/flang/Runtime/reduce.h
@@ -28,7 +28,9 @@ namespace Fortran::runtime {
class Descriptor;
-template <typename T> using ReductionOperation = T (*)(const T *, const T *);
+template <typename T>
+using ReferenceReductionOperation = T (*)(const T *, const T *);
+template <typename T> using ValueReductionOperation = T (*)(T, T);
template <typename CHAR>
using ReductionCharOperation = void (*)(CHAR *hiddenResult,
std::size_t resultLen, const CHAR *x, const CHAR *y, std::size_t xLen,
@@ -38,185 +40,364 @@ using ReductionDerivedTypeOperation = void (*)(
extern "C" {
-std::int8_t RTDECL(ReduceInteger1)(const Descriptor &,
- ReductionOperation<std::int8_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int8_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceInteger1Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int8_t>, const char *source, int line, int dim,
+std::int8_t RTDECL(ReduceInteger1Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int8_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int8_t *identity = nullptr, bool ordered = true);
+std::int8_t RTDECL(ReduceInteger1Value)(const Descriptor &,
+ ValueReductionOperation<std::int8_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int8_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger1DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int8_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger1DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int8_t>, const char *source, int line, int dim,
const Descriptor *mask = nullptr, const std::int8_t *identity = nullptr,
bool ordered = true);
-std::int16_t RTDECL(ReduceInteger2)(const Descriptor &,
- ReductionOperation<std::int16_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int16_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceInteger2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int16_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int16_t *identity = nullptr,
- bool ordered = true);
-std::int32_t RTDECL(ReduceInteger4)(const Descriptor &,
- ReductionOperation<std::int32_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int32_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceInteger4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int32_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int32_t *identity = nullptr,
- bool ordered = true);
-std::int64_t RTDECL(ReduceInteger8)(const Descriptor &,
- ReductionOperation<std::int64_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int64_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceInteger8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int64_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int64_t *identity = nullptr,
- bool ordered = true);
+std::int16_t RTDECL(ReduceInteger2Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int16_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+std::int16_t RTDECL(ReduceInteger2Value)(const Descriptor &,
+ ValueReductionOperation<std::int16_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger2DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger2DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int16_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+std::int32_t RTDECL(ReduceInteger4Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int32_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+std::int32_t RTDECL(ReduceInteger4Value)(const Descriptor &,
+ ValueReductionOperation<std::int32_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int32_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+std::int64_t RTDECL(ReduceInteger8Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int64_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+std::int64_t RTDECL(ReduceInteger8Value)(const Descriptor &,
+ ValueReductionOperation<std::int64_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int64_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
#ifdef __SIZEOF_INT128__
-common::int128_t RTDECL(ReduceInteger16)(const Descriptor &,
- ReductionOperation<common::int128_t>, const char *source, int line,
+common::int128_t RTDECL(ReduceInteger16Ref)(const Descriptor &,
+ ReferenceReductionOperation<common::int128_t>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const common::int128_t *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceInteger16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<common::int128_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr,
+common::int128_t RTDECL(ReduceInteger16Value)(const Descriptor &,
+ ValueReductionOperation<common::int128_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const common::int128_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger16DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<common::int128_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const common::int128_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceInteger16DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<common::int128_t>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const common::int128_t *identity = nullptr, bool ordered = true);
#endif
// REAL/COMPLEX(2 & 3) return 32-bit float results for the caller to downconvert
-float RTDECL(ReduceReal2)(const Descriptor &, ReductionOperation<float>,
- const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+float RTDECL(ReduceReal2Ref)(const Descriptor &,
+ ReferenceReductionOperation<float>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
const float *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceReal2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<float>, const char *source, int line, int dim,
+float RTDECL(ReduceReal2Value)(const Descriptor &,
+ ValueReductionOperation<float>, const char *source, int line, int dim = 0,
const Descriptor *mask = nullptr, const float *identity = nullptr,
bool ordered = true);
-float RTDECL(ReduceReal3)(const Descriptor &, ReductionOperation<float>,
- const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+void RTDECL(ReduceReal2DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+void RTDECL(ReduceReal2DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+float RTDECL(ReduceReal3Ref)(const Descriptor &,
+ ReferenceReductionOperation<float>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
const float *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceReal3Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<float>, const char *source, int line, int dim,
+float RTDECL(ReduceReal3Value)(const Descriptor &,
+ ValueReductionOperation<float>, const char *source, int line, int dim = 0,
const Descriptor *mask = nullptr, const float *identity = nullptr,
bool ordered = true);
-float RTDECL(ReduceReal4)(const Descriptor &, ReductionOperation<float>,
- const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+void RTDECL(ReduceReal3DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+void RTDECL(ReduceReal3DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+float RTDECL(ReduceReal4Ref)(const Descriptor &,
+ ReferenceReductionOperation<float>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
const float *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceReal4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<float>, const char *source, int line, int dim,
+float RTDECL(ReduceReal4Value)(const Descriptor &,
+ ValueReductionOperation<float>, const char *source, int line, int dim = 0,
const Descriptor *mask = nullptr, const float *identity = nullptr,
bool ordered = true);
-double RTDECL(ReduceReal8)(const Descriptor &, ReductionOperation<double>,
- const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+void RTDECL(ReduceReal4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+void RTDECL(ReduceReal4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<float>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const float *identity = nullptr,
+ bool ordered = true);
+double RTDECL(ReduceReal8Ref)(const Descriptor &,
+ ReferenceReductionOperation<double>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
const double *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceReal8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<double>, const char *source, int line, int dim,
+double RTDECL(ReduceReal8Value)(const Descriptor &,
+ ValueReductionOperation<double>, const char *source, int line, int dim = 0,
const Descriptor *mask = nullptr, const double *identity = nullptr,
bool ordered = true);
-#if LDBL_MANT_DIG == 64
-long double RTDECL(ReduceReal10)(const Descriptor &,
- ReductionOperation<long double>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const long double *identity = nullptr,
+void RTDECL(ReduceReal8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<double>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const double *identity = nullptr,
bool ordered = true);
-void RTDECL(ReduceReal10Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<long double>, const char *source, int line, int dim,
+void RTDECL(ReduceReal8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<double>, const char *source, int line, int dim,
+ const Descriptor *mask = nullptr, const double *identity = nullptr,
+ bool ordered = true);
+#if LDBL_MANT_DIG == 64
+long double RTDECL(ReduceReal10Ref)(const Descriptor &,
+ ReferenceReductionOperation<long double>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const long double *identity = nullptr, bool ordered = true);
+long double RTDECL(ReduceReal10Value)(const Descriptor &,
+ ValueReductionOperation<long double>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const long double *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceReal10DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<long double>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const long double *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceReal10DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<long double>, const char *source, int line, int dim,
const Descriptor *mask = nullptr, const long double *identity = nullptr,
bool ordered = true);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppFloat128Type RTDECL(ReduceReal16)(const Descriptor &,
- ReductionOperation<CppFloat128Type>, const char *source, int line,
+CppFloat128Type RTDECL(ReduceReal16Ref)(const Descriptor &,
+ ReferenceReductionOperation<CppFloat128Type>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const CppFloat128Type *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceReal16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<CppFloat128Type>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const CppFloat128Type *identity = nullptr,
- bool ordered = true);
+CppFloat128Type RTDECL(ReduceReal16Value)(const Descriptor &,
+ ValueReductionOperation<CppFloat128Type>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const CppFloat128Type *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceReal16DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<CppFloat128Type>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const CppFloat128Type *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceReal16DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<CppFloat128Type>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const CppFloat128Type *identity = nullptr, bool ordered = true);
#endif
-void RTDECL(CppReduceComplex2)(std::complex<float> &, const Descriptor &,
- ReductionOperation<std::complex<float>>, const char *source, int line,
+void RTDECL(CppReduceComplex2Ref)(std::complex<float> &, const Descriptor &,
+ ReferenceReductionOperation<std::complex<float>>, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex2Value)(std::complex<float> &, const Descriptor &,
+ ValueReductionOperation<std::complex<float>>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<float>>, const char *source, int line,
- int dim, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex2DimRef)(Descriptor &result,
+ const Descriptor &array, ReferenceReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex2DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex3)(std::complex<float> &, const Descriptor &,
- ReductionOperation<std::complex<float>>, const char *source, int line,
+void RTDECL(CppReduceComplex3Ref)(std::complex<float> &, const Descriptor &,
+ ReferenceReductionOperation<std::complex<float>>, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex3Value)(std::complex<float> &, const Descriptor &,
+ ValueReductionOperation<std::complex<float>>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex3Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<float>>, const char *source, int line,
- int dim, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex3DimRef)(Descriptor &result,
+ const Descriptor &array, ReferenceReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex3DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex4)(std::complex<float> &, const Descriptor &,
- ReductionOperation<std::complex<float>>, const char *source, int line,
+void RTDECL(CppReduceComplex4Ref)(std::complex<float> &, const Descriptor &,
+ ReferenceReductionOperation<std::complex<float>>, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex4Value)(std::complex<float> &, const Descriptor &,
+ ValueReductionOperation<std::complex<float>>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<float>>, const char *source, int line,
- int dim, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex4DimRef)(Descriptor &result,
+ const Descriptor &array, ReferenceReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const std::complex<float> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex8)(std::complex<double> &, const Descriptor &,
- ReductionOperation<std::complex<double>>, const char *source, int line,
+void RTDECL(CppReduceComplex4DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<std::complex<float>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<float> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex8Ref)(std::complex<double> &, const Descriptor &,
+ ReferenceReductionOperation<std::complex<double>>, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<double> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex8Value)(std::complex<double> &, const Descriptor &,
+ ValueReductionOperation<std::complex<double>>, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr,
const std::complex<double> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<double>>, const char *source, int line,
- int dim, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex8DimRef)(Descriptor &result,
+ const Descriptor &array, ReferenceReductionOperation<std::complex<double>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<double> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex8DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<std::complex<double>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const std::complex<double> *identity = nullptr, bool ordered = true);
#if LDBL_MANT_DIG == 64
-void RTDECL(CppReduceComplex10)(std::complex<long double> &, const Descriptor &,
- ReductionOperation<std::complex<long double>>, const char *source, int line,
- int dim = 0, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex10Ref)(std::complex<long double> &,
+ const Descriptor &, ReferenceReductionOperation<std::complex<long double>>,
+ const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
const std::complex<long double> *identity = nullptr, bool ordered = true);
-void RTDECL(CppReduceComplex10Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<long double>>, const char *source, int line,
- int dim, const Descriptor *mask = nullptr,
+void RTDECL(CppReduceComplex10Value)(std::complex<long double> &,
+ const Descriptor &, ValueReductionOperation<std::complex<long double>>,
+ const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<long double> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex10DimRef)(Descriptor &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<long double>>, const char *source,
+ int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<long double> *identity = nullptr, bool ordered = true);
+void RTDECL(CppReduceComplex10DimValue)(Descriptor &result,
+ const Descriptor &array, ValueReductionOperation<std::complex<long double>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
const std::complex<long double> *identity = nullptr, bool ordered = true);
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-void RTDECL(CppReduceComplex16)(std::complex<CppFloat128Type> &,
- const Descriptor &, ReductionOperation<std::complex<CppFloat128Type>>,
+void RTDECL(CppReduceComplex16Ref)(std::complex<CppFloat128Type> &,
+ const Descriptor &,
+ ReferenceReductionOperation<std::complex<CppFloat128Type>>,
const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
const std::complex<CppFloat128Type> *identity = nullptr,
bool ordered = true);
-void RTDECL(CppReduceComplex16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<CppFloat128Type>>, const char *source,
+void RTDECL(CppReduceComplex16Value)(std::complex<CppFloat128Type> &,
+ const Descriptor &, ValueReductionOperation<std::complex<CppFloat128Type>>,
+ const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+ const std::complex<CppFloat128Type> *identity = nullptr,
+ bool ordered = true);
+void RTDECL(CppReduceComplex16DimRef)(Descriptor &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<CppFloat128Type>>,
+ const char *source, int line, int dim, const Descriptor *mask = nullptr,
+ const std::complex<CppFloat128Type> *identity = nullptr,
+ bool ordered = true);
+void RTDECL(CppReduceComplex16DimValue)(Descriptor &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<CppFloat128Type>>, const char *source,
int line, int dim, const Descriptor *mask = nullptr,
const std::complex<CppFloat128Type> *identity = nullptr,
bool ordered = true);
#endif
-bool RTDECL(ReduceLogical1)(const Descriptor &, ReductionOperation<std::int8_t>,
- const char *source, int line, int dim = 0, const Descriptor *mask = nullptr,
+bool RTDECL(ReduceLogical1Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int8_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int8_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical1Value)(const Descriptor &,
+ ValueReductionOperation<std::int8_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int8_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical1DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
const std::int8_t *identity = nullptr, bool ordered = true);
-void RTDECL(ReduceLogical1Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int8_t>, const char *source, int line, int dim,
+void RTDECL(ReduceLogical1DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int8_t>, const char *source, int line, int dim,
const Descriptor *mask = nullptr, const std::int8_t *identity = nullptr,
bool ordered = true);
-bool RTDECL(ReduceLogical2)(const Descriptor &,
- ReductionOperation<std::int16_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int16_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceLogical2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int16_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int16_t *identity = nullptr,
- bool ordered = true);
-bool RTDECL(ReduceLogical4)(const Descriptor &,
- ReductionOperation<std::int32_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int32_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceLogical4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int32_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int32_t *identity = nullptr,
- bool ordered = true);
-bool RTDECL(ReduceLogical8)(const Descriptor &,
- ReductionOperation<std::int64_t>, const char *source, int line, int dim = 0,
- const Descriptor *mask = nullptr, const std::int64_t *identity = nullptr,
- bool ordered = true);
-void RTDECL(ReduceLogical8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int64_t>, const char *source, int line, int dim,
- const Descriptor *mask = nullptr, const std::int64_t *identity = nullptr,
- bool ordered = true);
+bool RTDECL(ReduceLogical2Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int16_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical2Value)(const Descriptor &,
+ ValueReductionOperation<std::int16_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical2DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical2DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int16_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int16_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical4Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int32_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical4Value)(const Descriptor &,
+ ValueReductionOperation<std::int32_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int32_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int32_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical8Ref)(const Descriptor &,
+ ReferenceReductionOperation<std::int64_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+bool RTDECL(ReduceLogical8Value)(const Descriptor &,
+ ValueReductionOperation<std::int64_t>, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
+void RTDECL(ReduceLogical8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int64_t>, const char *source, int line,
+ int dim, const Descriptor *mask = nullptr,
+ const std::int64_t *identity = nullptr, bool ordered = true);
void RTDECL(ReduceChar1)(char *result, const Descriptor &array,
ReductionCharOperation<char>, const char *source, int line, int dim = 0,
diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h
index da66e0eda321..8eb736bb098f 100644
--- a/flang/include/flang/Semantics/openmp-directive-sets.h
+++ b/flang/include/flang/Semantics/openmp-directive-sets.h
@@ -242,6 +242,7 @@ static const OmpDirectiveSet loopConstructSet{
Directive::OMPD_parallel_master_taskloop,
Directive::OMPD_parallel_master_taskloop_simd,
Directive::OMPD_simd,
+ Directive::OMPD_target_loop,
Directive::OMPD_target_parallel_do,
Directive::OMPD_target_parallel_do_simd,
Directive::OMPD_target_parallel_loop,
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 357a4c76d997..cdbe3e39386b 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -115,10 +115,13 @@ public:
bool isExplicitBindName() const { return isExplicitBindName_; }
void set_bindName(std::string &&name) { bindName_ = std::move(name); }
void set_isExplicitBindName(bool yes) { isExplicitBindName_ = yes; }
+ bool isCDefined() const { return isCDefined_; }
+ void set_isCDefined(bool yes) { isCDefined_ = yes; }
private:
std::optional<std::string> bindName_;
bool isExplicitBindName_{false};
+ bool isCDefined_{false};
};
// Device type specific OpenACC routine information
@@ -814,6 +817,7 @@ public:
void SetBindName(std::string &&);
bool GetIsExplicitBindName() const;
void SetIsExplicitBindName(bool);
+ void SetIsCDefined(bool);
bool IsFuncResult() const;
bool IsObjectArray() const;
const ArraySpec *GetShape() const;
diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index 528c51d8c1c4..7f2910c5cfd3 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -25,6 +25,10 @@
static llvm::cl::opt<bool> disable##DOName("disable-" DOOption, \
llvm::cl::desc("disable " DODescription " pass"), llvm::cl::init(false), \
llvm::cl::Hidden)
+#define EnableOption(EOName, EOOption, EODescription) \
+ static llvm::cl::opt<bool> enable##EOName("enable-" EOOption, \
+ llvm::cl::desc("enable " EODescription " pass"), llvm::cl::init(false), \
+ llvm::cl::Hidden)
/// Shared option in tools to control whether dynamically sized array
/// allocations should always be on the heap.
@@ -86,6 +90,8 @@ DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite",
DisableOption(ExternalNameConversion, "external-name-interop",
"convert names with external convention");
+EnableOption(ConstantArgumentGlobalisation, "constant-argument-globalisation",
+ "the local constant argument to global constant conversion");
using PassConstructor = std::unique_ptr<mlir::Pass>();
@@ -144,7 +150,7 @@ namespace fir {
static void addCanonicalizerPassWithoutRegionSimplification(
mlir::OpPassManager &pm) {
mlir::GreedyRewriteConfig config;
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCanonicalizerPass(config));
}
@@ -260,7 +266,7 @@ inline void createDefaultFIROptimizerPassPipeline(
// simplify the IR
mlir::GreedyRewriteConfig config;
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCSEPass());
fir::addAVC(pm, pc.OptLevel);
addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion);
@@ -270,6 +276,8 @@ inline void createDefaultFIROptimizerPassPipeline(
// These passes may increase code size.
pm.addPass(fir::createSimplifyIntrinsics());
pm.addPass(fir::createAlgebraicSimplificationPass(config));
+ if (enableConstantArgumentGlobalisation)
+ pm.addPass(fir::createConstantArgumentGlobalisationOpt());
}
if (pc.LoopVersioning)
@@ -295,6 +303,7 @@ inline void createDefaultFIROptimizerPassPipeline(
if (pc.AliasAnalysis && !disableFirAliasTags && !useOldAliasTags)
pm.addPass(fir::createAddAliasTags());
+ addNestedPassToAllTopLevelOperations(pm, fir::createStackReclaim);
// convert control flow to CFG form
fir::addCfgConversionPass(pm, pc);
pm.addPass(mlir::createConvertSCFToCFPass());
@@ -372,24 +381,22 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
pm.addPass(fir::createVScaleAttr({{config.VScaleMin, config.VScaleMax}}));
// Add function attributes
- fir::FunctionAttrTypes functionAttrs;
+ mlir::LLVM::framePointerKind::FramePointerKind framePointerKind;
if (config.FramePointerKind != llvm::FramePointerKind::None ||
config.NoInfsFPMath || config.NoNaNsFPMath || config.ApproxFuncFPMath ||
config.NoSignedZerosFPMath || config.UnsafeFPMath) {
if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf)
- functionAttrs.framePointerKind =
+ framePointerKind =
mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf;
else if (config.FramePointerKind == llvm::FramePointerKind::All)
- functionAttrs.framePointerKind =
- mlir::LLVM::framePointerKind::FramePointerKind::All;
+ framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All;
else
- functionAttrs.framePointerKind =
- mlir::LLVM::framePointerKind::FramePointerKind::None;
+ framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
- pm.addPass(fir::createFunctionAttrPass(functionAttrs, config.NoInfsFPMath,
+ pm.addPass(fir::createFunctionAttr({framePointerKind, config.NoInfsFPMath,
config.NoNaNsFPMath, config.ApproxFuncFPMath,
- config.NoSignedZerosFPMath, config.UnsafeFPMath));
+ config.NoSignedZerosFPMath, config.UnsafeFPMath}));
}
fir::addFIRToLLVMPass(pm, config);
diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index a0ce190b90e9..70e24d6e82eb 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -39,13 +39,16 @@ static void CopyAttrs(const semantics::Symbol &src, A &dst,
// Shapes of function results and dummy arguments have to have
// the same rank, the same deferred dimensions, and the same
// values for explicit dimensions when constant.
-bool ShapesAreCompatible(
- const Shape &x, const Shape &y, bool *possibleWarning) {
- if (x.size() != y.size()) {
+bool ShapesAreCompatible(const std::optional<Shape> &x,
+ const std::optional<Shape> &y, bool *possibleWarning) {
+ if (!x || !y) {
+ return !x && !y;
+ }
+ if (x->size() != y->size()) {
return false;
}
- auto yIter{y.begin()};
- for (const auto &xDim : x) {
+ auto yIter{y->begin()};
+ for (const auto &xDim : *x) {
const auto &yDim{*yIter++};
if (xDim && yDim) {
if (auto equiv{AreEquivalentInInterface(*xDim, *yDim)}) {
@@ -178,9 +181,11 @@ bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
thatIs, that.AsFortran(), thisIs, AsFortran());
return false;
}
- return omitShapeConformanceCheck ||
- CheckConformance(messages, shape_, that.shape_, flags, thisIs, thatIs)
- .value_or(true /*fail only when nonconformance is known now*/);
+ return omitShapeConformanceCheck || (!shape_ && !that.shape_) ||
+ (shape_ && that.shape_ &&
+ CheckConformance(
+ messages, *shape_, *that.shape_, flags, thisIs, thatIs)
+ .value_or(true /*fail only when nonconformance is known now*/));
}
std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureElementSizeInBytes(
@@ -201,11 +206,11 @@ std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureElementSizeInBytes(
std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureSizeInBytes(
FoldingContext &foldingContext) const {
- if (auto elements{GetSize(Shape{shape_})}) {
+ if (auto elements{GetSize(shape_)}) {
// Sizes of arrays (even with single elements) are multiples of
// their alignments.
if (auto elementBytes{
- MeasureElementSizeInBytes(foldingContext, GetRank(shape_) > 0)}) {
+ MeasureElementSizeInBytes(foldingContext, Rank() > 0)}) {
return Fold(
foldingContext, std::move(*elements) * std::move(*elementBytes));
}
@@ -254,10 +259,12 @@ std::string TypeAndShape::AsFortran() const {
llvm::raw_ostream &TypeAndShape::Dump(llvm::raw_ostream &o) const {
o << type_.AsFortran(LEN_ ? LEN_->AsFortran() : "");
attrs_.Dump(o, EnumToString);
- if (!shape_.empty()) {
+ if (!shape_) {
+ o << " dimension(..)";
+ } else if (!shape_->empty()) {
o << " dimension";
char sep{'('};
- for (const auto &expr : shape_) {
+ for (const auto &expr : *shape_) {
o << sep;
sep = ',';
if (expr) {
@@ -1112,6 +1119,7 @@ bool FunctionResult::CanBeReturnedViaImplicitInterface(
static std::optional<std::string> AreIncompatibleFunctionResultShapes(
const Shape &x, const Shape &y) {
+ // Function results cannot be assumed-rank, hence the non optional arguments.
int rank{GetRank(x)};
if (int yrank{GetRank(y)}; yrank != rank) {
return "rank "s + std::to_string(rank) + " vs " + std::to_string(yrank);
@@ -1147,7 +1155,8 @@ bool FunctionResult::IsCompatibleWith(
}
} else if (!attrs.test(Attr::Allocatable) && !attrs.test(Attr::Pointer) &&
(details = AreIncompatibleFunctionResultShapes(
- ifaceTypeShape->shape(), actualTypeShape->shape()))) {
+ ifaceTypeShape->shape().value(),
+ actualTypeShape->shape().value()))) {
if (whyNot) {
*whyNot = "function results have distinct extents (" + *details + ')';
}
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 068514b51421..342aac4dd5d5 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -419,7 +419,7 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
if (converted) {
auto folded{Fold(context, std::move(*converted))};
if (IsActuallyConstant(folded)) {
- int symRank{GetRank(symTS->shape())};
+ int symRank{symTS->Rank()};
if (IsImpliedShape(symbol)) {
if (folded.Rank() == symRank) {
return ArrayConstantBoundChanger{
@@ -442,7 +442,8 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
context, GetRawLowerBounds(context, NamedEntity{symbol}))}
.Expand(std::move(folded));
} else if (auto resultShape{GetShape(context, folded)}) {
- if (CheckConformance(context.messages(), symTS->shape(),
+ CHECK(symTS->shape()); // Assumed-ranks cannot be initialized.
+ if (CheckConformance(context.messages(), *symTS->shape(),
*resultShape, CheckConformanceFlags::None,
"initialized object", "initialization expression")
.value_or(false /*fail if not known now to conform*/)) {
@@ -507,43 +508,6 @@ std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &symbol,
return std::nullopt;
}
-static bool IsNonLocal(const semantics::Symbol &symbol) {
- return semantics::IsDummy(symbol) || symbol.has<semantics::UseDetails>() ||
- symbol.owner().kind() == semantics::Scope::Kind::Module ||
- semantics::FindCommonBlockContaining(symbol) ||
- symbol.has<semantics::HostAssocDetails>();
-}
-
-static bool IsPermissibleInquiry(const semantics::Symbol &firstSymbol,
- const semantics::Symbol &lastSymbol, DescriptorInquiry::Field field,
- const semantics::Scope &localScope) {
- if (IsNonLocal(firstSymbol)) {
- return true;
- }
- if (&localScope != &firstSymbol.owner()) {
- return true;
- }
- // Inquiries on local objects may not access a deferred bound or length.
- // (This code used to be a switch, but it proved impossible to write it
- // thus without running afoul of bogus warnings from different C++
- // compilers.)
- if (field == DescriptorInquiry::Field::Rank) {
- return true; // always known
- }
- const auto *object{lastSymbol.detailsIf<semantics::ObjectEntityDetails>()};
- if (field == DescriptorInquiry::Field::LowerBound ||
- field == DescriptorInquiry::Field::Extent ||
- field == DescriptorInquiry::Field::Stride) {
- return object && !object->shape().CanBeDeferredShape();
- }
- if (field == DescriptorInquiry::Field::Len) {
- return object && object->type() &&
- object->type()->category() == semantics::DeclTypeSpec::Character &&
- !object->type()->characterTypeSpec().length().isDeferred();
- }
- return false;
-}
-
// Specification expression validation (10.1.11(2), C1010)
class CheckSpecificationExprHelper
: public AnyTraverse<CheckSpecificationExprHelper,
@@ -551,9 +515,10 @@ class CheckSpecificationExprHelper
public:
using Result = std::optional<std::string>;
using Base = AnyTraverse<CheckSpecificationExprHelper, Result>;
- explicit CheckSpecificationExprHelper(
- const semantics::Scope &s, FoldingContext &context)
- : Base{*this}, scope_{s}, context_{context} {}
+ explicit CheckSpecificationExprHelper(const semantics::Scope &s,
+ FoldingContext &context, bool forElementalFunctionResult)
+ : Base{*this}, scope_{s}, context_{context},
+ forElementalFunctionResult_{forElementalFunctionResult} {}
using Base::operator();
Result operator()(const CoarrayRef &) const { return "coindexed reference"; }
@@ -572,7 +537,10 @@ public:
"reference variable '"s +
ultimate.name().ToString() + "'";
} else if (IsDummy(ultimate)) {
- if (ultimate.attrs().test(semantics::Attr::OPTIONAL)) {
+ if (!inInquiry_ && forElementalFunctionResult_) {
+ return "dependence on value of dummy argument '"s +
+ ultimate.name().ToString() + "'";
+ } else if (ultimate.attrs().test(semantics::Attr::OPTIONAL)) {
return "reference to OPTIONAL dummy argument '"s +
ultimate.name().ToString() + "'";
} else if (!inInquiry_ &&
@@ -629,8 +597,8 @@ public:
// expressions will have been converted to expressions over descriptor
// inquiries by Fold().
// Catch REAL, ALLOCATABLE :: X(:); REAL :: Y(SIZE(X))
- if (IsPermissibleInquiry(x.base().GetFirstSymbol(),
- x.base().GetLastSymbol(), x.field(), scope_)) {
+ if (IsPermissibleInquiry(
+ x.base().GetFirstSymbol(), x.base().GetLastSymbol(), x.field())) {
auto restorer{common::ScopedSet(inInquiry_, true)};
return (*this)(x.base());
} else if (IsConstantExpr(x)) {
@@ -641,10 +609,18 @@ public:
}
Result operator()(const TypeParamInquiry &inq) const {
- if (scope_.IsDerivedType() && !IsConstantExpr(inq) &&
- inq.base() /* X%T, not local T */) { // C750, C754
- return "non-constant reference to a type parameter inquiry not "
- "allowed for derived type components or type parameter values";
+ if (scope_.IsDerivedType()) {
+ if (!IsConstantExpr(inq) &&
+ inq.base() /* X%T, not local T */) { // C750, C754
+ return "non-constant reference to a type parameter inquiry not allowed "
+ "for derived type components or type parameter values";
+ }
+ } else if (inq.base() &&
+ IsInquiryAlwaysPermissible(inq.base()->GetFirstSymbol())) {
+ auto restorer{common::ScopedSet(inInquiry_, true)};
+ return (*this)(inq.base());
+ } else if (!IsConstantExpr(inq)) {
+ return "non-constant type parameter inquiry not allowed for local object";
}
return std::nullopt;
}
@@ -674,7 +650,8 @@ public:
return std::holds_alternative<characteristics::DummyProcedure>(
dummy.u);
})};
- if (iter != procChars->dummyArguments.end()) {
+ if (iter != procChars->dummyArguments.end() &&
+ ultimate.name().ToString() != "__builtin_c_funloc") {
return "reference to function '"s + ultimate.name().ToString() +
"' with dummy procedure argument '" + iter->name + '\'';
}
@@ -719,19 +696,19 @@ public:
intrin.name == "is_contiguous") { // ok
} else if (intrin.name == "len" &&
IsPermissibleInquiry(dataRef->GetFirstSymbol(),
- dataRef->GetLastSymbol(), DescriptorInquiry::Field::Len,
- scope_)) { // ok
+ dataRef->GetLastSymbol(),
+ DescriptorInquiry::Field::Len)) { // ok
} else if (intrin.name == "lbound" &&
IsPermissibleInquiry(dataRef->GetFirstSymbol(),
dataRef->GetLastSymbol(),
- DescriptorInquiry::Field::LowerBound, scope_)) { // ok
+ DescriptorInquiry::Field::LowerBound)) { // ok
} else if ((intrin.name == "shape" || intrin.name == "size" ||
intrin.name == "sizeof" ||
intrin.name == "storage_size" ||
intrin.name == "ubound") &&
IsPermissibleInquiry(dataRef->GetFirstSymbol(),
- dataRef->GetLastSymbol(), DescriptorInquiry::Field::Extent,
- scope_)) { // ok
+ dataRef->GetLastSymbol(),
+ DescriptorInquiry::Field::Extent)) { // ok
} else {
return "non-constant inquiry function '"s + intrin.name +
"' not allowed for local object";
@@ -750,32 +727,86 @@ private:
// Contextual information: this flag is true when in an argument to
// an inquiry intrinsic like SIZE().
mutable bool inInquiry_{false};
+ bool forElementalFunctionResult_{false}; // F'2023 C15121
const std::set<std::string> badIntrinsicsForComponents_{
"allocated", "associated", "extends_type_of", "present", "same_type_as"};
+
+ bool IsInquiryAlwaysPermissible(const semantics::Symbol &) const;
+ bool IsPermissibleInquiry(const semantics::Symbol &firstSymbol,
+ const semantics::Symbol &lastSymbol,
+ DescriptorInquiry::Field field) const;
};
+bool CheckSpecificationExprHelper::IsInquiryAlwaysPermissible(
+ const semantics::Symbol &symbol) const {
+ if (&symbol.owner() != &scope_ || symbol.has<semantics::UseDetails>() ||
+ symbol.owner().kind() == semantics::Scope::Kind::Module ||
+ semantics::FindCommonBlockContaining(symbol) ||
+ symbol.has<semantics::HostAssocDetails>()) {
+ return true; // it's nonlocal
+ } else if (semantics::IsDummy(symbol) && !forElementalFunctionResult_) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool CheckSpecificationExprHelper::IsPermissibleInquiry(
+ const semantics::Symbol &firstSymbol, const semantics::Symbol &lastSymbol,
+ DescriptorInquiry::Field field) const {
+ if (IsInquiryAlwaysPermissible(firstSymbol)) {
+ return true;
+ }
+ // Inquiries on local objects may not access a deferred bound or length.
+ // (This code used to be a switch, but it proved impossible to write it
+ // thus without running afoul of bogus warnings from different C++
+ // compilers.)
+ if (field == DescriptorInquiry::Field::Rank) {
+ return true; // always known
+ }
+ const auto *object{lastSymbol.detailsIf<semantics::ObjectEntityDetails>()};
+ if (field == DescriptorInquiry::Field::LowerBound ||
+ field == DescriptorInquiry::Field::Extent ||
+ field == DescriptorInquiry::Field::Stride) {
+ return object && !object->shape().CanBeDeferredShape();
+ }
+ if (field == DescriptorInquiry::Field::Len) {
+ return object && object->type() &&
+ object->type()->category() == semantics::DeclTypeSpec::Character &&
+ !object->type()->characterTypeSpec().length().isDeferred();
+ }
+ return false;
+}
+
template <typename A>
-void CheckSpecificationExpr(
- const A &x, const semantics::Scope &scope, FoldingContext &context) {
- if (auto why{CheckSpecificationExprHelper{scope, context}(x)}) {
- context.messages().Say(
- "Invalid specification expression: %s"_err_en_US, *why);
+void CheckSpecificationExpr(const A &x, const semantics::Scope &scope,
+ FoldingContext &context, bool forElementalFunctionResult) {
+ if (auto why{CheckSpecificationExprHelper{
+ scope, context, forElementalFunctionResult}(x)}) {
+ context.messages().Say("Invalid specification expression%s: %s"_err_en_US,
+ forElementalFunctionResult ? " for elemental function result" : "",
+ *why);
}
}
-template void CheckSpecificationExpr(
- const Expr<SomeType> &, const semantics::Scope &, FoldingContext &);
-template void CheckSpecificationExpr(
- const Expr<SomeInteger> &, const semantics::Scope &, FoldingContext &);
-template void CheckSpecificationExpr(
- const Expr<SubscriptInteger> &, const semantics::Scope &, FoldingContext &);
+template void CheckSpecificationExpr(const Expr<SomeType> &,
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
+template void CheckSpecificationExpr(const Expr<SomeInteger> &,
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
+template void CheckSpecificationExpr(const Expr<SubscriptInteger> &,
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
template void CheckSpecificationExpr(const std::optional<Expr<SomeType>> &,
- const semantics::Scope &, FoldingContext &);
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
template void CheckSpecificationExpr(const std::optional<Expr<SomeInteger>> &,
- const semantics::Scope &, FoldingContext &);
+ const semantics::Scope &, FoldingContext &,
+ bool forElementalFunctionResult);
template void CheckSpecificationExpr(
const std::optional<Expr<SubscriptInteger>> &, const semantics::Scope &,
- FoldingContext &);
+ FoldingContext &, bool forElementalFunctionResult);
// IsContiguous() -- 9.5.4
class IsContiguousHelper
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index b76b9d49b582..981cdff7f350 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -1116,14 +1116,25 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return FoldMaxvalMinval<T>(
context, std::move(funcRef), RelationalOperator::LT, T::Scalar::HUGE());
} else if (name == "mod") {
+ bool badPConst{false};
+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1])}) {
+ *pExpr = Fold(context, std::move(*pExpr));
+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
+ pConst->IsZero() &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say("MOD: P argument is zero"_warn_en_US);
+ badPConst = true;
+ }
+ }
return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
ScalarFuncWithContext<T, T, T>(
- [](FoldingContext &context, const Scalar<T> &x,
+ [badPConst](FoldingContext &context, const Scalar<T> &x,
const Scalar<T> &y) -> Scalar<T> {
auto quotRem{x.DivideSigned(y)};
if (context.languageFeatures().ShouldWarn(
common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
- if (quotRem.divisionByZero) {
+ if (!badPConst && quotRem.divisionByZero) {
context.messages().Say("mod() by zero"_warn_en_US);
} else if (quotRem.overflow) {
context.messages().Say("mod() folding overflowed"_warn_en_US);
@@ -1132,12 +1143,23 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return quotRem.remainder;
}));
} else if (name == "modulo") {
+ bool badPConst{false};
+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1])}) {
+ *pExpr = Fold(context, std::move(*pExpr));
+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
+ pConst->IsZero() &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say("MODULO: P argument is zero"_warn_en_US);
+ badPConst = true;
+ }
+ }
return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
- ScalarFuncWithContext<T, T, T>([](FoldingContext &context,
+ ScalarFuncWithContext<T, T, T>([badPConst](FoldingContext &context,
const Scalar<T> &x,
const Scalar<T> &y) -> Scalar<T> {
auto result{x.MODULO(y)};
- if (result.overflow &&
+ if (!badPConst && result.overflow &&
context.languageFeatures().ShouldWarn(
common::UsageWarning::FoldingException)) {
context.messages().Say("modulo() folding overflowed"_warn_en_US);
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index a7c655b72f56..ee6655f83871 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -620,6 +620,24 @@ static Expr<Type<TypeCategory::Logical, KIND>> RewriteOutOfRange(
return AsExpr(std::move(funcRef));
}
+static std::optional<common::RoundingMode> GetRoundingMode(
+ const std::optional<ActualArgument> &arg) {
+ if (arg) {
+ if (const auto *cst{UnwrapExpr<Constant<SomeDerived>>(*arg)}) {
+ if (auto constr{cst->GetScalarValue()}) {
+ if (StructureConstructorValues & values{constr->values()};
+ values.size() == 1) {
+ const Expr<SomeType> &value{values.begin()->second.value()};
+ if (auto code{ToInt64(value)}) {
+ return static_cast<common::RoundingMode>(*code);
+ }
+ }
+ }
+ }
+ }
+ return std::nullopt;
+}
+
template <int KIND>
Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
FoldingContext &context,
@@ -831,17 +849,48 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
}
}
}
- } else if (name == "__builtin_ieee_support_datatype" ||
- name == "__builtin_ieee_support_denormal" ||
- name == "__builtin_ieee_support_divide" ||
- name == "__builtin_ieee_support_inf" ||
- name == "__builtin_ieee_support_io" ||
- name == "__builtin_ieee_support_nan" ||
- name == "__builtin_ieee_support_sqrt" ||
- name == "__builtin_ieee_support_standard" ||
- name == "__builtin_ieee_support_subnormal" ||
- name == "__builtin_ieee_support_underflow_control") {
+ } else if (name == "__builtin_ieee_support_datatype") {
return Expr<T>{true};
+ } else if (name == "__builtin_ieee_support_denormal") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Denormal)};
+ } else if (name == "__builtin_ieee_support_divide") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Divide)};
+ } else if (name == "__builtin_ieee_support_flag") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Flags)};
+ } else if (name == "__builtin_ieee_support_halting") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Halting)};
+ } else if (name == "__builtin_ieee_support_inf") {
+ return Expr<T>{
+ context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Inf)};
+ } else if (name == "__builtin_ieee_support_io") {
+ return Expr<T>{
+ context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Io)};
+ } else if (name == "__builtin_ieee_support_nan") {
+ return Expr<T>{
+ context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::NaN)};
+ } else if (name == "__builtin_ieee_support_rounding") {
+ if (context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Rounding)) {
+ if (auto mode{GetRoundingMode(args[0])}) {
+ return Expr<T>{mode != common::RoundingMode::TiesAwayFromZero};
+ }
+ }
+ } else if (name == "__builtin_ieee_support_sqrt") {
+ return Expr<T>{
+ context.targetCharacteristics().ieeeFeatures().test(IeeeFeature::Sqrt)};
+ } else if (name == "__builtin_ieee_support_standard") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Standard)};
+ } else if (name == "__builtin_ieee_support_subnormal") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::Subnormal)};
+ } else if (name == "__builtin_ieee_support_underflow_control") {
+ return Expr<T>{context.targetCharacteristics().ieeeFeatures().test(
+ IeeeFeature::UnderflowControl)};
}
return Expr<T>{std::move(funcRef)};
}
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index f71addcc4094..69c7a924cc1c 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -303,41 +303,72 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
context, std::move(funcRef), RelationalOperator::LT, T::Scalar::HUGE());
} else if (name == "mod") {
CHECK(args.size() == 2);
+ bool badPConst{false};
+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1])}) {
+ *pExpr = Fold(context, std::move(*pExpr));
+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
+ pConst->IsZero() &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say("MOD: P argument is zero"_warn_en_US);
+ badPConst = true;
+ }
+ }
return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
- ScalarFunc<T, T, T>(
- [&context](const Scalar<T> &x, const Scalar<T> &y) -> Scalar<T> {
- auto result{x.MOD(y)};
- if (result.flags.test(RealFlag::DivideByZero) &&
- context.languageFeatures().ShouldWarn(
- common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
- context.messages().Say(
- "second argument to MOD must not be zero"_warn_en_US);
- }
- return result.value;
- }));
+ ScalarFunc<T, T, T>([&context, badPConst](const Scalar<T> &x,
+ const Scalar<T> &y) -> Scalar<T> {
+ auto result{x.MOD(y)};
+ if (!badPConst && result.flags.test(RealFlag::DivideByZero) &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say(
+ "second argument to MOD must not be zero"_warn_en_US);
+ }
+ return result.value;
+ }));
} else if (name == "modulo") {
CHECK(args.size() == 2);
+ bool badPConst{false};
+ if (auto *pExpr{UnwrapExpr<Expr<T>>(args[1])}) {
+ *pExpr = Fold(context, std::move(*pExpr));
+ if (auto pConst{GetScalarConstantValue<T>(*pExpr)}; pConst &&
+ pConst->IsZero() &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say("MODULO: P argument is zero"_warn_en_US);
+ badPConst = true;
+ }
+ }
return FoldElementalIntrinsic<T, T, T>(context, std::move(funcRef),
- ScalarFunc<T, T, T>(
- [&context](const Scalar<T> &x, const Scalar<T> &y) -> Scalar<T> {
- auto result{x.MODULO(y)};
- if (result.flags.test(RealFlag::DivideByZero) &&
- context.languageFeatures().ShouldWarn(
- common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
- context.messages().Say(
- "second argument to MODULO must not be zero"_warn_en_US);
- }
- return result.value;
- }));
+ ScalarFunc<T, T, T>([&context, badPConst](const Scalar<T> &x,
+ const Scalar<T> &y) -> Scalar<T> {
+ auto result{x.MODULO(y)};
+ if (!badPConst && result.flags.test(RealFlag::DivideByZero) &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingAvoidsRuntimeCrash)) {
+ context.messages().Say(
+ "second argument to MODULO must not be zero"_warn_en_US);
+ }
+ return result.value;
+ }));
} else if (name == "nearest") {
- if (const auto *sExpr{UnwrapExpr<Expr<SomeReal>>(args[1])}) {
+ if (auto *sExpr{UnwrapExpr<Expr<SomeReal>>(args[1])}) {
+ *sExpr = Fold(context, std::move(*sExpr));
return common::visit(
[&](const auto &sVal) {
using TS = ResultType<decltype(sVal)>;
+ bool badSConst{false};
+ if (auto sConst{GetScalarConstantValue<TS>(sVal)}; sConst &&
+ sConst->IsZero() &&
+ context.languageFeatures().ShouldWarn(
+ common::UsageWarning::FoldingValueChecks)) {
+ context.messages().Say("NEAREST: S argument is zero"_warn_en_US);
+ badSConst = true;
+ }
return FoldElementalIntrinsic<T, T, TS>(context, std::move(funcRef),
ScalarFunc<T, T, TS>([&](const Scalar<T> &x,
const Scalar<TS> &s) -> Scalar<T> {
- if (s.IsZero() &&
+ if (!badSConst && s.IsZero() &&
context.languageFeatures().ShouldWarn(
common::UsageWarning::FoldingValueChecks)) {
context.messages().Say(
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 58c1b6989f49..80752d02b5ba 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -88,6 +88,8 @@ ENUM_CLASS(KindCode, none, defaultIntegerKind,
sameKind,
operand, // match any kind, with promotion (non-standard)
typeless, // BOZ literals are INTEGER with this kind
+ ieeeFlagType, // IEEE_FLAG_TYPE from ISO_FORTRAN_EXCEPTION
+ ieeeRoundType, // IEEE_ROUND_TYPE from ISO_FORTRAN_ARITHMETIC
teamType, // TEAM_TYPE from module ISO_FORTRAN_ENV (for coarrays)
kindArg, // this argument is KIND=
effectiveKind, // for function results: "kindArg" value, possibly defaulted
@@ -121,6 +123,9 @@ static constexpr TypePattern DefaultChar{CharType, KindCode::defaultCharKind};
static constexpr TypePattern DefaultLogical{
LogicalType, KindCode::defaultLogicalKind};
static constexpr TypePattern BOZ{IntType, KindCode::typeless};
+static constexpr TypePattern IeeeFlagType{DerivedType, KindCode::ieeeFlagType};
+static constexpr TypePattern IeeeRoundType{
+ DerivedType, KindCode::ieeeRoundType};
static constexpr TypePattern TeamType{DerivedType, KindCode::teamType};
static constexpr TypePattern DoublePrecision{
RealType, KindCode::doublePrecision};
@@ -940,6 +945,12 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"__builtin_ieee_support_divide",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},
+ {"__builtin_ieee_support_flag",
+ {{"flag", IeeeFlagType, Rank::scalar},
+ {"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
+ {"__builtin_ieee_support_halting", {{"flag", IeeeFlagType, Rank::scalar}},
+ DefaultLogical},
{"__builtin_ieee_support_inf",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},
@@ -949,6 +960,10 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"__builtin_ieee_support_nan",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},
+ {"__builtin_ieee_support_rounding",
+ {{"round_value", IeeeRoundType, Rank::scalar},
+ {"x", AnyReal, Rank::elemental, Optionality::optional}},
+ DefaultLogical},
{"__builtin_ieee_support_sqrt",
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
DefaultLogical},
@@ -1098,6 +1113,7 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
{{"ddim", {{"x", DoublePrecision}, {"y", DoublePrecision}},
DoublePrecision},
"dim"},
+ {{"derf", {{"x", DoublePrecision}}, DoublePrecision}, "erf"},
{{"dexp", {{"x", DoublePrecision}}, DoublePrecision}, "exp"},
{{"dfloat", {{"a", AnyInt}}, DoublePrecision}, "real", true},
{{"dim", {{"x", DefaultReal}, {"y", DefaultReal}}, DefaultReal}},
@@ -1851,6 +1867,16 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
case KindCode::typeless:
argOk = false;
break;
+ case KindCode::ieeeFlagType:
+ argOk = !type->IsUnlimitedPolymorphic() &&
+ type->category() == TypeCategory::Derived &&
+ semantics::IsIeeeFlagType(&type->GetDerivedTypeSpec());
+ break;
+ case KindCode::ieeeRoundType:
+ argOk = !type->IsUnlimitedPolymorphic() &&
+ type->category() == TypeCategory::Derived &&
+ semantics::IsIeeeRoundType(&type->GetDerivedTypeSpec());
+ break;
case KindCode::teamType:
argOk = !type->IsUnlimitedPolymorphic() &&
type->category() == TypeCategory::Derived &&
@@ -2691,6 +2717,10 @@ SpecificCall IntrinsicProcTable::Implementation::HandleNull(
mold = nullptr;
}
if (mold) {
+ if (IsAssumedRank(*arguments[0])) {
+ context.messages().Say(arguments[0]->sourceLocation(),
+ "MOLD= argument to NULL() must not be assumed-rank"_err_en_US);
+ }
bool isProcPtrTarget{
IsProcedurePointerTarget(*mold) && !IsNullObjectPointer(*mold)};
if (isProcPtrTarget || IsAllocatableOrPointerObject(*mold)) {
@@ -2932,7 +2962,7 @@ static bool CheckForNonPositiveValues(FoldingContext &context,
if (arg.Rank() > 0) {
if (const Expr<SomeType> *expr{arg.UnwrapExpr()}) {
if (const auto *intExpr{std::get_if<Expr<SomeInteger>>(&expr->u)}) {
- std::visit(
+ Fortran::common::visit(
[&](const auto &kindExpr) {
using IntType = typename std::decay_t<decltype(kindExpr)>::Result;
if (const auto *constArray{
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index 5cf48b240eca..c62d0cb0ff29 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -1037,7 +1037,7 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
} else if (context_) {
if (auto moldTypeAndShape{characteristics::TypeAndShape::Characterize(
call.arguments().at(1), *context_)}) {
- if (GetRank(moldTypeAndShape->shape()) == 0) {
+ if (moldTypeAndShape->Rank() == 0) {
// SIZE= is absent and MOLD= is scalar: result is scalar
return ScalarShape();
} else {
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 4699c5312868..a5f4faa0cef8 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -82,6 +82,8 @@ auto IsVariableHelper::operator()(const Symbol &symbol) const -> Result {
const Symbol &ultimate{symbol.GetUltimate()};
return !IsNamedConstant(ultimate) &&
(ultimate.has<semantics::ObjectEntityDetails>() ||
+ (ultimate.has<semantics::EntityDetails>() &&
+ ultimate.attrs().test(semantics::Attr::TARGET)) ||
ultimate.has<semantics::AssocEntityDetails>());
}
auto IsVariableHelper::operator()(const Component &x) const -> Result {
@@ -1754,13 +1756,34 @@ bool IsSequenceOrBindCType(const DerivedTypeSpec *derived) {
derived->typeSymbol().get<DerivedTypeDetails>().sequence());
}
+static bool IsSameModule(const Scope *x, const Scope *y) {
+ if (x == y) {
+ return true;
+ } else if (x && y) {
+ // Allow for a builtin module to be read from distinct paths
+ const Symbol *xSym{x->symbol()};
+ const Symbol *ySym{y->symbol()};
+ if (xSym && ySym && xSym->name() == ySym->name()) {
+ const auto *xMod{xSym->detailsIf<ModuleDetails>()};
+ const auto *yMod{ySym->detailsIf<ModuleDetails>()};
+ if (xMod && yMod) {
+ auto xHash{xMod->moduleFileHash()};
+ auto yHash{yMod->moduleFileHash()};
+ return xHash && yHash && *xHash == *yHash;
+ }
+ }
+ }
+ return false;
+}
+
bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name) {
- if (!derived) {
- return false;
- } else {
+ if (derived) {
const auto &symbol{derived->typeSymbol()};
- return &symbol.owner() == symbol.owner().context().GetBuiltinsScope() &&
- symbol.name() == "__builtin_"s + name;
+ const Scope &scope{symbol.owner()};
+ return symbol.name() == "__builtin_"s + name &&
+ IsSameModule(&scope, scope.context().GetBuiltinsScope());
+ } else {
+ return false;
}
}
@@ -1790,6 +1813,14 @@ bool IsNotifyType(const DerivedTypeSpec *derived) {
return IsBuiltinDerivedType(derived, "notify_type");
}
+bool IsIeeeFlagType(const DerivedTypeSpec *derived) {
+ return IsBuiltinDerivedType(derived, "ieee_flag_type");
+}
+
+bool IsIeeeRoundType(const DerivedTypeSpec *derived) {
+ return IsBuiltinDerivedType(derived, "ieee_round_type");
+}
+
bool IsTeamType(const DerivedTypeSpec *derived) {
return IsBuiltinDerivedType(derived, "team_type");
}
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index f85665d11429..c20b9096aff4 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -50,6 +50,7 @@ add_flang_library(flangFrontend
Passes
Analysis
Extensions
+ IRPrinter
IRReader
Option
Support
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index f64a939b785e..f96d72f1ad69 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -347,6 +347,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ))
opts.SaveTempsDir = a->getValue();
+ // -mlink-builtin-bitcode
+ for (auto *a :
+ args.filtered(clang::driver::options::OPT_mlink_builtin_bitcode))
+ opts.BuiltinBCLibs.push_back(a->getValue());
+
// -mrelocation-model option.
if (const llvm::opt::Arg *a =
args.getLastArg(clang::driver::options::OPT_mrelocation_model)) {
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index b1b6391f1439..24db4df31279 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -43,6 +43,8 @@
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -53,7 +55,9 @@
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/IRReader/IRReader.h"
+#include "llvm/Linker/Linker.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
@@ -68,6 +72,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
+#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <memory>
#include <system_error>
@@ -995,6 +1000,8 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
if (action == BackendActionTy::Backend_EmitBC)
mpm.addPass(llvm::BitcodeWriterPass(os));
+ else if (action == BackendActionTy::Backend_EmitLL)
+ mpm.addPass(llvm::PrintModulePass(os));
// Run the passes.
mpm.run(*llvmModule, mam);
@@ -1146,6 +1153,54 @@ void CodeGenAction::embedOffloadObjects() {
}
}
+void CodeGenAction::linkBuiltinBCLibs() {
+ auto options = clang::FileSystemOptions();
+ clang::FileManager fileManager(options);
+ CompilerInstance &ci = this->getInstance();
+ const auto &cgOpts = ci.getInvocation().getCodeGenOpts();
+
+ std::vector<std::unique_ptr<llvm::Module>> modules;
+
+ // Load LLVM modules
+ for (llvm::StringRef bcLib : cgOpts.BuiltinBCLibs) {
+ auto BCBuf = fileManager.getBufferForFile(bcLib);
+ if (!BCBuf) {
+ auto diagID = ci.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "could not open '%0' for linking");
+ ci.getDiagnostics().Report(diagID) << bcLib;
+ return;
+ }
+
+ llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
+ getOwningLazyBitcodeModule(std::move(*BCBuf), *llvmCtx);
+ if (!ModuleOrErr) {
+ auto diagID = ci.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "error loading '%0' for linking");
+ ci.getDiagnostics().Report(diagID) << bcLib;
+ return;
+ }
+ modules.push_back(std::move(ModuleOrErr.get()));
+ }
+
+ // Link modules and internalize functions
+ for (auto &module : modules) {
+ bool Err;
+ Err = llvm::Linker::linkModules(
+ *llvmModule, std::move(module), llvm::Linker::Flags::LinkOnlyNeeded,
+ [](llvm::Module &M, const llvm::StringSet<> &GVS) {
+ llvm::internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
+ return !GV.hasName() || (GVS.count(GV.getName()) == 0);
+ });
+ });
+ if (Err) {
+ auto diagID = ci.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "link error when linking '%0'");
+ ci.getDiagnostics().Report(diagID) << module->getSourceFileName();
+ return;
+ }
+ }
+}
+
static void reportOptRecordError(llvm::Error e, clang::DiagnosticsEngine &diags,
const CodeGenOptions &codeGenOpts) {
handleAllErrors(
@@ -1237,6 +1292,10 @@ void CodeGenAction::executeAction() {
llvmModule->setTargetTriple(theTriple);
llvmModule->setDataLayout(targetMachine.createDataLayout());
+ // Link in builtin bitcode libraries
+ if (!codeGenOpts.BuiltinBCLibs.empty())
+ linkBuiltinBCLibs();
+
// Embed offload objects specified with -fembed-offload-object
if (!codeGenOpts.OffloadObjects.empty())
embedOffloadObjects();
@@ -1270,13 +1329,8 @@ void CodeGenAction::executeAction() {
// Run LLVM's middle-end (i.e. the optimizer).
runOptimizationPipeline(ci.isOutputStreamNull() ? *os : ci.getOutputStream());
- if (action == BackendActionTy::Backend_EmitLL) {
- llvmModule->print(ci.isOutputStreamNull() ? *os : ci.getOutputStream(),
- /*AssemblyAnnotationWriter=*/nullptr);
- return;
- }
-
- if (action == BackendActionTy::Backend_EmitBC) {
+ if (action == BackendActionTy::Backend_EmitLL ||
+ action == BackendActionTy::Backend_EmitBC) {
// This action has effectively been completed in runOptimizationPipeline.
return;
}
diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index 068f5d25967c..77e02898ac9f 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -350,10 +350,10 @@ private:
void visitAllocateOptions() {
for (const auto &allocOption :
std::get<std::list<Fortran::parser::AllocOpt>>(stmt.t))
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::StatOrErrmsg &statOrErr) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::StatVariable &statVar) {
statExpr = Fortran::semantics::GetExpr(statVar);
@@ -898,15 +898,16 @@ void Fortran::lower::genDeallocateStmt(
const Fortran::lower::SomeExpr *errMsgExpr = nullptr;
for (const Fortran::parser::StatOrErrmsg &statOrErr :
std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t))
- std::visit(Fortran::common::visitors{
- [&](const Fortran::parser::StatVariable &statVar) {
- statExpr = Fortran::semantics::GetExpr(statVar);
- },
- [&](const Fortran::parser::MsgVariable &errMsgVar) {
- errMsgExpr = Fortran::semantics::GetExpr(errMsgVar);
- },
- },
- statOrErr.u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::StatVariable &statVar) {
+ statExpr = Fortran::semantics::GetExpr(statVar);
+ },
+ [&](const Fortran::parser::MsgVariable &errMsgVar) {
+ errMsgExpr = Fortran::semantics::GetExpr(errMsgVar);
+ },
+ },
+ statOrErr.u);
ErrorManager errorManager;
errorManager.init(converter, loc, statExpr, errMsgExpr);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 512c7a349ae2..50f58843ec70 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -104,7 +104,7 @@ struct IncrementLoopInfo {
bool hasLocalitySpecs() const {
return !localSymList.empty() || !localInitSymList.empty() ||
- !sharedSymList.empty();
+ !reduceSymList.empty() || !sharedSymList.empty();
}
// Data members common to both structured and unstructured loops.
@@ -116,6 +116,9 @@ struct IncrementLoopInfo {
bool isUnordered; // do concurrent, forall
llvm::SmallVector<const Fortran::semantics::Symbol *> localSymList;
llvm::SmallVector<const Fortran::semantics::Symbol *> localInitSymList;
+ llvm::SmallVector<
+ std::pair<fir::ReduceOperationEnum, const Fortran::semantics::Symbol *>>
+ reduceSymList;
llvm::SmallVector<const Fortran::semantics::Symbol *> sharedSymList;
mlir::Value loopVariable = nullptr;
@@ -299,28 +302,32 @@ public:
bool hasMainProgram = false;
const Fortran::semantics::Symbol *globalOmpRequiresSymbol = nullptr;
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
- std::visit(Fortran::common::visitors{
- [&](Fortran::lower::pft::FunctionLikeUnit &f) {
- if (f.isMainProgram())
- hasMainProgram = true;
- declareFunction(f);
- if (!globalOmpRequiresSymbol)
- globalOmpRequiresSymbol = f.getScope().symbol();
- },
- [&](Fortran::lower::pft::ModuleLikeUnit &m) {
- lowerModuleDeclScope(m);
- for (Fortran::lower::pft::FunctionLikeUnit &f :
- m.nestedFunctions)
- declareFunction(f);
- },
- [&](Fortran::lower::pft::BlockDataUnit &b) {
- if (!globalOmpRequiresSymbol)
- globalOmpRequiresSymbol = b.symTab.symbol();
- },
- [&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
- [&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
- },
- u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](Fortran::lower::pft::FunctionLikeUnit &f) {
+ if (f.isMainProgram())
+ hasMainProgram = true;
+ declareFunction(f);
+ if (!globalOmpRequiresSymbol)
+ globalOmpRequiresSymbol = f.getScope().symbol();
+ },
+ [&](Fortran::lower::pft::ModuleLikeUnit &m) {
+ lowerModuleDeclScope(m);
+ for (Fortran::lower::pft::ContainedUnit &unit :
+ m.containedUnitList)
+ if (auto *f =
+ std::get_if<Fortran::lower::pft::FunctionLikeUnit>(
+ &unit))
+ declareFunction(*f);
+ },
+ [&](Fortran::lower::pft::BlockDataUnit &b) {
+ if (!globalOmpRequiresSymbol)
+ globalOmpRequiresSymbol = b.symTab.symbol();
+ },
+ [&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
+ [&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
+ },
+ u);
}
// Create definitions of intrinsic module constants.
@@ -329,7 +336,7 @@ public:
// Primary translation pass.
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](Fortran::lower::pft::FunctionLikeUnit &f) { lowerFunc(f); },
[&](Fortran::lower::pft::ModuleLikeUnit &m) { lowerMod(m); },
@@ -384,13 +391,15 @@ public:
// Compute the set of host associated entities from the nested functions.
llvm::SetVector<const Fortran::semantics::Symbol *> escapeHost;
- for (Fortran::lower::pft::FunctionLikeUnit &f : funit.nestedFunctions)
- collectHostAssociatedVariables(f, escapeHost);
+ for (Fortran::lower::pft::ContainedUnit &unit : funit.containedUnitList)
+ if (auto *f = std::get_if<Fortran::lower::pft::FunctionLikeUnit>(&unit))
+ collectHostAssociatedVariables(*f, escapeHost);
funit.setHostAssociatedSymbols(escapeHost);
// Declare internal procedures
- for (Fortran::lower::pft::FunctionLikeUnit &f : funit.nestedFunctions)
- declareFunction(f);
+ for (Fortran::lower::pft::ContainedUnit &unit : funit.containedUnitList)
+ if (auto *f = std::get_if<Fortran::lower::pft::FunctionLikeUnit>(&unit))
+ declareFunction(*f);
}
/// Get the scope that is defining or using \p sym. The returned scope is not
@@ -748,10 +757,16 @@ public:
});
}
- void copyVar(mlir::Location loc, mlir::Value dst,
- mlir::Value src) override final {
+ void copyVar(mlir::Location loc, mlir::Value dst, mlir::Value src,
+ fir::FortranVariableFlagsEnum attrs) override final {
+ bool isAllocatable =
+ bitEnumContainsAny(attrs, fir::FortranVariableFlagsEnum::allocatable);
+ bool isPointer =
+ bitEnumContainsAny(attrs, fir::FortranVariableFlagsEnum::pointer);
+
copyVarHLFIR(loc, Fortran::lower::SymbolBox::Intrinsic{dst},
- Fortran::lower::SymbolBox::Intrinsic{src});
+ Fortran::lower::SymbolBox::Intrinsic{src}, isAllocatable,
+ isPointer);
}
void copyHostAssociateVar(
@@ -1080,6 +1095,28 @@ private:
void copyVarHLFIR(mlir::Location loc, Fortran::lower::SymbolBox dst,
Fortran::lower::SymbolBox src) {
assert(lowerToHighLevelFIR());
+
+ bool isBoxAllocatable = dst.match(
+ [](const fir::MutableBoxValue &box) { return box.isAllocatable(); },
+ [](const fir::FortranVariableOpInterface &box) {
+ return fir::FortranVariableOpInterface(box).isAllocatable();
+ },
+ [](const auto &box) { return false; });
+
+ bool isBoxPointer = dst.match(
+ [](const fir::MutableBoxValue &box) { return box.isPointer(); },
+ [](const fir::FortranVariableOpInterface &box) {
+ return fir::FortranVariableOpInterface(box).isPointer();
+ },
+ [](const auto &box) { return false; });
+
+ copyVarHLFIR(loc, dst, src, isBoxAllocatable, isBoxPointer);
+ }
+
+ void copyVarHLFIR(mlir::Location loc, Fortran::lower::SymbolBox dst,
+ Fortran::lower::SymbolBox src, bool isAllocatable,
+ bool isPointer) {
+ assert(lowerToHighLevelFIR());
hlfir::Entity lhs{dst.getAddr()};
hlfir::Entity rhs{src.getAddr()};
// Temporary_lhs is set to true in hlfir.assign below to avoid user
@@ -1096,21 +1133,7 @@ private:
/*temporary_lhs=*/true);
};
- bool isBoxAllocatable = dst.match(
- [](const fir::MutableBoxValue &box) { return box.isAllocatable(); },
- [](const fir::FortranVariableOpInterface &box) {
- return fir::FortranVariableOpInterface(box).isAllocatable();
- },
- [](const auto &box) { return false; });
-
- bool isBoxPointer = dst.match(
- [](const fir::MutableBoxValue &box) { return box.isPointer(); },
- [](const fir::FortranVariableOpInterface &box) {
- return fir::FortranVariableOpInterface(box).isPointer();
- },
- [](const auto &box) { return false; });
-
- if (isBoxAllocatable) {
+ if (isAllocatable) {
// Deep copy allocatable if it is allocated.
// Note that when allocated, the RHS is already allocated with the LHS
// shape for copy on entry in createHostAssociateVarClone.
@@ -1125,7 +1148,7 @@ private:
copyData(lhs, rhs);
})
.end();
- } else if (isBoxPointer) {
+ } else if (isPointer) {
// Set LHS target to the target of RHS (do not copy the RHS
// target data into the LHS target storage).
auto loadVal = builder->create<fir::LoadOp>(loc, rhs);
@@ -1741,6 +1764,35 @@ private:
builder->create<fir::UnreachableOp>(loc);
}
+ fir::ReduceOperationEnum
+ getReduceOperationEnum(const Fortran::parser::ReductionOperator &rOpr) {
+ switch (rOpr.v) {
+ case Fortran::parser::ReductionOperator::Operator::Plus:
+ return fir::ReduceOperationEnum::Add;
+ case Fortran::parser::ReductionOperator::Operator::Multiply:
+ return fir::ReduceOperationEnum::Multiply;
+ case Fortran::parser::ReductionOperator::Operator::And:
+ return fir::ReduceOperationEnum::AND;
+ case Fortran::parser::ReductionOperator::Operator::Or:
+ return fir::ReduceOperationEnum::OR;
+ case Fortran::parser::ReductionOperator::Operator::Eqv:
+ return fir::ReduceOperationEnum::EQV;
+ case Fortran::parser::ReductionOperator::Operator::Neqv:
+ return fir::ReduceOperationEnum::NEQV;
+ case Fortran::parser::ReductionOperator::Operator::Max:
+ return fir::ReduceOperationEnum::MAX;
+ case Fortran::parser::ReductionOperator::Operator::Min:
+ return fir::ReduceOperationEnum::MIN;
+ case Fortran::parser::ReductionOperator::Operator::Iand:
+ return fir::ReduceOperationEnum::IAND;
+ case Fortran::parser::ReductionOperator::Operator::Ior:
+ return fir::ReduceOperationEnum::IOR;
+ case Fortran::parser::ReductionOperator::Operator::Ieor:
+ return fir::ReduceOperationEnum::EIOR;
+ }
+ llvm_unreachable("illegal reduction operator");
+ }
+
/// Collect DO CONCURRENT or FORALL loop control information.
IncrementLoopNestInfo getConcurrentControl(
const Fortran::parser::ConcurrentHeader &header,
@@ -1763,6 +1815,18 @@ private:
std::get_if<Fortran::parser::LocalitySpec::LocalInit>(&x.u))
for (const Fortran::parser::Name &x : localInitList->v)
info.localInitSymList.push_back(x.symbol);
+ for (IncrementLoopInfo &info : incrementLoopNestInfo) {
+ if (const auto *reduceList =
+ std::get_if<Fortran::parser::LocalitySpec::Reduce>(&x.u)) {
+ fir::ReduceOperationEnum reduce_operation = getReduceOperationEnum(
+ std::get<Fortran::parser::ReductionOperator>(reduceList->t));
+ for (const Fortran::parser::Name &x :
+ std::get<std::list<Fortran::parser::Name>>(reduceList->t)) {
+ info.reduceSymList.push_back(
+ std::make_pair(reduce_operation, x.symbol));
+ }
+ }
+ }
if (const auto *sharedList =
std::get_if<Fortran::parser::LocalitySpec::Shared>(&x.u))
for (const Fortran::parser::Name &x : sharedList->v)
@@ -1887,7 +1951,7 @@ private:
// Increment loop begin code. (Infinite/while code was already generated.)
if (!infiniteLoop && !whileCondition)
- genFIRIncrementLoopBegin(incrementLoopNestInfo);
+ genFIRIncrementLoopBegin(incrementLoopNestInfo, doStmtEval.dirs);
// Loop body code.
auto iter = eval.getNestedEvaluations().begin();
@@ -1932,8 +1996,20 @@ private:
return builder->createIntegerConstant(loc, controlType, 1); // step
}
+ void addLoopAnnotationAttr(IncrementLoopInfo &info) {
+ mlir::BoolAttr f = mlir::BoolAttr::get(builder->getContext(), false);
+ mlir::LLVM::LoopVectorizeAttr va = mlir::LLVM::LoopVectorizeAttr::get(
+ builder->getContext(), /*disable=*/f, {}, {}, {}, {}, {}, {});
+ mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
+ builder->getContext(), {}, /*vectorize=*/va, {}, {}, {}, {}, {}, {}, {},
+ {}, {}, {}, {}, {}, {});
+ info.doLoop.setLoopAnnotationAttr(la);
+ }
+
/// Generate FIR to begin a structured or unstructured increment loop nest.
- void genFIRIncrementLoopBegin(IncrementLoopNestInfo &incrementLoopNestInfo) {
+ void genFIRIncrementLoopBegin(
+ IncrementLoopNestInfo &incrementLoopNestInfo,
+ llvm::SmallVectorImpl<const Fortran::parser::CompilerDirective *> &dirs) {
assert(!incrementLoopNestInfo.empty() && "empty loop nest");
mlir::Location loc = toLocation();
for (IncrementLoopInfo &info : incrementLoopNestInfo) {
@@ -1955,9 +2031,23 @@ private:
mlir::Type loopVarType = info.getLoopVariableType();
mlir::Value loopValue;
if (info.isUnordered) {
+ llvm::SmallVector<mlir::Value> reduceOperands;
+ llvm::SmallVector<mlir::Attribute> reduceAttrs;
+ // Create DO CONCURRENT reduce operands and attributes
+ for (const auto &reduceSym : info.reduceSymList) {
+ const fir::ReduceOperationEnum reduce_operation = reduceSym.first;
+ const Fortran::semantics::Symbol *sym = reduceSym.second;
+ fir::ExtendedValue exv = getSymbolExtendedValue(*sym, nullptr);
+ reduceOperands.push_back(fir::getBase(exv));
+ auto reduce_attr =
+ fir::ReduceAttr::get(builder->getContext(), reduce_operation);
+ reduceAttrs.push_back(reduce_attr);
+ }
// The loop variable value is explicitly updated.
info.doLoop = builder->create<fir::DoLoopOp>(
- loc, lowerValue, upperValue, stepValue, /*unordered=*/true);
+ loc, lowerValue, upperValue, stepValue, /*unordered=*/true,
+ /*finalCountValue=*/false, /*iterArgs=*/std::nullopt,
+ llvm::ArrayRef<mlir::Value>(reduceOperands), reduceAttrs);
builder->setInsertionPointToStart(info.doLoop.getBody());
loopValue = builder->createConvert(loc, loopVarType,
info.doLoop.getInductionVar());
@@ -1984,6 +2074,15 @@ private:
}
if (info.hasLocalitySpecs())
handleLocalitySpecs(info);
+
+ for (const auto *dir : dirs) {
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::CompilerDirective::VectorAlways
+ &d) { addLoopAnnotationAttr(info); },
+ [&](const auto &) {}},
+ dir->u);
+ }
continue;
}
@@ -2348,7 +2447,7 @@ private:
}
void genFIR(const Fortran::parser::ForallAssignmentStmt &stmt) {
- std::visit([&](const auto &x) { genFIR(x); }, stmt.u);
+ Fortran::common::visit([&](const auto &x) { genFIR(x); }, stmt.u);
}
void genFIR(const Fortran::parser::EndForallStmt &) {
@@ -2409,7 +2508,7 @@ private:
forall.t));
for (const Fortran::parser::ForallBodyConstruct &s :
std::get<std::list<Fortran::parser::ForallBodyConstruct>>(forall.t)) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::WhereConstruct &b) { genFIR(b); },
[&](const Fortran::common::Indirection<
@@ -2517,8 +2616,25 @@ private:
}
}
- void genFIR(const Fortran::parser::CompilerDirective &) {
- // TODO
+ void attachDirectiveToLoop(const Fortran::parser::CompilerDirective &dir,
+ Fortran::lower::pft::Evaluation *e) {
+ while (e->isDirective())
+ e = e->lexicalSuccessor;
+
+ if (e->isA<Fortran::parser::NonLabelDoStmt>())
+ e->dirs.push_back(&dir);
+ }
+
+ void genFIR(const Fortran::parser::CompilerDirective &dir) {
+ Fortran::lower::pft::Evaluation &eval = getEval();
+
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::CompilerDirective::VectorAlways &) {
+ attachDirectiveToLoop(dir, &eval);
+ },
+ [&](const auto &) {}},
+ dir.u);
}
void genFIR(const Fortran::parser::OpenACCConstruct &acc) {
@@ -2613,6 +2729,35 @@ private:
std::get<2>(dir.t);
const std::optional<Fortran::parser::ScalarIntExpr> &stream =
std::get<3>(dir.t);
+ const std::list<Fortran::parser::CUFReduction> &cufreds =
+ std::get<4>(dir.t);
+
+ llvm::SmallVector<mlir::Value> reduceOperands;
+ llvm::SmallVector<mlir::Attribute> reduceAttrs;
+
+ for (const Fortran::parser::CUFReduction &cufred : cufreds) {
+ fir::ReduceOperationEnum redOpEnum = getReduceOperationEnum(
+ std::get<Fortran::parser::ReductionOperator>(cufred.t));
+ const std::list<Fortran::parser::Scalar<Fortran::parser::Variable>>
+ &scalarvars = std::get<1>(cufred.t);
+ for (const Fortran::parser::Scalar<Fortran::parser::Variable> &scalarvar :
+ scalarvars) {
+ auto reduce_attr =
+ fir::ReduceAttr::get(builder->getContext(), redOpEnum);
+ reduceAttrs.push_back(reduce_attr);
+ const Fortran::parser::Variable &var = scalarvar.thing;
+ if (const auto *iDesignator = std::get_if<
+ Fortran::common::Indirection<Fortran::parser::Designator>>(
+ &var.u)) {
+ const Fortran::parser::Designator &designator = iDesignator->value();
+ if (const auto *name =
+ Fortran::semantics::getDesignatorNameIfDataRef(designator)) {
+ auto val = getSymbolAddress(*name->symbol);
+ reduceOperands.push_back(val);
+ }
+ }
+ }
+ }
auto isOnlyStars =
[&](const std::list<Fortran::parser::CUFKernelDoConstruct::StarOrExpr>
@@ -2715,8 +2860,9 @@ private:
loopEval = &*std::next(loopEval->getNestedEvaluations().begin());
}
- auto op = builder->create<cuf::KernelOp>(loc, gridValues, blockValues,
- streamValue, lbs, ubs, steps, n);
+ auto op = builder->create<cuf::KernelOp>(
+ loc, gridValues, blockValues, streamValue, lbs, ubs, steps, n,
+ mlir::ValueRange(reduceOperands), builder->getArrayAttr(reduceAttrs));
builder->createBlock(&op.getRegion(), op.getRegion().end(), ivTypes,
ivLocs);
mlir::Block &b = op.getRegion().back();
@@ -3063,7 +3209,7 @@ private:
const auto &rank = std::get<Fortran::parser::SelectRankCaseStmt::Rank>(
rankCaseStmt->t);
assert(e->block && "missing SelectRankCaseStmt block");
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::ScalarIntConstantExpr &rankExpr) {
blockList.emplace_back(e->block);
@@ -3094,9 +3240,9 @@ private:
"selector should not yet be set");
Fortran::lower::StatementContext &stmtCtx =
activeConstructStack.back().stmtCtx;
- const Fortran::lower::SomeExpr *selectorExpr =
- std::visit([](const auto &x) { return Fortran::semantics::GetExpr(x); },
- std::get<Fortran::parser::Selector>(selectRankStmt.t).u);
+ const Fortran::lower::SomeExpr *selectorExpr = Fortran::common::visit(
+ [](const auto &x) { return Fortran::semantics::GetExpr(x); },
+ std::get<Fortran::parser::Selector>(selectRankStmt.t).u);
assert(selectorExpr && "failed to retrieve selector expr");
hlfir::Entity selector = Fortran::lower::convertExprToHLFIR(
loc, *this, *selectorExpr, localSymbols, stmtCtx);
@@ -3528,7 +3674,7 @@ private:
Fortran::parser::Label errLabel{};
bool hasIostat{};
for (const auto &spec : specList) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::EndLabel &label) {
endLabel = label.v;
@@ -3975,8 +4121,8 @@ private:
void genCUDADataTransfer(fir::FirOpBuilder &builder, mlir::Location loc,
const Fortran::evaluate::Assignment &assign,
hlfir::Entity &lhs, hlfir::Entity &rhs) {
- bool lhsIsDevice = Fortran::evaluate::HasCUDAAttrs(assign.lhs);
- bool rhsIsDevice = Fortran::evaluate::HasCUDAAttrs(assign.rhs);
+ bool lhsIsDevice = Fortran::evaluate::HasCUDADeviceAttrs(assign.lhs);
+ bool rhsIsDevice = Fortran::evaluate::HasCUDADeviceAttrs(assign.rhs);
auto getRefIfLoaded = [](mlir::Value val) -> mlir::Value {
if (auto loadOp =
@@ -4045,7 +4191,8 @@ private:
if (const auto *details =
sym.GetUltimate()
.detailsIf<Fortran::semantics::ObjectEntityDetails>()) {
- if (details->cudaDataAttr()) {
+ if (details->cudaDataAttr() &&
+ *details->cudaDataAttr() != Fortran::common::CUDADataAttr::Pinned) {
if (sym.owner().IsDerivedType() && IsAllocatable(sym.GetUltimate()))
TODO(loc, "Device resident allocatable derived-type component");
// TODO: This should probably being checked in semantic and give a
@@ -4097,8 +4244,8 @@ private:
fir::FirOpBuilder &builder = getFirOpBuilder();
bool isInDeviceContext = isDeviceContext(builder);
- bool isCUDATransfer = (Fortran::evaluate::HasCUDAAttrs(assign.lhs) ||
- Fortran::evaluate::HasCUDAAttrs(assign.rhs)) &&
+ bool isCUDATransfer = (Fortran::evaluate::HasCUDADeviceAttrs(assign.lhs) ||
+ Fortran::evaluate::HasCUDADeviceAttrs(assign.rhs)) &&
!isInDeviceContext;
bool hasCUDAImplicitTransfer =
Fortran::evaluate::HasCUDAImplicitTransfer(assign.rhs);
@@ -4238,7 +4385,7 @@ private:
void genAssignment(const Fortran::evaluate::Assignment &assign) {
mlir::Location loc = toLocation();
if (lowerToHighLevelFIR()) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::Assignment::Intrinsic &) {
genDataAssignment(assign, /*userDefinedAssignment=*/nullptr);
@@ -4266,7 +4413,7 @@ private:
explicitIterSpace.genLoopNest();
}
Fortran::lower::StatementContext stmtCtx;
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
// [1] Plain old assignment.
[&](const Fortran::evaluate::Assignment::Intrinsic &) {
@@ -4535,7 +4682,7 @@ private:
}
}
void genFIR(const Fortran::parser::WhereBodyConstruct &body) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::Statement<
Fortran::parser::AssignmentStmt> &stmt) {
@@ -5251,18 +5398,19 @@ private:
// The intrinsic module scope, if present, is the first scope.
const Fortran::semantics::Scope *intrinsicModuleScope = nullptr;
for (Fortran::lower::pft::Program::Units &u : pft.getUnits()) {
- std::visit(Fortran::common::visitors{
- [&](Fortran::lower::pft::FunctionLikeUnit &f) {
- intrinsicModuleScope = &f.getScope().parent();
- },
- [&](Fortran::lower::pft::ModuleLikeUnit &m) {
- intrinsicModuleScope = &m.getScope().parent();
- },
- [&](Fortran::lower::pft::BlockDataUnit &b) {},
- [&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
- [&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
- },
- u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](Fortran::lower::pft::FunctionLikeUnit &f) {
+ intrinsicModuleScope = &f.getScope().parent();
+ },
+ [&](Fortran::lower::pft::ModuleLikeUnit &m) {
+ intrinsicModuleScope = &m.getScope().parent();
+ },
+ [&](Fortran::lower::pft::BlockDataUnit &b) {},
+ [&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
+ [&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
+ },
+ u);
if (intrinsicModuleScope) {
while (!intrinsicModuleScope->IsGlobal())
intrinsicModuleScope = &intrinsicModuleScope->parent();
@@ -5300,8 +5448,9 @@ private:
endNewFunction(funit);
}
funit.setActiveEntry(0);
- for (Fortran::lower::pft::FunctionLikeUnit &f : funit.nestedFunctions)
- lowerFunc(f); // internal procedure
+ for (Fortran::lower::pft::ContainedUnit &unit : funit.containedUnitList)
+ if (auto *f = std::get_if<Fortran::lower::pft::FunctionLikeUnit>(&unit))
+ lowerFunc(*f); // internal procedure
}
/// Lower module variable definitions to fir::globalOp and OpenMP/OpenACC
@@ -5325,8 +5474,9 @@ private:
/// Lower functions contained in a module.
void lowerMod(Fortran::lower::pft::ModuleLikeUnit &mod) {
- for (Fortran::lower::pft::FunctionLikeUnit &f : mod.nestedFunctions)
- lowerFunc(f);
+ for (Fortran::lower::pft::ContainedUnit &unit : mod.containedUnitList)
+ if (auto *f = std::get_if<Fortran::lower::pft::FunctionLikeUnit>(&unit))
+ lowerFunc(*f);
}
void setCurrentPosition(const Fortran::parser::CharBlock &position) {
@@ -5394,7 +5544,7 @@ private:
analyzeExplicitSpace</*LHS=*/true>(lhs);
analyzeExplicitSpace(rhs);
};
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::ProcedureRef &procRef) {
// Ensure the procRef expressions are the one being visited.
@@ -5412,7 +5562,8 @@ private:
explicitIterSpace.endAssign();
}
void analyzeExplicitSpace(const Fortran::parser::ForallAssignmentStmt &stmt) {
- std::visit([&](const auto &s) { analyzeExplicitSpace(s); }, stmt.u);
+ Fortran::common::visit([&](const auto &s) { analyzeExplicitSpace(s); },
+ stmt.u);
}
void analyzeExplicitSpace(const Fortran::parser::AssignmentStmt &s) {
analyzeExplicitSpace(s.typedAssignment->v.operator->());
@@ -5457,13 +5608,14 @@ private:
analyzeExplicitSpace(e);
}
void analyzeExplicitSpace(const Fortran::parser::WhereBodyConstruct &body) {
- std::visit(Fortran::common::visitors{
- [&](const Fortran::common::Indirection<
- Fortran::parser::WhereConstruct> &wc) {
- analyzeExplicitSpace(wc.value());
- },
- [&](const auto &s) { analyzeExplicitSpace(s.statement); }},
- body.u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::common::Indirection<
+ Fortran::parser::WhereConstruct> &wc) {
+ analyzeExplicitSpace(wc.value());
+ },
+ [&](const auto &s) { analyzeExplicitSpace(s.statement); }},
+ body.u);
}
void analyzeExplicitSpace(const Fortran::parser::MaskedElsewhereStmt &stmt) {
const Fortran::lower::SomeExpr *exp = Fortran::semantics::GetExpr(
@@ -5514,16 +5666,17 @@ private:
.statement);
for (const Fortran::parser::ForallBodyConstruct &s :
std::get<std::list<Fortran::parser::ForallBodyConstruct>>(forall.t)) {
- std::visit(Fortran::common::visitors{
- [&](const Fortran::common::Indirection<
- Fortran::parser::ForallConstruct> &b) {
- analyzeExplicitSpace(b.value());
- },
- [&](const Fortran::parser::WhereConstruct &w) {
- analyzeExplicitSpace(w);
- },
- [&](const auto &b) { analyzeExplicitSpace(b.statement); }},
- s.u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::common::Indirection<
+ Fortran::parser::ForallConstruct> &b) {
+ analyzeExplicitSpace(b.value());
+ },
+ [&](const Fortran::parser::WhereConstruct &w) {
+ analyzeExplicitSpace(w);
+ },
+ [&](const auto &b) { analyzeExplicitSpace(b.statement); }},
+ s.u);
}
analyzeExplicitSpacePop();
}
@@ -5578,7 +5731,7 @@ private:
std::string getConstantExprManglePrefix(mlir::Location loc,
const Fortran::lower::SomeExpr &expr,
mlir::Type eleTy) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> std::string {
using T = std::decay_t<decltype(x)>;
if constexpr (Fortran::common::HasMember<
@@ -5593,7 +5746,7 @@ private:
fir::emitFatalError(loc,
"non a constant derived type expression");
} else {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &someKind) -> std::string {
using T = std::decay_t<decltype(someKind)>;
using TK = Fortran::evaluate::Type<T::Result::category,
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index cfbb7c7f6b4f..c0ef96adc20c 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -177,9 +177,10 @@ mlir::Location Fortran::lower::CallerInterface::getCalleeLocation() const {
// explicit.
static Fortran::evaluate::characteristics::DummyDataObject
asImplicitArg(Fortran::evaluate::characteristics::DummyDataObject &&dummy) {
- Fortran::evaluate::Shape shape =
- dummy.type.attrs().none() ? dummy.type.shape()
- : Fortran::evaluate::Shape(dummy.type.Rank());
+ std::optional<Fortran::evaluate::Shape> shape =
+ dummy.type.attrs().none()
+ ? dummy.type.shape()
+ : std::make_optional<Fortran::evaluate::Shape>(dummy.type.Rank());
return Fortran::evaluate::characteristics::DummyDataObject(
Fortran::evaluate::characteristics::TypeAndShape(dummy.type.type(),
std::move(shape)));
@@ -187,7 +188,7 @@ asImplicitArg(Fortran::evaluate::characteristics::DummyDataObject &&dummy) {
static Fortran::evaluate::characteristics::DummyArgument
asImplicitArg(Fortran::evaluate::characteristics::DummyArgument &&dummy) {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[&](Fortran::evaluate::characteristics::DummyDataObject &obj) {
return Fortran::evaluate::characteristics::DummyArgument(
@@ -610,6 +611,17 @@ static void addSymbolAttribute(mlir::func::FuncOp func,
}
}
+ // Set procedure attributes to the func op.
+ if (IsPureProcedure(sym))
+ func->setAttr(fir::getFuncPureAttrName(),
+ mlir::UnitAttr::get(&mlirContext));
+ if (IsElementalProcedure(sym))
+ func->setAttr(fir::getFuncElementalAttrName(),
+ mlir::UnitAttr::get(&mlirContext));
+ if (sym.attrs().test(Fortran::semantics::Attr::RECURSIVE))
+ func->setAttr(fir::getFuncRecursiveAttrName(),
+ mlir::UnitAttr::get(&mlirContext));
+
// Only add this on bind(C) functions for which the symbol is not reflected in
// the current context.
if (!Fortran::semantics::IsBindCProcedure(sym))
@@ -832,7 +844,7 @@ public:
for (auto pair : llvm::zip(procedure.dummyArguments, argumentEntities)) {
const Fortran::evaluate::characteristics::DummyArgument
&argCharacteristics = std::get<0>(pair);
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const auto &dummy) {
const auto &entity = getDataObjectEntity(std::get<1>(pair));
@@ -866,7 +878,7 @@ public:
for (auto pair : llvm::zip(procedure.dummyArguments, argumentEntities)) {
const Fortran::evaluate::characteristics::DummyArgument
&argCharacteristics = std::get<0>(pair);
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::characteristics::DummyDataObject
&dummy) {
@@ -1297,18 +1309,17 @@ private:
// with the shape (may contain unknown extents) for arrays.
std::optional<fir::SequenceType::Shape> getBounds(
const Fortran::evaluate::characteristics::TypeAndShape &typeAndShape) {
- using ShapeAttr = Fortran::evaluate::characteristics::TypeAndShape::Attr;
- if (typeAndShape.shape().empty() &&
- !typeAndShape.attrs().test(ShapeAttr::AssumedRank))
+ if (typeAndShape.shape() && typeAndShape.shape()->empty())
return std::nullopt;
fir::SequenceType::Shape bounds;
- for (const std::optional<Fortran::evaluate::ExtentExpr> &extent :
- typeAndShape.shape()) {
- fir::SequenceType::Extent bound = fir::SequenceType::getUnknownExtent();
- if (std::optional<std::int64_t> i = toInt64(extent))
- bound = *i;
- bounds.emplace_back(bound);
- }
+ if (typeAndShape.shape())
+ for (const std::optional<Fortran::evaluate::ExtentExpr> &extent :
+ *typeAndShape.shape()) {
+ fir::SequenceType::Extent bound = fir::SequenceType::getUnknownExtent();
+ if (std::optional<std::int64_t> i = toInt64(extent))
+ bound = *i;
+ bounds.emplace_back(bound);
+ }
return bounds;
}
std::optional<std::int64_t>
diff --git a/flang/lib/Lower/ComponentPath.cpp b/flang/lib/Lower/ComponentPath.cpp
index d20ea2315310..5bdbca6062e6 100644
--- a/flang/lib/Lower/ComponentPath.cpp
+++ b/flang/lib/Lower/ComponentPath.cpp
@@ -36,7 +36,7 @@ void Fortran::lower::ComponentPath::clear() {
bool Fortran::lower::isRankedArrayAccess(const Fortran::evaluate::ArrayRef &x) {
for (const Fortran::evaluate::Subscript &sub : x.subscript()) {
- if (std::visit(
+ if (Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::Triplet &) { return true; },
[&](const Fortran::evaluate::IndirectSubscriptIntegerExpr &e) {
diff --git a/flang/lib/Lower/ConvertArrayConstructor.cpp b/flang/lib/Lower/ConvertArrayConstructor.cpp
index 341fad9a5e43..3c43cd20eb08 100644
--- a/flang/lib/Lower/ConvertArrayConstructor.cpp
+++ b/flang/lib/Lower/ConvertArrayConstructor.cpp
@@ -438,7 +438,7 @@ public:
void pushValue(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity value) {
- return std::visit(
+ return Fortran::common::visit(
[&](auto &impl) { return impl.pushValue(loc, builder, value); },
implVariant);
}
@@ -446,7 +446,7 @@ public:
mlir::Value startImpliedDo(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value lower, mlir::Value upper,
mlir::Value stride) {
- return std::visit(
+ return Fortran::common::visit(
[&](auto &impl) {
return impl.startImpliedDo(loc, builder, lower, upper, stride);
},
@@ -455,13 +455,13 @@ public:
hlfir::Entity finishArrayCtorLowering(mlir::Location loc,
fir::FirOpBuilder &builder) {
- return std::visit(
+ return Fortran::common::visit(
[&](auto &impl) { return impl.finishArrayCtorLowering(loc, builder); },
implVariant);
}
void startImpliedDoScope(llvm::StringRef doName, mlir::Value indexValue) {
- std::visit(
+ Fortran::common::visit(
[&](auto &impl) {
return impl.startImpliedDoScope(doName, indexValue);
},
@@ -469,8 +469,8 @@ public:
}
void endImpliedDoScope() {
- std::visit([&](auto &impl) { return impl.endImpliedDoScope(); },
- implVariant);
+ Fortran::common::visit([&](auto &impl) { return impl.endImpliedDoScope(); },
+ implVariant);
}
private:
@@ -612,16 +612,17 @@ ArrayCtorAnalysis::ArrayCtorAnalysis(
arrayValueListStack.pop_back_val();
for (const Fortran::evaluate::ArrayConstructorValue<T> &acValue :
*currentArrayValueList)
- std::visit(Fortran::common::visitors{
- [&](const Fortran::evaluate::ImpliedDo<T> &impledDo) {
- arrayValueListStack.push_back(&impledDo.values());
- localNumberOfImpliedDo++;
- },
- [&](const Fortran::evaluate::Expr<T> &expr) {
- localNumberOfExpr++;
- anyArrayExpr = anyArrayExpr || expr.Rank() > 0;
- }},
- acValue.u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::evaluate::ImpliedDo<T> &impledDo) {
+ arrayValueListStack.push_back(&impledDo.values());
+ localNumberOfImpliedDo++;
+ },
+ [&](const Fortran::evaluate::Expr<T> &expr) {
+ localNumberOfExpr++;
+ anyArrayExpr = anyArrayExpr || expr.Rank() > 0;
+ }},
+ acValue.u);
anyImpliedDo = anyImpliedDo || localNumberOfImpliedDo > 0;
if (localNumberOfImpliedDo == 0) {
@@ -765,7 +766,7 @@ static void genAcValue(mlir::Location loc,
impliedDoIndexValue);
for (const auto &acValue : impledDo.values())
- std::visit(
+ Fortran::common::visit(
[&](const auto &x) {
genAcValue(loc, converter, x, symMap, stmtCtx, arrayBuilder);
},
@@ -787,7 +788,7 @@ hlfir::EntityWithAttributes Fortran::lower::ArrayConstructorBuilder<T>::gen(
loc, converter, arrayCtorExpr, symMap, stmtCtx);
// Run the array lowering strategy through the ac-values.
for (const auto &acValue : arrayCtorExpr)
- std::visit(
+ Fortran::common::visit(
[&](const auto &x) {
genAcValue(loc, converter, x, symMap, stmtCtx, arrayBuilder);
},
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 3bd199324957..5e20f9eee4fc 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -920,9 +920,11 @@ namespace {
struct CallCleanUp {
struct CopyIn {
void genCleanUp(mlir::Location loc, fir::FirOpBuilder &builder) {
- builder.create<hlfir::CopyOutOp>(loc, copiedIn, wasCopied, copyBackVar);
+ builder.create<hlfir::CopyOutOp>(loc, tempBox, wasCopied, copyBackVar);
}
- mlir::Value copiedIn;
+ // address of the descriptor holding the temp if a temp was created.
+ mlir::Value tempBox;
+ // Boolean indicating if a copy was made or not.
mlir::Value wasCopied;
// copyBackVar may be null if copy back is not needed.
mlir::Value copyBackVar;
@@ -935,7 +937,8 @@ struct CallCleanUp {
mlir::Value mustFree;
};
void genCleanUp(mlir::Location loc, fir::FirOpBuilder &builder) {
- std::visit([&](auto &c) { c.genCleanUp(loc, builder); }, cleanUp);
+ Fortran::common::visit([&](auto &c) { c.genCleanUp(loc, builder); },
+ cleanUp);
}
std::variant<CopyIn, ExprAssociate> cleanUp;
};
@@ -944,10 +947,10 @@ struct CallCleanUp {
/// It holds the value to be passed in the call and any related
/// clean-ups to be done after the call.
struct PreparedDummyArgument {
- void pushCopyInCleanUp(mlir::Value copiedIn, mlir::Value wasCopied,
+ void pushCopyInCleanUp(mlir::Value tempBox, mlir::Value wasCopied,
mlir::Value copyBackVar) {
cleanups.emplace_back(
- CallCleanUp{CallCleanUp::CopyIn{copiedIn, wasCopied, copyBackVar}});
+ CallCleanUp{CallCleanUp::CopyIn{tempBox, wasCopied, copyBackVar}});
}
void pushExprAssociateCleanUp(mlir::Value tempVar, mlir::Value wasCopied) {
cleanups.emplace_back(
@@ -986,7 +989,6 @@ struct ConditionallyPreparedDummy {
for (const CallCleanUp &c : preparedDummy.cleanups) {
if (const auto *copyInCleanUp =
std::get_if<CallCleanUp::CopyIn>(&c.cleanUp)) {
- thenResultValues.push_back(copyInCleanUp->copiedIn);
thenResultValues.push_back(copyInCleanUp->wasCopied);
if (copyInCleanUp->copyBackVar)
thenResultValues.push_back(copyInCleanUp->copyBackVar);
@@ -1041,8 +1043,10 @@ struct ConditionallyPreparedDummy {
mlir::Value copyBackVar;
if (copyInCleanUp->copyBackVar)
copyBackVar = ifOp.getResults().back();
- preparedDummy.pushCopyInCleanUp(ifOp.getResults()[1],
- ifOp.getResults()[2], copyBackVar);
+ // tempBox is an hlfir.copy_in argument created outside of the
+ // fir.if region. It needs not to be threaded as a fir.if result.
+ preparedDummy.pushCopyInCleanUp(copyInCleanUp->tempBox,
+ ifOp.getResults()[1], copyBackVar);
} else {
preparedDummy.pushExprAssociateCleanUp(ifOp.getResults()[1],
ifOp.getResults()[2]);
@@ -1085,11 +1089,8 @@ static hlfir::Entity fixProcedureDummyMismatch(mlir::Location loc,
mlir::Value static getZeroLowerBounds(mlir::Location loc,
fir::FirOpBuilder &builder,
hlfir::Entity entity) {
- // Assumed rank should not fall here, but better safe than sorry until
- // implemented.
- if (entity.isAssumedRank())
- TODO(loc, "setting lower bounds of assumed rank to zero before passing it "
- "to BIND(C) procedure");
+ assert(!entity.isAssumedRank() &&
+ "assumed-rank must use fir.rebox_assumed_rank");
if (entity.getRank() < 1)
return {};
mlir::Value zero =
@@ -1206,24 +1207,45 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
dummyTypeWithActualRank, actual.getFortranElementType(),
actual.isPolymorphic());
+ PreparedDummyArgument preparedDummy;
+
+ // Helpers to generate hlfir.copy_in operation and register the related
+ // hlfir.copy_out creation.
+ auto genCopyIn = [&](hlfir::Entity var, bool doCopyOut) -> hlfir::Entity {
+ auto baseBoxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType());
+ assert(baseBoxTy && "expect non simply contiguous variables to be boxes");
+ // Create allocatable descriptor for the potential temporary.
+ mlir::Type tempBoxType = baseBoxTy.getBoxTypeWithNewAttr(
+ fir::BaseBoxType::Attribute::Allocatable);
+ mlir::Value tempBox = builder.createTemporary(loc, tempBoxType);
+ auto copyIn = builder.create<hlfir::CopyInOp>(
+ loc, var, tempBox, /*var_is_present=*/mlir::Value{});
+ // Register the copy-out after the call.
+ preparedDummy.pushCopyInCleanUp(copyIn.getTempBox(), copyIn.getWasCopied(),
+ doCopyOut ? copyIn.getVar()
+ : mlir::Value{});
+ return hlfir::Entity{copyIn.getCopiedIn()};
+ };
+
// Step 2: prepare the storage for the dummy arguments, ensuring that it
// matches the dummy requirements (e.g., must be contiguous or must be
// a temporary).
- PreparedDummyArgument preparedDummy;
hlfir::Entity entity =
hlfir::derefPointersAndAllocatables(loc, builder, actual);
if (entity.isVariable()) {
if (mustSetDynamicTypeToDummyType) {
// Note: this is important to do this before any copy-in or copy so
// that the dummy is contiguous according to the dummy type.
- if (actualIsAssumedRank)
- TODO(loc, "passing polymorphic assumed-rank to non polymorphic dummy "
- "argument");
mlir::Type boxType = fir::BoxType::get(
hlfir::getFortranElementOrSequenceType(dummyTypeWithActualRank));
- entity = hlfir::Entity{builder.create<fir::ReboxOp>(
- loc, boxType, entity, /*shape=*/mlir::Value{},
- /*slice=*/mlir::Value{})};
+ if (actualIsAssumedRank) {
+ entity = hlfir::Entity{builder.create<fir::ReboxAssumedRankOp>(
+ loc, boxType, entity, fir::LowerBoundModifierAttribute::SetToOnes)};
+ } else {
+ entity = hlfir::Entity{builder.create<fir::ReboxOp>(
+ loc, boxType, entity, /*shape=*/mlir::Value{},
+ /*slice=*/mlir::Value{})};
+ }
}
if (arg.hasValueAttribute() ||
// Constant expressions might be lowered as variables with
@@ -1243,10 +1265,6 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
preparedDummy.pushExprAssociateCleanUp(associate);
} else if (mustDoCopyInOut) {
// Copy-in non contiguous variables.
- assert(mlir::isa<fir::BaseBoxType>(entity.getType()) &&
- "expect non simply contiguous variables to be boxes");
- if (actualIsAssumedRank)
- TODO(loc, "copy-in and copy-out of assumed-rank arguments");
// TODO: for non-finalizable monomorphic derived type actual
// arguments associated with INTENT(OUT) dummy arguments
// we may avoid doing the copy and only allocate the temporary.
@@ -1254,13 +1272,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
// allocation for the temp in this case. We can communicate
// this to the codegen via some CopyInOp flag.
// This is a performance concern.
- auto copyIn = builder.create<hlfir::CopyInOp>(
- loc, entity, /*var_is_present=*/mlir::Value{});
- entity = hlfir::Entity{copyIn.getCopiedIn()};
- // Register the copy-out after the call.
- preparedDummy.pushCopyInCleanUp(
- copyIn.getCopiedIn(), copyIn.getWasCopied(),
- arg.mayBeModifiedByCall() ? copyIn.getVar() : mlir::Value{});
+ entity = genCopyIn(entity, arg.mayBeModifiedByCall());
}
} else {
const Fortran::lower::SomeExpr *expr = arg.entity->UnwrapExpr();
@@ -1287,14 +1299,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
entity = hlfir::Entity{builder.create<fir::ReboxOp>(
loc, boxType, entity, /*shape=*/mlir::Value{},
/*slice=*/mlir::Value{})};
- auto copyIn = builder.create<hlfir::CopyInOp>(
- loc, entity, /*var_is_present=*/mlir::Value{});
- entity = hlfir::Entity{copyIn.getCopiedIn()};
- // Note that the copy-out is not required, but the copy-in
- // temporary must be deallocated if created.
- preparedDummy.pushCopyInCleanUp(copyIn.getCopiedIn(),
- copyIn.getWasCopied(),
- /*copyBackVar=*/mlir::Value{});
+ entity = genCopyIn(entity, /*doCopyOut=*/false);
}
}
@@ -1330,19 +1335,19 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
if (needToAddAddendum || actualBoxHasAllocatableOrPointerFlag ||
needsZeroLowerBounds) {
if (actualIsAssumedRank) {
- if (needToAddAddendum)
- TODO(loc, "passing intrinsic assumed-rank to unlimited polymorphic "
- "assumed-rank");
- else
- TODO(loc, "passing pointer or allocatable assumed-rank to non "
- "pointer non allocatable assumed-rank");
+ auto lbModifier = needsZeroLowerBounds
+ ? fir::LowerBoundModifierAttribute::SetToZeroes
+ : fir::LowerBoundModifierAttribute::SetToOnes;
+ entity = hlfir::Entity{builder.create<fir::ReboxAssumedRankOp>(
+ loc, dummyTypeWithActualRank, entity, lbModifier)};
+ } else {
+ mlir::Value shift{};
+ if (needsZeroLowerBounds)
+ shift = getZeroLowerBounds(loc, builder, entity);
+ entity = hlfir::Entity{builder.create<fir::ReboxOp>(
+ loc, dummyTypeWithActualRank, entity, /*shape=*/shift,
+ /*slice=*/mlir::Value{})};
}
- mlir::Value shift{};
- if (needsZeroLowerBounds)
- shift = getZeroLowerBounds(loc, builder, entity);
- entity = hlfir::Entity{builder.create<fir::ReboxOp>(
- loc, dummyTypeWithActualRank, entity, /*shape=*/shift,
- /*slice=*/mlir::Value{})};
}
addr = entity;
} else {
@@ -1592,9 +1597,6 @@ void prepareUserCallArguments(
if (dataTy.isAssumedRank()) {
dataTy =
dataTy.getBoxTypeWithNewShape(fir::getBase(actualExv).getType());
- if (dataTy.isAssumedRank())
- TODO(loc, "associating assumed-rank target to pointer assumed-rank "
- "argument");
}
mlir::Value irBox = builder.createTemporary(loc, dataTy);
fir::MutableBoxValue ptrBox(irBox,
diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp
index 653e874a969c..3361817ee27e 100644
--- a/flang/lib/Lower/ConvertConstant.cpp
+++ b/flang/lib/Lower/ConvertConstant.cpp
@@ -102,9 +102,10 @@ public:
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
mlir::StringAttr linkage, bool isConst,
- const Fortran::lower::SomeExpr &initExpr) {
+ const Fortran::lower::SomeExpr &initExpr,
+ cuf::DataAttributeAttr dataAttr) {
DenseGlobalBuilder globalBuilder;
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::Expr<Fortran::evaluate::SomeLogical> &
x) { globalBuilder.tryConvertingToAttributes(builder, x); },
@@ -119,7 +120,7 @@ public:
},
initExpr.u);
return globalBuilder.tryCreatingGlobal(builder, loc, symTy, globalName,
- linkage, isConst);
+ linkage, isConst, dataAttr);
}
template <Fortran::common::TypeCategory TC, int KIND>
@@ -127,11 +128,12 @@ public:
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName, mlir::StringAttr linkage, bool isConst,
const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>>
- &constant) {
+ &constant,
+ cuf::DataAttributeAttr dataAttr) {
DenseGlobalBuilder globalBuilder;
globalBuilder.tryConvertingToAttributes(builder, constant);
return globalBuilder.tryCreatingGlobal(builder, loc, symTy, globalName,
- linkage, isConst);
+ linkage, isConst, dataAttr);
}
private:
@@ -162,7 +164,7 @@ private:
template <typename SomeCat>
void tryConvertingToAttributes(fir::FirOpBuilder &builder,
const Fortran::evaluate::Expr<SomeCat> &expr) {
- std::visit(
+ Fortran::common::visit(
[&](const auto &x) {
using TR = Fortran::evaluate::ResultType<decltype(x)>;
if (const auto *constant =
@@ -178,8 +180,8 @@ private:
fir::GlobalOp tryCreatingGlobal(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
- mlir::StringAttr linkage,
- bool isConst) const {
+ mlir::StringAttr linkage, bool isConst,
+ cuf::DataAttributeAttr dataAttr) const {
// Not a "trivial" intrinsic constant array, or empty array.
if (!attributeElementType || attributes.empty())
return {};
@@ -191,7 +193,8 @@ private:
auto tensorTy =
mlir::RankedTensorType::get(tensorShape, attributeElementType);
auto init = mlir::DenseElementsAttr::get(tensorTy, attributes);
- return builder.createGlobal(loc, symTy, globalName, linkage, init, isConst);
+ return builder.createGlobal(loc, symTy, globalName, linkage, init, isConst,
+ /*isTarget=*/false, dataAttr);
}
llvm::SmallVector<mlir::Attribute> attributes;
@@ -202,9 +205,9 @@ private:
fir::GlobalOp Fortran::lower::tryCreatingDenseGlobal(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName, mlir::StringAttr linkage, bool isConst,
- const Fortran::lower::SomeExpr &initExpr) {
+ const Fortran::lower::SomeExpr &initExpr, cuf::DataAttributeAttr dataAttr) {
return DenseGlobalBuilder::tryCreating(builder, loc, symTy, globalName,
- linkage, isConst, initExpr);
+ linkage, isConst, initExpr, dataAttr);
}
//===----------------------------------------------------------------------===//
@@ -661,7 +664,7 @@ genOutlineArrayLit(Fortran::lower::AbstractConverter &converter,
T::category == Fortran::common::TypeCategory::Complex) {
global = DenseGlobalBuilder::tryCreating(
builder, loc, arrayTy, globalName, builder.createInternalLinkage(),
- true, constant);
+ true, constant, {});
}
if (!global)
// If the number of elements of the array is huge, the compilation may
@@ -793,7 +796,7 @@ static fir::ExtendedValue
genConstantValue(Fortran::lower::AbstractConverter &converter,
mlir::Location loc,
const Fortran::lower::SomeExpr &constantExpr) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> fir::ExtendedValue {
using T = std::decay_t<decltype(x)>;
if constexpr (Fortran::common::HasMember<
@@ -802,7 +805,7 @@ genConstantValue(Fortran::lower::AbstractConverter &converter,
Fortran::common::TypeCategory::Derived) {
return genConstantValue(converter, loc, x);
} else {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &preciseKind) {
return genConstantValue(converter, loc, preciseKind);
},
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 9567685aa3d2..44c3dc88edd3 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -398,8 +398,8 @@ static bool isParenthesizedVariable(const Fortran::evaluate::Expr<T> &expr) {
return Fortran::evaluate::IsVariable(parentheses->left());
return false;
} else {
- return std::visit([&](const auto &x) { return isParenthesizedVariable(x); },
- expr.u);
+ return Fortran::common::visit(
+ [&](const auto &x) { return isParenthesizedVariable(x); }, expr.u);
}
}
@@ -646,7 +646,7 @@ isOptimizableTranspose(Fortran::evaluate::Expr<T> expr,
if (!isTransposeOptEnabled(converter))
return false;
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &e) { return isOptimizableTranspose(e, converter); },
expr.u);
}
@@ -696,7 +696,7 @@ public:
// - result of NULL() or NULL(MOLD) intrinsic.
// NULL() requires some context to be lowered, so it is not handled
// here and must be lowered according to the context where it appears.
- ExtValue exv = std::visit(
+ ExtValue exv = Fortran::common::visit(
[&](const auto &x) { return genMutableBoxValueImpl(x); }, expr.u);
const fir::MutableBoxValue *mutableBox =
exv.getBoxOf<fir::MutableBoxValue>();
@@ -737,7 +737,7 @@ public:
template <typename T>
ExtValue
genMutableBoxValueImpl(const Fortran::evaluate::Designator<T> &designator) {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::SymbolRef &sym) -> ExtValue {
return converter.getSymbolExtendedValue(*sym, &symMap);
@@ -754,8 +754,8 @@ public:
template <typename T>
ExtValue genMutableBoxValueImpl(const Fortran::evaluate::Expr<T> &expr) {
- return std::visit([&](const auto &x) { return genMutableBoxValueImpl(x); },
- expr.u);
+ return Fortran::common::visit(
+ [&](const auto &x) { return genMutableBoxValueImpl(x); }, expr.u);
}
mlir::Location getLoc() { return location; }
@@ -1222,7 +1222,8 @@ public:
ExtValue
genval(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &op) {
- return std::visit([&](const auto &x) { return genval(x); }, op.u);
+ return Fortran::common::visit([&](const auto &x) { return genval(x); },
+ op.u);
}
template <Fortran::common::TypeCategory TC1, int KIND,
@@ -1341,7 +1342,7 @@ public:
/// Reference to a substring.
ExtValue gen(const Fortran::evaluate::Substring &s) {
// Get base string
- auto baseString = std::visit(
+ auto baseString = Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::DataRef &x) { return gen(x); },
[&](const Fortran::evaluate::StaticDataObject::Pointer &p)
@@ -1400,10 +1401,12 @@ public:
}
ExtValue gen(const Fortran::evaluate::DataRef &dref) {
- return std::visit([&](const auto &x) { return gen(x); }, dref.u);
+ return Fortran::common::visit([&](const auto &x) { return gen(x); },
+ dref.u);
}
ExtValue genval(const Fortran::evaluate::DataRef &dref) {
- return std::visit([&](const auto &x) { return genval(x); }, dref.u);
+ return Fortran::common::visit([&](const auto &x) { return genval(x); },
+ dref.u);
}
// Helper function to turn the Component structure into a list of nested
@@ -1418,7 +1421,7 @@ public:
std::list<const Fortran::evaluate::Component *> &list) {
if (!getLastSym(cmpt).test(Fortran::semantics::Symbol::Flag::ParentComp))
list.push_front(&cmpt);
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::Component &x) {
if (Fortran::semantics::IsAllocatableOrPointer(getLastSym(x)))
@@ -1713,11 +1716,12 @@ public:
template <typename A>
ExtValue gen(const Fortran::evaluate::Designator<A> &des) {
- return std::visit([&](const auto &x) { return gen(x); }, des.u);
+ return Fortran::common::visit([&](const auto &x) { return gen(x); }, des.u);
}
template <typename A>
ExtValue genval(const Fortran::evaluate::Designator<A> &des) {
- return std::visit([&](const auto &x) { return genval(x); }, des.u);
+ return Fortran::common::visit([&](const auto &x) { return genval(x); },
+ des.u);
}
mlir::Type genType(const Fortran::evaluate::DynamicType &dt) {
@@ -2286,11 +2290,21 @@ public:
bool isActualArgBox =
fir::isa_box_type(fir::getBase(copyOutPair.var).getType());
auto doCopyOut = [&]() {
- if (!copyOutPair.argMayBeModifiedByCall) {
- return;
- }
if (!isActualArgBox || inlineCopyInOutForBoxes) {
- genArrayCopy(copyOutPair.var, copyOutPair.temp);
+ if (copyOutPair.argMayBeModifiedByCall)
+ genArrayCopy(copyOutPair.var, copyOutPair.temp);
+ if (mlir::isa<fir::RecordType>(
+ fir::getElementTypeOf(copyOutPair.temp))) {
+ // Destroy components of the temporary (if any).
+ // If there are no components requiring destruction, then the call
+ // is a no-op.
+ mlir::Value tempBox =
+ fir::getBase(builder.createBox(loc, copyOutPair.temp));
+ fir::runtime::genDerivedTypeDestroyWithoutFinalization(builder, loc,
+ tempBox);
+ }
+ // Deallocate the top-level entity of the temporary.
+ builder.create<fir::FreeMemOp>(loc, fir::getBase(copyOutPair.temp));
return;
}
// Generate CopyOutAssign() call to copy data from the temporary
@@ -2301,51 +2315,39 @@ public:
// Moreover, CopyOutAssign() guarantees that there will be no
// finalization for the LHS even if it is of a derived type
// with finalization.
+
+ // Create allocatable descriptor for the temp so that the runtime may
+ // deallocate it.
mlir::Value srcBox =
fir::getBase(builder.createBox(loc, copyOutPair.temp));
- mlir::Value destBox =
- fir::getBase(builder.createBox(loc, copyOutPair.var));
- mlir::Value destBoxRef = builder.createTemporary(loc, destBox.getType());
- builder.create<fir::StoreOp>(loc, destBox, destBoxRef);
- fir::runtime::genCopyOutAssign(builder, loc, destBoxRef, srcBox,
- /*skipToInit=*/true);
- };
- if (!copyOutPair.restrictCopyAndFreeAtRuntime) {
- doCopyOut();
-
- if (mlir::isa<fir::RecordType>(fir::getElementTypeOf(copyOutPair.temp))) {
- // Destroy components of the temporary (if any).
- // If there are no components requiring destruction, then the call
- // is a no-op.
- mlir::Value tempBox =
- fir::getBase(builder.createBox(loc, copyOutPair.temp));
- fir::runtime::genDerivedTypeDestroyWithoutFinalization(builder, loc,
- tempBox);
+ mlir::Type allocBoxTy =
+ mlir::cast<fir::BaseBoxType>(srcBox.getType())
+ .getBoxTypeWithNewAttr(fir::BaseBoxType::Attribute::Allocatable);
+ srcBox = builder.create<fir::ReboxOp>(loc, allocBoxTy, srcBox,
+ /*shift=*/mlir::Value{},
+ /*slice=*/mlir::Value{});
+ mlir::Value srcBoxRef = builder.createTemporary(loc, srcBox.getType());
+ builder.create<fir::StoreOp>(loc, srcBox, srcBoxRef);
+ // Create descriptor pointer to variable descriptor if copy out is needed,
+ // and nullptr otherwise.
+ mlir::Value destBoxRef;
+ if (copyOutPair.argMayBeModifiedByCall) {
+ mlir::Value destBox =
+ fir::getBase(builder.createBox(loc, copyOutPair.var));
+ destBoxRef = builder.createTemporary(loc, destBox.getType());
+ builder.create<fir::StoreOp>(loc, destBox, destBoxRef);
+ } else {
+ destBoxRef = builder.create<fir::ZeroOp>(loc, srcBoxRef.getType());
}
+ fir::runtime::genCopyOutAssign(builder, loc, destBoxRef, srcBoxRef);
+ };
- // Deallocate the top-level entity of the temporary.
- builder.create<fir::FreeMemOp>(loc, fir::getBase(copyOutPair.temp));
- return;
- }
-
- builder.genIfThen(loc, *copyOutPair.restrictCopyAndFreeAtRuntime)
- .genThen([&]() {
- doCopyOut();
- if (mlir::isa<fir::RecordType>(
- fir::getElementTypeOf(copyOutPair.temp))) {
- // Destroy components of the temporary (if any).
- // If there are no components requiring destruction, then the call
- // is a no-op.
- mlir::Value tempBox =
- fir::getBase(builder.createBox(loc, copyOutPair.temp));
- fir::runtime::genDerivedTypeDestroyWithoutFinalization(builder, loc,
- tempBox);
- }
-
- // Deallocate the top-level entity of the temporary.
- builder.create<fir::FreeMemOp>(loc, fir::getBase(copyOutPair.temp));
- })
- .end();
+ if (!copyOutPair.restrictCopyAndFreeAtRuntime)
+ doCopyOut();
+ else
+ builder.genIfThen(loc, *copyOutPair.restrictCopyAndFreeAtRuntime)
+ .genThen([&]() { doCopyOut(); })
+ .end();
}
/// Lower a designator to a variable that may be absent at runtime into an
@@ -2900,8 +2902,8 @@ public:
}
template <typename T>
bool isTransformationalRef(Fortran::evaluate::Expr<T> expr) {
- return std::visit([&](const auto &e) { return isTransformationalRef(e); },
- expr.u);
+ return Fortran::common::visit(
+ [&](const auto &e) { return isTransformationalRef(e); }, expr.u);
}
template <typename A>
@@ -2914,11 +2916,13 @@ public:
/// value, so it may be possible to avoid making a temporary.
template <typename A>
ExtValue asArrayArg(const Fortran::evaluate::Expr<A> &x) {
- return std::visit([&](const auto &e) { return asArrayArg(e, x); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &e) { return asArrayArg(e, x); }, x.u);
}
template <typename A, typename B>
ExtValue asArrayArg(const Fortran::evaluate::Expr<A> &x, const B &y) {
- return std::visit([&](const auto &e) { return asArrayArg(e, y); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &e) { return asArrayArg(e, y); }, x.u);
}
template <typename A, typename B>
ExtValue asArrayArg(const Fortran::evaluate::Designator<A> &, const B &x) {
@@ -2956,7 +2960,8 @@ public:
if (isScalar(x) ||
Fortran::evaluate::UnwrapWholeSymbolOrComponentDataRef(x) ||
(isTransformationalRef(x) && !isOptimizableTranspose(x, converter)))
- return std::visit([&](const auto &e) { return genref(e); }, x.u);
+ return Fortran::common::visit([&](const auto &e) { return genref(e); },
+ x.u);
if (useBoxArg)
return asArrayArg(x);
return asArray(x);
@@ -2967,7 +2972,8 @@ public:
return val;
if (isScalar(x) || Fortran::evaluate::UnwrapWholeSymbolDataRef(x) ||
inInitializer)
- return std::visit([&](const auto &e) { return genval(e); }, x.u);
+ return Fortran::common::visit([&](const auto &e) { return genval(e); },
+ x.u);
return asArray(x);
}
@@ -2976,7 +2982,8 @@ public:
Fortran::common::TypeCategory::Logical, KIND>> &exp) {
if (mlir::Value val = getIfOverridenExpr(exp))
return val;
- return std::visit([&](const auto &e) { return genval(e); }, exp.u);
+ return Fortran::common::visit([&](const auto &e) { return genval(e); },
+ exp.u);
}
using RefSet =
@@ -3462,7 +3469,7 @@ public:
ExtValue lowerBoxedArrayExpr(const Fortran::lower::SomeExpr &exp) {
PushSemantics(ConstituentSemantics::BoxValue);
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &e) {
auto f = genarr(e);
ExtValue exv = f(IterationSpace{});
@@ -3824,28 +3831,29 @@ private:
fir::factory::getExtents(loc, builder, exv);
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
for (auto ss : llvm::enumerate(x.subscript())) {
- std::visit(Fortran::common::visitors{
- [&](const Fortran::evaluate::Triplet &trip) {
- // For a subscript of triple notation, we compute the
- // range of this dimension of the iteration space.
- auto lo = [&]() {
- if (auto optLo = trip.lower())
- return fir::getBase(asScalar(*optLo));
- return getLBound(exv, ss.index(), one);
- }();
- auto hi = [&]() {
- if (auto optHi = trip.upper())
- return fir::getBase(asScalar(*optHi));
- return getUBound(exv, ss.index(), one);
- }();
- auto step = builder.createConvert(
- loc, idxTy, fir::getBase(asScalar(trip.stride())));
- auto extent = builder.genExtentFromTriplet(loc, lo, hi,
- step, idxTy);
- destShape.push_back(extent);
- },
- [&](auto) {}},
- ss.value().u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::evaluate::Triplet &trip) {
+ // For a subscript of triple notation, we compute the
+ // range of this dimension of the iteration space.
+ auto lo = [&]() {
+ if (auto optLo = trip.lower())
+ return fir::getBase(asScalar(*optLo));
+ return getLBound(exv, ss.index(), one);
+ }();
+ auto hi = [&]() {
+ if (auto optHi = trip.upper())
+ return fir::getBase(asScalar(*optHi));
+ return getUBound(exv, ss.index(), one);
+ }();
+ auto step = builder.createConvert(
+ loc, idxTy, fir::getBase(asScalar(trip.stride())));
+ auto extent =
+ builder.genExtentFromTriplet(loc, lo, hi, step, idxTy);
+ destShape.push_back(extent);
+ },
+ [&](auto) {}},
+ ss.value().u);
}
return true;
}
@@ -3855,8 +3863,8 @@ private:
return genShapeFromDataRef(x.GetComponent());
}
bool genShapeFromDataRef(const Fortran::evaluate::DataRef &x) {
- return std::visit([&](const auto &v) { return genShapeFromDataRef(v); },
- x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return genShapeFromDataRef(v); }, x.u);
}
/// When in an explicit space, the ranked component must be evaluated to
@@ -3890,7 +3898,7 @@ private:
TODO(getLoc(),
"polymorphic array expression lowering with vector subscript");
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &e) { return lowerArrayExpression(genarr(e), resTy); },
exp.u);
}
@@ -5012,10 +5020,12 @@ private:
LLVM_DEBUG(Fortran::lower::DumpEvaluateExpr::dump(llvm::dbgs(), x));
if (isArray(x) || (explicitSpaceIsActive() && isLeftHandSide()) ||
isElementalProcWithArrayArgs(x))
- return std::visit([&](const auto &e) { return genarr(e); }, x.u);
+ return Fortran::common::visit([&](const auto &e) { return genarr(e); },
+ x.u);
if (explicitSpaceIsActive()) {
assert(!isArray(x) && !isLeftHandSide());
- auto cc = std::visit([&](const auto &e) { return genarr(e); }, x.u);
+ auto cc =
+ Fortran::common::visit([&](const auto &e) { return genarr(e); }, x.u);
auto result = cc(IterationSpace{});
return [=](IterSpace) { return result; };
}
@@ -5289,7 +5299,8 @@ private:
static Fortran::lower::SomeExpr
ignoreEvConvert(const Fortran::evaluate::Expr<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Integer, 8>> &x) {
- return std::visit([&](const auto &v) { return ignoreEvConvert(v); }, x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return ignoreEvConvert(v); }, x.u);
}
template <Fortran::common::TypeCategory FROM>
static Fortran::lower::SomeExpr ignoreEvConvert(
@@ -5310,8 +5321,8 @@ private:
template <typename A>
static const Fortran::semantics::Symbol *
extractSubscriptSymbol(const Fortran::evaluate::Expr<A> &x) {
- return std::visit([&](const auto &v) { return extractSubscriptSymbol(v); },
- x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return extractSubscriptSymbol(v); }, x.u);
}
template <typename A>
static const Fortran::semantics::Symbol *
@@ -5420,7 +5431,7 @@ private:
std::size_t shapeIndex = 0;
for (auto sub : llvm::enumerate(x.subscript())) {
const std::size_t subsIndex = sub.index();
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::Triplet &t) {
mlir::Value lowerBound;
@@ -6034,8 +6045,8 @@ private:
/// Substrings (see 9.4.1)
CC genarr(const Fortran::evaluate::Substring &x, ComponentPath &components) {
components.substring = &x;
- return std::visit([&](const auto &v) { return genarr(v, components); },
- x.parent());
+ return Fortran::common::visit(
+ [&](const auto &v) { return genarr(v, components); }, x.parent());
}
template <typename T>
@@ -6333,7 +6344,7 @@ private:
stmtCtx.pushScope();
std::optional<mlir::Value> charLen;
for (const Fortran::evaluate::ArrayConstructorValue<A> &acv : x.values()) {
- auto [exv, copyNeeded] = std::visit(
+ auto [exv, copyNeeded] = Fortran::common::visit(
[&](const auto &v) {
return genArrayCtorInitializer(v, resTy, mem, buffPos, buffSize,
stmtCtx);
@@ -6417,7 +6428,7 @@ private:
// Populate the buffer with the elements, growing as necessary.
std::optional<mlir::Value> charLen;
for (const auto &expr : x) {
- auto [exv, copyNeeded] = std::visit(
+ auto [exv, copyNeeded] = Fortran::common::visit(
[&](const auto &e) {
return genArrayCtorInitializer(e, resTy, mem, buffPos, buffSize,
stmtCtx);
@@ -6582,22 +6593,24 @@ private:
}
CC genarr(
const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &r) {
- return std::visit([&](const auto &x) { return genarr(x); }, r.u);
+ return Fortran::common::visit([&](const auto &x) { return genarr(x); },
+ r.u);
}
template <typename A>
CC genarr(const Fortran::evaluate::Designator<A> &des) {
ComponentPath components(des.Rank() > 0);
- return std::visit([&](const auto &x) { return genarr(x, components); },
- des.u);
+ return Fortran::common::visit(
+ [&](const auto &x) { return genarr(x, components); }, des.u);
}
/// Is the path component rank > 0?
static bool ranked(const PathComponent &x) {
- return std::visit(Fortran::common::visitors{
- [](const ImplicitSubscripts &) { return false; },
- [](const auto *v) { return v->Rank() > 0; }},
- x);
+ return Fortran::common::visit(
+ Fortran::common::visitors{
+ [](const ImplicitSubscripts &) { return false; },
+ [](const auto *v) { return v->Rank() > 0; }},
+ x);
}
void extendComponent(Fortran::lower::ComponentPath &component,
@@ -6653,7 +6666,7 @@ private:
: nextPathSemantics());
unsigned index = 0;
for (const auto &v : llvm::reverse(revPath)) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const ImplicitSubscripts &) {
prefix = false;
@@ -6678,7 +6691,7 @@ private:
unsigned ssIndex = 0u;
llvm::SmallVector<mlir::Value> componentsToAdd;
for (const auto &ss : x->subscript()) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::
IndirectSubscriptIntegerExpr &ie) {
@@ -7099,8 +7112,8 @@ private:
}
CC genarr(const Fortran::evaluate::DataRef &x, ComponentPath &components) {
- return std::visit([&](const auto &v) { return genarr(v, components); },
- x.u);
+ return Fortran::common::visit(
+ [&](const auto &v) { return genarr(v, components); }, x.u);
}
bool pathIsEmpty(const ComponentPath &components) {
@@ -7575,13 +7588,13 @@ void Fortran::lower::createArrayLoads(
};
if (esp.lhsBases[counter]) {
auto &base = *esp.lhsBases[counter];
- auto load = std::visit(genLoad, base);
+ auto load = Fortran::common::visit(genLoad, base);
esp.initialArgs.push_back(load);
esp.resetInnerArgs();
esp.bindLoad(base, load);
}
for (const auto &base : esp.rhsBases[counter])
- esp.bindLoad(base, std::visit(genLoad, base));
+ esp.bindLoad(base, Fortran::common::visit(genLoad, base));
}
void Fortran::lower::createArrayMergeStores(
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 9035856eabfe..1933f38f735b 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -75,7 +75,7 @@ public:
hlfir::EntityWithAttributes
gen(const CharacterDesignators &designatorVariant,
bool vectorSubscriptDesignatorToValue = true) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> hlfir::EntityWithAttributes {
return genLeafPartRef(x, vectorSubscriptDesignatorToValue);
},
@@ -88,7 +88,7 @@ public:
hlfir::EntityWithAttributes
gen(const RealDesignators &designatorVariant,
bool vectorSubscriptDesignatorToValue = true) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> hlfir::EntityWithAttributes {
return genLeafPartRef(x, vectorSubscriptDesignatorToValue);
},
@@ -101,7 +101,7 @@ public:
hlfir::EntityWithAttributes
gen(const OtherDesignators &designatorVariant,
bool vectorSubscriptDesignatorToValue = true) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> hlfir::EntityWithAttributes {
return genLeafPartRef(x, vectorSubscriptDesignatorToValue);
},
@@ -169,7 +169,7 @@ public:
fir::FortranVariableOpInterface
gen(const Fortran::evaluate::DataRef &dataRef) {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{[&](const auto &x) { return gen(x); }},
dataRef.u);
}
@@ -364,7 +364,7 @@ private:
fir::FortranVariableOpInterface
gen(const Fortran::evaluate::Substring &substring) {
PartInfo partInfo;
- mlir::Type baseStringType = std::visit(
+ mlir::Type baseStringType = Fortran::common::visit(
[&](const auto &x) { return visit(x, partInfo); }, substring.parent());
assert(partInfo.typeParams.size() == 1 && "expect base string length");
// Compute the substring lower and upper bound.
@@ -436,8 +436,8 @@ private:
mlir::Type visit(const Fortran::evaluate::DataRef &dataRef,
PartInfo &partInfo) {
- return std::visit([&](const auto &x) { return visit(x, partInfo); },
- dataRef.u);
+ return Fortran::common::visit(
+ [&](const auto &x) { return visit(x, partInfo); }, dataRef.u);
}
mlir::Type
@@ -892,7 +892,7 @@ hlfir::EntityWithAttributes HlfirDesignatorBuilder::genDesignatorExpr(
bool vectorSubscriptDesignatorToValue) {
// Expr<SomeType> plumbing to unwrap Designator<T> and call
// gen(Designator<T>.u).
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &x) -> hlfir::EntityWithAttributes {
using T = std::decay_t<decltype(x)>;
if constexpr (Fortran::common::HasMember<
@@ -904,7 +904,7 @@ hlfir::EntityWithAttributes HlfirDesignatorBuilder::genDesignatorExpr(
.u,
vectorSubscriptDesignatorToValue);
} else {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto &preciseKind) {
using TK =
typename std::decay_t<decltype(preciseKind)>::Result;
@@ -1426,7 +1426,8 @@ public:
return hlfir::EntityWithAttributes{match->second};
}
}
- return std::visit([&](const auto &x) { return gen(x); }, expr.u);
+ return Fortran::common::visit([&](const auto &x) { return gen(x); },
+ expr.u);
}
private:
@@ -1594,7 +1595,7 @@ private:
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &op) {
- return std::visit([&](const auto &x) { return gen(x); }, op.u);
+ return Fortran::common::visit([&](const auto &x) { return gen(x); }, op.u);
}
hlfir::EntityWithAttributes gen(const Fortran::evaluate::TypeParamInquiry &) {
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index e6557d7f0b76..a47fc99ea9f4 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -212,7 +212,7 @@ struct TypeBuilderImpl {
}
mlir::Type genTypelessExprType(const Fortran::lower::SomeExpr &expr) {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::BOZLiteralConstant &) -> mlir::Type {
return mlir::NoneType::get(context);
@@ -280,10 +280,11 @@ struct TypeBuilderImpl {
if (ultimate.IsObjectArray()) {
auto shapeExpr =
Fortran::evaluate::GetShape(converter.getFoldingContext(), ultimate);
- if (!shapeExpr)
- TODO(loc, "assumed rank symbol type");
fir::SequenceType::Shape shape;
- translateShape(shape, std::move(*shapeExpr));
+ // If there is no shapExpr, this is an assumed-rank, and the empty shape
+ // will build the desired fir.array<*:T> type.
+ if (shapeExpr)
+ translateShape(shape, std::move(*shapeExpr));
ty = fir::SequenceType::get(shape, ty);
}
if (Fortran::semantics::IsPointer(symbol))
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 80a80fd1d92e..e5a71c5ec5b4 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -165,12 +165,15 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
if (fir::GlobalOp global = builder.getNamedGlobal(globalName))
return global;
+ const Fortran::semantics::Symbol &sym = var.getSymbol();
+ cuf::DataAttributeAttr dataAttr =
+ Fortran::lower::translateSymbolCUFDataAttribute(
+ converter.getFirOpBuilder().getContext(), sym);
// Always define linkonce data since it may be optimized out from the module
// that actually owns the variable if it does not refers to it.
if (linkage == builder.createLinkOnceODRLinkage() ||
linkage == builder.createLinkOnceLinkage())
- return defineGlobal(converter, var, globalName, linkage);
- const Fortran::semantics::Symbol &sym = var.getSymbol();
+ return defineGlobal(converter, var, globalName, linkage, dataAttr);
mlir::Location loc = genLocation(converter, sym);
// Resolve potential host and module association before checking that this
// symbol is an object of a function pointer.
@@ -179,9 +182,6 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
!Fortran::semantics::IsProcedurePointer(ultimate))
mlir::emitError(loc, "processing global declaration: symbol '")
<< toStringRef(sym.name()) << "' has unexpected details\n";
- cuf::DataAttributeAttr dataAttr =
- Fortran::lower::translateSymbolCUFDataAttribute(
- converter.getFirOpBuilder().getContext(), sym);
return builder.createGlobal(loc, converter.genType(var), globalName, linkage,
mlir::Attribute{}, isConstant(ultimate),
var.isTarget(), dataAttr);
@@ -510,7 +510,7 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
if (details->init()) {
global = Fortran::lower::tryCreatingDenseGlobal(
builder, loc, symTy, globalName, linkage, isConst,
- details->init().value());
+ details->init().value(), dataAttr);
if (global) {
global.setVisibility(mlir::SymbolTable::Visibility::Public);
return global;
@@ -2036,11 +2036,6 @@ void Fortran::lower::mapSymbolAttributes(
if (isUnusedEntryDummy) {
assert(!Fortran::semantics::IsAllocatableOrPointer(sym) &&
"handled above");
- // Need to add support for allocatable assumed-rank to use
- // logic below, or to simplify it and add codegen for fir.zero
- // !fir.box<> instead.
- if (isAssumedRank)
- TODO(loc, "assumed rank in ENTRY");
// The box is read right away because lowering code does not expect
// a non pointer/allocatable symbol to be mapped to a MutableBox.
mlir::Type ty = converter.genType(var);
diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h
index 48b090f6d2db..f0af5f982c14 100644
--- a/flang/lib/Lower/DirectivesCommon.h
+++ b/flang/lib/Lower/DirectivesCommon.h
@@ -836,7 +836,7 @@ struct PeelConvert {
static Fortran::semantics::MaybeExpr visit_with_category(
const Fortran::evaluate::Expr<Fortran::evaluate::Type<Category, Kind>>
&expr) {
- return std::visit(
+ return Fortran::common::visit(
[](auto &&s) { return visit_with_category<Category, Kind>(s); },
expr.u);
}
@@ -859,12 +859,12 @@ struct PeelConvert {
static Fortran::semantics::MaybeExpr
visit(const Fortran::evaluate::Expr<Fortran::evaluate::SomeKind<Category>>
&expr) {
- return std::visit([](auto &&s) { return visit_with_category<Category>(s); },
- expr.u);
+ return Fortran::common::visit(
+ [](auto &&s) { return visit_with_category<Category>(s); }, expr.u);
}
static Fortran::semantics::MaybeExpr
visit(const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr) {
- return std::visit([](auto &&s) { return visit(s); }, expr.u);
+ return Fortran::common::visit([](auto &&s) { return visit(s); }, expr.u);
}
template <typename T> //
static Fortran::semantics::MaybeExpr visit(const T &) {
diff --git a/flang/lib/Lower/HostAssociations.cpp b/flang/lib/Lower/HostAssociations.cpp
index 75a5bed56655..0f75a8a7c312 100644
--- a/flang/lib/Lower/HostAssociations.cpp
+++ b/flang/lib/Lower/HostAssociations.cpp
@@ -366,7 +366,8 @@ public:
}
};
-/// Class defining how arrays are captured inside internal procedures.
+/// Class defining how arrays, including assumed-ranks, are captured inside
+/// internal procedures.
/// Array are captured via a `fir.box<fir.array<T>>` descriptor that belongs to
/// the host tuple. This allows capturing lower bounds, which can be done by
/// providing a ShapeShiftOp argument to the EmboxOp.
@@ -430,7 +431,7 @@ public:
mlir::Value box = args.valueInTuple;
mlir::IndexType idxTy = builder.getIndexType();
llvm::SmallVector<mlir::Value> lbounds;
- if (!ba.lboundIsAllOnes()) {
+ if (!ba.lboundIsAllOnes() && !Fortran::evaluate::IsAssumedRank(sym)) {
if (ba.isStaticArray()) {
for (std::int64_t lb : ba.staticLBound())
lbounds.emplace_back(builder.createIntegerConstant(loc, idxTy, lb));
@@ -488,7 +489,8 @@ private:
const Fortran::semantics::DeclTypeSpec *type = sym.GetType();
bool isPolymorphic = type && type->IsPolymorphic();
return isScalarOrContiguous && !isPolymorphic &&
- !isDerivedWithLenParameters(sym);
+ !isDerivedWithLenParameters(sym) &&
+ !Fortran::evaluate::IsAssumedRank(sym);
}
};
} // namespace
@@ -514,7 +516,7 @@ walkCaptureCategories(T visitor, Fortran::lower::AbstractConverter &converter,
if (Fortran::semantics::IsAllocatableOrPointer(sym) ||
sym.GetUltimate().test(Fortran::semantics::Symbol::Flag::CrayPointee))
return CapturedAllocatableAndPointer::visit(visitor, converter, sym, ba);
- if (ba.isArray())
+ if (ba.isArray()) // include assumed-ranks.
return CapturedArrays::visit(visitor, converter, sym, ba);
if (Fortran::semantics::IsPolymorphic(sym))
return CapturedPolymorphicScalar::visit(visitor, converter, sym, ba);
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 97ef991cb399..9e98b230b676 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -1388,7 +1388,7 @@ static void threadSpecs(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
for (const auto &spec : specList) {
makeNextConditionalOn(builder, loc, checkResult, ok);
- ok = std::visit(
+ ok = Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::IoControlSpec::Size &x) -> mlir::Value {
// Size must be queried after the related READ runtime calls, not
@@ -1425,7 +1425,7 @@ ConditionSpecInfo lowerErrorSpec(Fortran::lower::AbstractConverter &converter,
ConditionSpecInfo csi;
const Fortran::lower::SomeExpr *ioMsgExpr = nullptr;
for (const auto &spec : specList) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::StatVariable &var) {
csi.ioStatExpr = Fortran::semantics::GetExpr(var);
@@ -2397,7 +2397,7 @@ lowerIdExpr(Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const std::list<Fortran::parser::InquireSpec> &ispecs,
Fortran::lower::StatementContext &stmtCtx) {
for (const Fortran::parser::InquireSpec &spec : ispecs)
- if (mlir::Value v = std::visit(
+ if (mlir::Value v = Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::IdExpr &idExpr) {
return fir::getBase(converter.genExprValue(
@@ -2419,11 +2419,11 @@ static void threadInquire(Fortran::lower::AbstractConverter &converter,
mlir::Value idExpr = lowerIdExpr(converter, loc, ispecs, stmtCtx);
for (const Fortran::parser::InquireSpec &spec : ispecs) {
makeNextConditionalOn(builder, loc, checkResult, ok);
- ok = std::visit(Fortran::common::visitors{[&](const auto &x) {
- return genInquireSpec(converter, loc, cookie, idExpr, x,
- stmtCtx);
- }},
- spec.u);
+ ok = Fortran::common::visit(Fortran::common::visitors{[&](const auto &x) {
+ return genInquireSpec(converter, loc, cookie,
+ idExpr, x, stmtCtx);
+ }},
+ spec.u);
}
}
diff --git a/flang/lib/Lower/IterationSpace.cpp b/flang/lib/Lower/IterationSpace.cpp
index 6bf310b5cfb7..930353640383 100644
--- a/flang/lib/Lower/IterationSpace.cpp
+++ b/flang/lib/Lower/IterationSpace.cpp
@@ -21,14 +21,14 @@
unsigned Fortran::lower::getHashValue(
const Fortran::lower::ExplicitIterSpace::ArrayBases &x) {
- return std::visit(
+ return Fortran::common::visit(
[&](const auto *p) { return HashEvaluateExpr::getHashValue(*p); }, x);
}
bool Fortran::lower::isEqual(
const Fortran::lower::ExplicitIterSpace::ArrayBases &x,
const Fortran::lower::ExplicitIterSpace::ArrayBases &y) {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
// Fortran::semantics::Symbol * are the exception here. These pointers
// have identity; if two Symbol * values are the same (different) then
@@ -169,7 +169,7 @@ private:
}
template <typename... A>
RT find(const std::variant<A...> &u) {
- return std::visit([&](const auto &v) { return find(v); }, u);
+ return Fortran::common::visit([&](const auto &v) { return find(v); }, u);
}
template <typename A>
RT find(const std::vector<A> &x) {
@@ -361,22 +361,23 @@ llvm::raw_ostream &
Fortran::lower::operator<<(llvm::raw_ostream &s,
const Fortran::lower::ExplicitIterSpace &e) {
auto dump = [&](const auto &u) {
- std::visit(Fortran::common::visitors{
- [&](const Fortran::semantics::Symbol *y) {
- s << " " << *y << '\n';
- },
- [&](const Fortran::evaluate::ArrayRef *y) {
- s << " ";
- if (y->base().IsSymbol())
- s << y->base().GetFirstSymbol();
- else
- s << y->base().GetComponent().GetLastSymbol();
- s << '\n';
- },
- [&](const Fortran::evaluate::Component *y) {
- s << " " << y->GetLastSymbol() << '\n';
- }},
- u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::semantics::Symbol *y) {
+ s << " " << *y << '\n';
+ },
+ [&](const Fortran::evaluate::ArrayRef *y) {
+ s << " ";
+ if (y->base().IsSymbol())
+ s << y->base().GetFirstSymbol();
+ else
+ s << y->base().GetComponent().GetLastSymbol();
+ s << '\n';
+ },
+ [&](const Fortran::evaluate::Component *y) {
+ s << " " << y->GetLastSymbol() << '\n';
+ }},
+ u);
};
s << "LHS bases:\n";
for (const std::optional<Fortran::lower::ExplicitIterSpace::ArrayBases> &u :
diff --git a/flang/lib/Lower/Mangler.cpp b/flang/lib/Lower/Mangler.cpp
index 9a33be318a27..878ba6dea49b 100644
--- a/flang/lib/Lower/Mangler.cpp
+++ b/flang/lib/Lower/Mangler.cpp
@@ -110,7 +110,7 @@ std::string Fortran::lower::mangle::mangleName(
return fir::NameUniquer::doVariable(modules, procs, blockId, symbolName);
};
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::semantics::MainProgramDetails &) {
return fir::NameUniquer::doProgramEntry().str();
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 4f5da8fb70eb..166fa686cd88 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -46,14 +46,15 @@ static mlir::Location
genOperandLocation(Fortran::lower::AbstractConverter &converter,
const Fortran::parser::AccObject &accObject) {
mlir::Location loc = converter.genUnknownLocation();
- std::visit(Fortran::common::visitors{
- [&](const Fortran::parser::Designator &designator) {
- loc = converter.genLocation(designator.source);
- },
- [&](const Fortran::parser::Name &name) {
- loc = converter.genLocation(name.source);
- }},
- accObject.u);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::Designator &designator) {
+ loc = converter.genLocation(designator.source);
+ },
+ [&](const Fortran::parser::Name &name) {
+ loc = converter.genLocation(name.source);
+ }},
+ accObject.u);
return loc;
}
@@ -297,8 +298,8 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
std::stringstream asFortran;
mlir::Location operandLocation = genOperandLocation(converter, accObject);
Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
- Fortran::semantics::MaybeExpr designator =
- std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+ Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+ [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
Fortran::lower::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -335,8 +336,8 @@ static void genDeclareDataOperandOperations(
std::stringstream asFortran;
mlir::Location operandLocation = genOperandLocation(converter, accObject);
Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
- Fortran::semantics::MaybeExpr designator =
- std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+ Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+ [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
Fortran::lower::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -790,8 +791,8 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
std::stringstream asFortran;
mlir::Location operandLocation = genOperandLocation(converter, accObject);
Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
- Fortran::semantics::MaybeExpr designator =
- std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+ Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+ [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
Fortran::lower::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -1364,8 +1365,8 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
std::stringstream asFortran;
mlir::Location operandLocation = genOperandLocation(converter, accObject);
Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
- Fortran::semantics::MaybeExpr designator =
- std::visit([&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+ Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+ [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
Fortran::lower::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -3414,7 +3415,7 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
for (const auto &accObject : accObjectList.v) {
mlir::Location operandLocation = genOperandLocation(converter, accObject);
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::Designator &designator) {
if (const auto *name =
@@ -3993,7 +3994,7 @@ genACC(Fortran::lower::AbstractConverter &converter,
const Fortran::parser::OpenACCAtomicConstruct &atomicConstruct) {
mlir::Location loc = converter.genLocation(atomicConstruct.source);
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::AccAtomicRead &atomicRead) {
Fortran::lower::genOmpAccAtomicRead<Fortran::parser::AccAtomicRead,
@@ -4061,7 +4062,7 @@ mlir::Value Fortran::lower::genOpenACCConstruct(
const Fortran::parser::OpenACCConstruct &accConstruct) {
mlir::Value exitCond;
- std::visit(
+ Fortran::common::visit(
common::visitors{
[&](const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
genACC(converter, semanticsContext, eval, blockConstruct);
@@ -4101,7 +4102,7 @@ void Fortran::lower::genOpenACCDeclarativeConstruct(
const Fortran::parser::OpenACCDeclarativeConstruct &accDeclConstruct,
Fortran::lower::AccRoutineInfoMappingList &accRoutineInfos) {
- std::visit(
+ Fortran::common::visit(
common::visitors{
[&](const Fortran::parser::OpenACCStandaloneDeclarativeConstruct
&standaloneDeclarativeConstruct) {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index d289f2fdfab2..f78cd0f9df1a 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -16,6 +16,7 @@
#include "flang/Lower/PFTBuilder.h"
#include "flang/Parser/tools.h"
#include "flang/Semantics/tools.h"
+#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
namespace Fortran {
namespace lower {
@@ -317,6 +318,20 @@ bool ClauseProcessor::processDeviceType(
return false;
}
+bool ClauseProcessor::processDistSchedule(
+ lower::StatementContext &stmtCtx,
+ mlir::omp::DistScheduleClauseOps &result) const {
+ if (auto *clause = findUniqueClause<omp::clause::DistSchedule>()) {
+ result.distScheduleStaticAttr = converter.getFirOpBuilder().getUnitAttr();
+ const auto &chunkSize = std::get<std::optional<ExprTy>>(clause->t);
+ if (chunkSize)
+ result.distScheduleChunkSizeVar =
+ fir::getBase(converter.genExprValue(*chunkSize, stmtCtx));
+ return true;
+ }
+ return false;
+}
+
bool ClauseProcessor::processFinal(lower::StatementContext &stmtCtx,
mlir::omp::FinalClauseOps &result) const {
const parser::CharBlock *source = nullptr;
@@ -379,6 +394,28 @@ bool ClauseProcessor::processNumThreads(
return false;
}
+bool ClauseProcessor::processOrder(mlir::omp::OrderClauseOps &result) const {
+ using Order = omp::clause::Order;
+ if (auto *clause = findUniqueClause<Order>()) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ result.orderAttr = mlir::omp::ClauseOrderKindAttr::get(
+ firOpBuilder.getContext(), mlir::omp::ClauseOrderKind::Concurrent);
+ const auto &modifier =
+ std::get<std::optional<Order::OrderModifier>>(clause->t);
+ if (modifier && *modifier == Order::OrderModifier::Unconstrained) {
+ result.orderModAttr = mlir::omp::OrderModifierAttr::get(
+ firOpBuilder.getContext(), mlir::omp::OrderModifier::unconstrained);
+ } else {
+ // "If order-modifier is not unconstrained, the behavior is as if the
+ // reproducible modifier is present."
+ result.orderModAttr = mlir::omp::OrderModifierAttr::get(
+ firOpBuilder.getContext(), mlir::omp::OrderModifier::reproducible);
+ }
+ return true;
+ }
+ return false;
+}
+
bool ClauseProcessor::processOrdered(
mlir::omp::OrderedClauseOps &result) const {
if (auto *clause = findUniqueClause<omp::clause::Ordered>()) {
@@ -500,6 +537,65 @@ bool ClauseProcessor::processUntied(mlir::omp::UntiedClauseOps &result) const {
//===----------------------------------------------------------------------===//
// ClauseProcessor repeatable clauses
//===----------------------------------------------------------------------===//
+static llvm::StringMap<bool> getTargetFeatures(mlir::ModuleOp module) {
+ llvm::StringMap<bool> featuresMap;
+ llvm::SmallVector<llvm::StringRef> targetFeaturesVec;
+ if (mlir::LLVM::TargetFeaturesAttr features =
+ fir::getTargetFeatures(module)) {
+ llvm::ArrayRef<mlir::StringAttr> featureAttrs = features.getFeatures();
+ for (auto &featureAttr : featureAttrs) {
+ llvm::StringRef featureKeyString = featureAttr.strref();
+ featuresMap[featureKeyString.substr(1)] = (featureKeyString[0] == '+');
+ }
+ }
+ return featuresMap;
+}
+
+static void
+addAlignedClause(lower::AbstractConverter &converter,
+ const omp::clause::Aligned &clause,
+ llvm::SmallVectorImpl<mlir::Value> &alignedVars,
+ llvm::SmallVectorImpl<mlir::Attribute> &alignmentAttrs) {
+ using Aligned = omp::clause::Aligned;
+ lower::StatementContext stmtCtx;
+ mlir::IntegerAttr alignmentValueAttr;
+ int64_t alignment = 0;
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+
+ if (auto &alignmentValueParserExpr =
+ std::get<std::optional<Aligned::Alignment>>(clause.t)) {
+ mlir::Value operand = fir::getBase(
+ converter.genExprValue(*alignmentValueParserExpr, stmtCtx));
+ alignment = *fir::getIntIfConstant(operand);
+ } else {
+ llvm::StringMap<bool> featuresMap = getTargetFeatures(builder.getModule());
+ llvm::Triple triple = fir::getTargetTriple(builder.getModule());
+ alignment =
+ llvm::OpenMPIRBuilder::getOpenMPDefaultSimdAlign(triple, featuresMap);
+ }
+
+ // The default alignment for some targets is equal to 0.
+ // Do not generate alignment assumption if alignment is less than or equal to
+ // 0.
+ if (alignment > 0) {
+ auto &objects = std::get<omp::ObjectList>(clause.t);
+ if (!objects.empty())
+ genObjectList(objects, converter, alignedVars);
+ alignmentValueAttr = builder.getI64IntegerAttr(alignment);
+ // All the list items in a aligned clause will have same alignment
+ for (std::size_t i = 0; i < objects.size(); i++)
+ alignmentAttrs.push_back(alignmentValueAttr);
+ }
+}
+
+bool ClauseProcessor::processAligned(
+ mlir::omp::AlignedClauseOps &result) const {
+ return findRepeatableClause<omp::clause::Aligned>(
+ [&](const omp::clause::Aligned &clause, const parser::CharBlock &) {
+ addAlignedClause(converter, clause, result.alignedVars,
+ result.alignmentAttrs);
+ });
+}
bool ClauseProcessor::processAllocate(
mlir::omp::AllocateClauseOps &result) const {
@@ -655,7 +751,7 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter,
auto declSrc = builder.create<hlfir::DeclareOp>(
loc, funcOp.getArgument(1), copyFuncName + "_src", shape, typeparams,
/*dummy_scope=*/nullptr, attrs);
- converter.copyVar(loc, declDst.getBase(), declSrc.getBase());
+ converter.copyVar(loc, declDst.getBase(), declSrc.getBase(), varAttrs);
builder.create<mlir::func::ReturnOp>(loc);
return funcOp;
}
@@ -931,7 +1027,8 @@ bool ClauseProcessor::processReduction(
// Copy local lists into the output.
llvm::copy(reductionVars, std::back_inserter(result.reductionVars));
- llvm::copy(reduceVarByRef, std::back_inserter(result.reduceVarByRef));
+ llvm::copy(reduceVarByRef,
+ std::back_inserter(result.reductionVarsByRef));
llvm::copy(reductionDeclSymbols,
std::back_inserter(result.reductionDeclSymbols));
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 28f26697c1f5..53571ae5abc2 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -61,6 +61,8 @@ public:
bool processDevice(lower::StatementContext &stmtCtx,
mlir::omp::DeviceClauseOps &result) const;
bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const;
+ bool processDistSchedule(lower::StatementContext &stmtCtx,
+ mlir::omp::DistScheduleClauseOps &result) const;
bool processFinal(lower::StatementContext &stmtCtx,
mlir::omp::FinalClauseOps &result) const;
bool processHasDeviceAddr(
@@ -75,6 +77,7 @@ public:
mlir::omp::NumTeamsClauseOps &result) const;
bool processNumThreads(lower::StatementContext &stmtCtx,
mlir::omp::NumThreadsClauseOps &result) const;
+ bool processOrder(mlir::omp::OrderClauseOps &result) const;
bool processOrdered(mlir::omp::OrderedClauseOps &result) const;
bool processPriority(lower::StatementContext &stmtCtx,
mlir::omp::PriorityClauseOps &result) const;
@@ -88,6 +91,7 @@ public:
bool processUntied(mlir::omp::UntiedClauseOps &result) const;
// 'Repeatable' clauses: They can appear multiple times in the clause list.
+ bool processAligned(mlir::omp::AlignedClauseOps &result) const;
bool processAllocate(mlir::omp::AllocateClauseOps &result) const;
bool processCopyin() const;
bool processCopyprivate(mlir::Location currentLocation,
@@ -138,7 +142,6 @@ public:
template <typename T>
bool processMotionClauses(lower::StatementContext &stmtCtx,
mlir::omp::MapClauseOps &result);
-
// Call this method for these clauses that should be supported but are not
// implemented yet. It triggers a compilation error if any of the given
// clauses is found.
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 1e3fea7c4cdc..c355b63deff8 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -38,8 +38,8 @@ llvm::omp::Clause getClauseIdForClass(C &&) {
} // namespace detail
static llvm::omp::Clause getClauseId(const Fortran::parser::OmpClause &clause) {
- return std::visit([](auto &&s) { return detail::getClauseIdForClass(s); },
- clause.u);
+ return Fortran::common::visit(
+ [](auto &&s) { return detail::getClauseIdForClass(s); }, clause.u);
}
namespace Fortran::lower::omp {
@@ -83,7 +83,7 @@ struct SymbolAndDesignatorExtractor {
template <typename T>
static SymbolWithDesignator visit(const evaluate::Expr<T> &e) {
- return std::visit([](auto &&s) { return visit(s); }, e.u);
+ return Fortran::common::visit([](auto &&s) { return visit(s); }, e.u);
}
static void verify(const SymbolWithDesignator &sd) {
@@ -112,7 +112,7 @@ struct SymbolAndDesignatorExtractor {
SymbolWithDesignator getSymbolAndDesignator(const MaybeExpr &expr) {
if (!expr)
return SymbolWithDesignator{};
- return std::visit(
+ return Fortran::common::visit(
[](auto &&s) { return SymbolAndDesignatorExtractor::visit(s); }, expr->u);
}
@@ -153,7 +153,7 @@ Object makeObject(const parser::OmpObject &object,
std::optional<Object> getBaseObject(const Object &object,
semantics::SemanticsContext &semaCtx) {
// If it's just the symbol, then there is no base.
- if (!object.id())
+ if (!object.ref())
return std::nullopt;
auto maybeRef = evaluate::ExtractDataRef(*object.ref());
@@ -278,7 +278,7 @@ DefinedOperator makeDefinedOperator(const parser::DefinedOperator &inp,
// clang-format on
);
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const parser::DefinedOpName &s) {
return DefinedOperator{
@@ -294,7 +294,7 @@ DefinedOperator makeDefinedOperator(const parser::DefinedOperator &inp,
ProcedureDesignator
makeProcedureDesignator(const parser::ProcedureDesignator &inp,
semantics::SemanticsContext &semaCtx) {
- return ProcedureDesignator{std::visit(
+ return ProcedureDesignator{Fortran::common::visit(
common::visitors{
[&](const parser::Name &t) { return makeObject(t, semaCtx); },
[&](const parser::ProcComponentRef &t) {
@@ -306,7 +306,7 @@ makeProcedureDesignator(const parser::ProcedureDesignator &inp,
ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
semantics::SemanticsContext &semaCtx) {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const parser::DefinedOperator &s) {
return ReductionOperator{makeDefinedOperator(s, semaCtx)};
@@ -366,7 +366,7 @@ Allocate make(const parser::OmpClause::Allocate &inp,
using Tuple = decltype(Allocate::t);
- return Allocate{std::visit(
+ return Allocate{Fortran::common::visit(
common::visitors{
// simple-modifier
[&](const wrapped::AllocateModifier::Allocator &v) -> Tuple {
@@ -531,7 +531,7 @@ Depend make(const parser::OmpClause::Depend &inp,
// clang-format on
);
- return Depend{std::visit( //
+ return Depend{Fortran::common::visit( //
common::visitors{
// Doacross
[&](const wrapped::Source &s) -> Variant {
@@ -793,7 +793,7 @@ Linear make(const parser::OmpClause::Linear &inp,
using Tuple = decltype(Linear::t);
- return Linear{std::visit(
+ return Linear{Fortran::common::visit(
common::visitors{
[&](const wrapped::WithModifier &s) -> Tuple {
return {
@@ -949,7 +949,7 @@ Order make(const parser::OmpClause::Order &inp,
auto &t1 = std::get<wrapped::Type>(inp.v.t);
auto convert3 = [&](const parser::OmpOrderModifier &s) {
- return std::visit(
+ return Fortran::common::visit(
[&](parser::OmpOrderModifier::Kind k) { return convert1(k); }, s.u);
};
return Order{
@@ -1212,7 +1212,7 @@ UsesAllocators make(const parser::OmpClause::UsesAllocators &inp,
Clause makeClause(const parser::OmpClause &cls,
semantics::SemanticsContext &semaCtx) {
- return std::visit(
+ return Fortran::common::visit(
[&](auto &&s) {
return makeClause(getClauseId(cls), clause::make(s, semaCtx),
cls.source);
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6b391e11beb4..0b33c2a62d38 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -776,6 +776,33 @@ static void genBodyOfTargetDataOp(
}
}
+// This generates intermediate common block member accesses within a region
+// and then rebinds the members symbol to the intermediate accessors we have
+// generated so that subsequent code generation will utilise these instead.
+//
+// When the scope changes, the bindings to the intermediate accessors should
+// be dropped in place of the original symbol bindings.
+//
+// This is for utilisation with TargetOp.
+static void genIntermediateCommonBlockAccessors(
+ Fortran::lower::AbstractConverter &converter,
+ const mlir::Location &currentLocation, mlir::Region &region,
+ llvm::ArrayRef<const Fortran::semantics::Symbol *> mapSyms) {
+ for (auto [argIndex, argSymbol] : llvm::enumerate(mapSyms)) {
+ if (auto *details =
+ argSymbol->detailsIf<Fortran::semantics::CommonBlockDetails>()) {
+ for (auto obj : details->objects()) {
+ auto targetCBMemberBind = Fortran::lower::genCommonBlockMember(
+ converter, currentLocation, *obj, region.getArgument(argIndex));
+ fir::ExtendedValue sexv = converter.getSymbolExtendedValue(*obj);
+ fir::ExtendedValue targetCBExv =
+ getExtendedValue(sexv, targetCBMemberBind);
+ converter.bindSymbol(*obj, targetCBExv);
+ }
+ }
+ }
+}
+
// This functions creates a block for the body of the targetOp's region. It adds
// all the symbols present in mapSymbols as block arguments to this block.
static void
@@ -955,6 +982,16 @@ genBodyOfTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
// Create the insertion point after the marker.
firOpBuilder.setInsertionPointAfter(undefMarker.getDefiningOp());
+ // If we map a common block using it's symbol e.g. map(tofrom: /common_block/)
+ // and accessing it's members within the target region, there is a large
+ // chance we will end up with uses external to the region accessing the common
+ // resolve these, we do so by generating new common block member accesses
+ // within the region, binding them to the member symbol for the scope of the
+ // region so that subsequent code generation within the region will utilise
+ // our new member accesses we have created.
+ genIntermediateCommonBlockAccessors(converter, currentLocation, region,
+ mapSyms);
+
if (ConstructQueue::iterator next = std::next(item); next != queue.end()) {
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
next);
@@ -991,6 +1028,19 @@ static void genCriticalDeclareClauses(lower::AbstractConverter &converter,
mlir::StringAttr::get(converter.getFirOpBuilder().getContext(), name);
}
+static void genDistributeClauses(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::StatementContext &stmtCtx,
+ const List<Clause> &clauses,
+ mlir::Location loc,
+ mlir::omp::DistributeClauseOps &clauseOps) {
+ ClauseProcessor cp(converter, semaCtx, clauses);
+ cp.processAllocate(clauseOps);
+ cp.processDistSchedule(stmtCtx, clauseOps);
+ cp.processOrder(clauseOps);
+ // TODO Support delayed privatization.
+}
+
static void genFlushClauses(lower::AbstractConverter &converter,
semantics::SemanticsContext &semaCtx,
const ObjectList &objects,
@@ -1058,14 +1108,15 @@ static void genSimdClauses(lower::AbstractConverter &converter,
const List<Clause> &clauses, mlir::Location loc,
mlir::omp::SimdClauseOps &clauseOps) {
ClauseProcessor cp(converter, semaCtx, clauses);
+ cp.processAligned(clauseOps);
cp.processIf(llvm::omp::Directive::OMPD_simd, clauseOps);
+ cp.processOrder(clauseOps);
cp.processReduction(loc, clauseOps);
cp.processSafelen(clauseOps);
cp.processSimdlen(clauseOps);
- // TODO Support delayed privatization.
- cp.processTODO<clause::Aligned, clause::Allocate, clause::Linear,
- clause::Nontemporal, clause::Order>(
+ // TODO Support delayed privatization.
+ cp.processTODO<clause::Allocate, clause::Linear, clause::Nontemporal>(
loc, llvm::omp::Directive::OMPD_simd);
}
@@ -1231,12 +1282,13 @@ static void genWsloopClauses(
llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms) {
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processNowait(clauseOps);
+ cp.processOrder(clauseOps);
cp.processOrdered(clauseOps);
cp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms);
cp.processSchedule(stmtCtx, clauseOps);
// TODO Support delayed privatization.
- cp.processTODO<clause::Allocate, clause::Linear, clause::Order>(
+ cp.processTODO<clause::Allocate, clause::Linear>(
loc, llvm::omp::Directive::OMPD_do);
}
@@ -1288,8 +1340,50 @@ genDistributeOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval, mlir::Location loc,
const ConstructQueue &queue, ConstructQueue::iterator item) {
- TODO(loc, "Distribute construct");
- return nullptr;
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ symTable.pushScope();
+ DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
+ lower::omp::isLastItemInQueue(item, queue));
+ dsp.processStep1();
+
+ lower::StatementContext stmtCtx;
+ mlir::omp::LoopNestClauseOps loopClauseOps;
+ mlir::omp::DistributeClauseOps distributeClauseOps;
+ llvm::SmallVector<const semantics::Symbol *> iv;
+ genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
+ loopClauseOps, iv);
+ genDistributeClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
+ distributeClauseOps);
+
+ // Create omp.distribute wrapper.
+ auto distributeOp =
+ firOpBuilder.create<mlir::omp::DistributeOp>(loc, distributeClauseOps);
+
+ firOpBuilder.createBlock(&distributeOp.getRegion());
+ firOpBuilder.setInsertionPoint(
+ lower::genOpenMPTerminator(firOpBuilder, distributeOp, loc));
+
+ // Create nested omp.loop_nest and fill body with loop contents.
+ auto loopOp = firOpBuilder.create<mlir::omp::LoopNestOp>(loc, loopClauseOps);
+
+ auto *nestedEval =
+ getCollapsedLoopEval(eval, getCollapseValue(item->clauses));
+
+ auto ivCallback = [&](mlir::Operation *op) {
+ genLoopVars(op, converter, loc, iv);
+ return iv;
+ };
+
+ createBodyOfOp(*loopOp,
+ OpWithBodyGenInfo(converter, symTable, semaCtx, loc,
+ *nestedEval, llvm::omp::Directive::OMPD_simd)
+ .setClauses(&item->clauses)
+ .setDataSharingProcessor(&dsp)
+ .setGenRegionEntryCb(ivCallback),
+ queue, item);
+
+ symTable.popScope();
+ return distributeOp;
}
static mlir::omp::FlushOp
@@ -1616,6 +1710,13 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
if (dsp.getAllSymbolsToPrivatize().contains(&sym))
return;
+ // if the symbol is part of an already mapped common block, do not make a
+ // map for it.
+ if (const Fortran::semantics::Symbol *common =
+ Fortran::semantics::FindCommonBlockContaining(sym.GetUltimate()))
+ if (llvm::find(mapSyms, common) != mapSyms.end())
+ return;
+
if (llvm::find(mapSyms, &sym) == mapSyms.end()) {
mlir::Value baseOp = converter.getSymbolAddress(sym);
if (!baseOp)
@@ -1925,8 +2026,8 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter,
ConstructQueue::iterator item) {
ClauseProcessor cp(converter, semaCtx, item->clauses);
cp.processTODO<clause::Aligned, clause::Allocate, clause::Linear,
- clause::Order, clause::Safelen, clause::Simdlen>(
- loc, llvm::omp::OMPD_do_simd);
+ clause::Safelen, clause::Simdlen>(loc,
+ llvm::omp::OMPD_do_simd);
// TODO: Add support for vectorization - add vectorization hints inside loop
// body.
// OpenMP standard does not specify the length of vector instructions.
@@ -2145,7 +2246,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPDeclarativeConstruct &ompDeclConstruct) {
- std::visit(
+ Fortran::common::visit(
[&](auto &&s) { return genOMP(converter, symTable, semaCtx, eval, s); },
ompDeclConstruct.u);
}
@@ -2222,7 +2323,7 @@ static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
const parser::OpenMPStandaloneConstruct &standaloneConstruct) {
- std::visit(
+ Fortran::common::visit(
[&](auto &&s) { return genOMP(converter, symTable, semaCtx, eval, s); },
standaloneConstruct.u);
}
@@ -2242,7 +2343,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPAtomicConstruct &atomicConstruct) {
- std::visit(
+ Fortran::common::visit(
common::visitors{
[&](const parser::OmpAtomicRead &atomicRead) {
mlir::Location loc = converter.genLocation(atomicRead.source);
@@ -2433,7 +2534,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPConstruct &ompConstruct) {
- std::visit(
+ Fortran::common::visit(
[&](auto &&s) { return genOMP(converter, symTable, semaCtx, eval, s); },
ompConstruct.u);
}
@@ -2595,21 +2696,22 @@ void Fortran::lower::gatherOpenMPDeferredDeclareTargets(
const parser::OpenMPDeclarativeConstruct &ompDecl,
llvm::SmallVectorImpl<OMPDeferredDeclareTargetInfo>
&deferredDeclareTarget) {
- std::visit(common::visitors{
- [&](const parser::OpenMPDeclareTargetConstruct &ompReq) {
- collectDeferredDeclareTargets(converter, semaCtx, eval,
- ompReq, deferredDeclareTarget);
- },
- [&](const auto &) {},
- },
- ompDecl.u);
+ Fortran::common::visit(
+ common::visitors{
+ [&](const parser::OpenMPDeclareTargetConstruct &ompReq) {
+ collectDeferredDeclareTargets(converter, semaCtx, eval, ompReq,
+ deferredDeclareTarget);
+ },
+ [&](const auto &) {},
+ },
+ ompDecl.u);
}
bool Fortran::lower::isOpenMPDeviceDeclareTarget(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPDeclarativeConstruct &ompDecl) {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const parser::OpenMPDeclareTargetConstruct &ompReq) {
mlir::omp::DeclareTargetDeviceType targetType =
diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
index 60e933f5bc1f..c3c1f363033c 100644
--- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
@@ -332,7 +332,9 @@ static void genBoxCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
fir::unwrapRefType(boxTy.getEleTy()));
fir::HeapType heapTy =
mlir::dyn_cast_or_null<fir::HeapType>(boxTy.getEleTy());
- if ((!seqTy || seqTy.hasUnknownShape()) && !heapTy)
+ fir::PointerType ptrTy =
+ mlir::dyn_cast_or_null<fir::PointerType>(boxTy.getEleTy());
+ if ((!seqTy || seqTy.hasUnknownShape()) && !heapTy && !ptrTy)
TODO(loc, "Unsupported boxed type in OpenMP reduction");
// load fir.ref<fir.box<...>>
@@ -340,7 +342,7 @@ static void genBoxCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
lhs = builder.create<fir::LoadOp>(loc, lhs);
rhs = builder.create<fir::LoadOp>(loc, rhs);
- if (heapTy && !seqTy) {
+ if ((heapTy || ptrTy) && !seqTy) {
// get box contents (heap pointers)
lhs = builder.create<fir::BoxAddrOp>(loc, lhs);
rhs = builder.create<fir::BoxAddrOp>(loc, rhs);
@@ -350,8 +352,10 @@ static void genBoxCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
lhs = builder.create<fir::LoadOp>(loc, lhs);
rhs = builder.create<fir::LoadOp>(loc, rhs);
+ mlir::Type eleTy = heapTy ? heapTy.getEleTy() : ptrTy.getEleTy();
+
mlir::Value result = ReductionProcessor::createScalarCombiner(
- builder, loc, redId, heapTy.getEleTy(), lhs, rhs);
+ builder, loc, redId, eleTy, lhs, rhs);
builder.create<fir::StoreOp>(loc, result, lhsValAddr);
builder.create<mlir::omp::YieldOp>(loc, lhsAddr);
return;
@@ -439,7 +443,7 @@ createReductionCleanupRegion(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type valTy = fir::unwrapRefType(redTy);
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(valTy)) {
- if (!mlir::isa<fir::HeapType>(boxTy.getEleTy())) {
+ if (!mlir::isa<fir::HeapType, fir::PointerType>(boxTy.getEleTy())) {
mlir::Type innerTy = fir::extractSequenceType(boxTy);
if (!mlir::isa<fir::SequenceType>(innerTy))
typeError();
@@ -533,12 +537,13 @@ createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc,
// all arrays are boxed
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) {
assert(isByRef && "passing boxes by value is unsupported");
- bool isAllocatable = mlir::isa<fir::HeapType>(boxTy.getEleTy());
+ bool isAllocatableOrPointer =
+ mlir::isa<fir::HeapType, fir::PointerType>(boxTy.getEleTy());
mlir::Value boxAlloca = builder.create<fir::AllocaOp>(loc, ty);
mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
if (fir::isa_trivial(innerTy)) {
// boxed non-sequence value e.g. !fir.box<!fir.heap<i32>>
- if (!isAllocatable)
+ if (!isAllocatableOrPointer)
TODO(loc, "Reduction of non-allocatable trivial typed box");
fir::IfOp ifUnallocated = handleNullAllocatable(boxAlloca);
@@ -560,7 +565,7 @@ createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc,
TODO(loc, "Unsupported boxed type for reduction");
fir::IfOp ifUnallocated{nullptr};
- if (isAllocatable) {
+ if (isAllocatableOrPointer) {
ifUnallocated = handleNullAllocatable(boxAlloca);
builder.setInsertionPointToStart(&ifUnallocated.getElseRegion().front());
}
@@ -587,7 +592,8 @@ createReductionInitRegion(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::OpBuilder::InsertionGuard guard(builder);
createReductionCleanupRegion(builder, loc, reductionDecl);
} else {
- assert(!isAllocatable && "Allocatable arrays must be heap allocated");
+ assert(!isAllocatableOrPointer &&
+ "Pointer-like arrays must be heap allocated");
}
// Put the temporary inside of a box:
@@ -703,8 +709,8 @@ void ReductionProcessor::addDeclareReduction(
}
}
- // initial pass to collect all reduction vars so we can figure out if this
- // should happen byref
+ // Reduction variable processing common to both intrinsic operators and
+ // procedure designators
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
for (const Object &object : objectList) {
const semantics::Symbol *symbol = object.sym();
@@ -757,64 +763,56 @@ void ReductionProcessor::addDeclareReduction(
reduceVarByRef.push_back(doReductionByRef(symVal));
}
- if (const auto &redDefinedOp =
- std::get_if<omp::clause::DefinedOperator>(&redOperator.u)) {
- const auto &intrinsicOp{
- std::get<omp::clause::DefinedOperator::IntrinsicOperator>(
- redDefinedOp->u)};
- ReductionIdentifier redId = getReductionType(intrinsicOp);
- switch (redId) {
- case ReductionIdentifier::ADD:
- case ReductionIdentifier::MULTIPLY:
- case ReductionIdentifier::AND:
- case ReductionIdentifier::EQV:
- case ReductionIdentifier::OR:
- case ReductionIdentifier::NEQV:
- break;
- default:
- TODO(currentLocation,
- "Reduction of some intrinsic operators is not supported");
- break;
- }
+ for (auto [symVal, isByRef] : llvm::zip(reductionVars, reduceVarByRef)) {
+ auto redType = mlir::cast<fir::ReferenceType>(symVal.getType());
+ const auto &kindMap = firOpBuilder.getKindMap();
+ std::string reductionName;
+ ReductionIdentifier redId;
+ mlir::Type redNameTy = redType;
+ if (mlir::isa<fir::LogicalType>(redType.getEleTy()))
+ redNameTy = builder.getI1Type();
+
+ if (const auto &redDefinedOp =
+ std::get_if<omp::clause::DefinedOperator>(&redOperator.u)) {
+ const auto &intrinsicOp{
+ std::get<omp::clause::DefinedOperator::IntrinsicOperator>(
+ redDefinedOp->u)};
+ redId = getReductionType(intrinsicOp);
+ switch (redId) {
+ case ReductionIdentifier::ADD:
+ case ReductionIdentifier::MULTIPLY:
+ case ReductionIdentifier::AND:
+ case ReductionIdentifier::EQV:
+ case ReductionIdentifier::OR:
+ case ReductionIdentifier::NEQV:
+ break;
+ default:
+ TODO(currentLocation,
+ "Reduction of some intrinsic operators is not supported");
+ break;
+ }
- for (auto [symVal, isByRef] : llvm::zip(reductionVars, reduceVarByRef)) {
- auto redType = mlir::cast<fir::ReferenceType>(symVal.getType());
- const auto &kindMap = firOpBuilder.getKindMap();
- if (mlir::isa<fir::LogicalType>(redType.getEleTy()))
- decl = createDeclareReduction(firOpBuilder,
- getReductionName(intrinsicOp, kindMap,
- firOpBuilder.getI1Type(),
- isByRef),
- redId, redType, currentLocation, isByRef);
- else
- decl = createDeclareReduction(
- firOpBuilder,
- getReductionName(intrinsicOp, kindMap, redType, isByRef), redId,
- redType, currentLocation, isByRef);
- reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get(
- firOpBuilder.getContext(), decl.getSymName()));
- }
- } else if (const auto *reductionIntrinsic =
- std::get_if<omp::clause::ProcedureDesignator>(
- &redOperator.u)) {
- if (ReductionProcessor::supportedIntrinsicProcReduction(
- *reductionIntrinsic)) {
- ReductionProcessor::ReductionIdentifier redId =
- ReductionProcessor::getReductionType(*reductionIntrinsic);
- for (auto [symVal, isByRef] : llvm::zip(reductionVars, reduceVarByRef)) {
- auto redType = mlir::cast<fir::ReferenceType>(symVal.getType());
- if (!redType.getEleTy().isIntOrIndexOrFloat())
- TODO(currentLocation,
- "Reduction of some types is not supported for intrinsics");
- decl = createDeclareReduction(
- firOpBuilder,
- getReductionName(getRealName(*reductionIntrinsic).ToString(),
- firOpBuilder.getKindMap(), redType, isByRef),
- redId, redType, currentLocation, isByRef);
- reductionDeclSymbols.push_back(mlir::SymbolRefAttr::get(
- firOpBuilder.getContext(), decl.getSymName()));
+ reductionName =
+ getReductionName(intrinsicOp, kindMap, redNameTy, isByRef);
+ } else if (const auto *reductionIntrinsic =
+ std::get_if<omp::clause::ProcedureDesignator>(
+ &redOperator.u)) {
+ if (!ReductionProcessor::supportedIntrinsicProcReduction(
+ *reductionIntrinsic)) {
+ TODO(currentLocation, "Unsupported intrinsic proc reduction");
}
+ redId = getReductionType(*reductionIntrinsic);
+ reductionName =
+ getReductionName(getRealName(*reductionIntrinsic).ToString(), kindMap,
+ redNameTy, isByRef);
+ } else {
+ TODO(currentLocation, "Unexpected reduction type");
}
+
+ decl = createDeclareReduction(firOpBuilder, reductionName, redId, redType,
+ currentLocation, isByRef);
+ reductionDeclSymbols.push_back(
+ mlir::SymbolRefAttr::get(firOpBuilder.getContext(), decl.getSymName()));
}
}
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 36d96f37ff36..8aeef175ad2d 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -325,7 +325,7 @@ void insertChildMapInfoIntoParent(
semantics::Symbol *getOmpObjectSymbol(const parser::OmpObject &ompObject) {
semantics::Symbol *sym = nullptr;
- std::visit(
+ Fortran::common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (auto *arrayEle =
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index f196b9c5a0cb..5b3d5471925b 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -103,7 +103,7 @@ public:
stmt.unwrapped, pftParentStack.back(), stmt.position, stmt.label});
return false;
} else if constexpr (std::is_same_v<T, parser::ActionStmt>) {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const common::Indirection<parser::CallStmt> &x) {
addEvaluation(lower::pft::Evaluation{
@@ -209,6 +209,20 @@ public:
}
}
+ bool Pre(const parser::SpecificationPart &) {
+ ++specificationPartLevel;
+ return true;
+ }
+ void Post(const parser::SpecificationPart &) { --specificationPartLevel; }
+
+ bool Pre(const parser::ContainsStmt &) {
+ if (!specificationPartLevel) {
+ assert(containsStmtStack.size() && "empty contains stack");
+ containsStmtStack.back() = true;
+ }
+ return false;
+ }
+
// Module like
bool Pre(const parser::Module &node) { return enterModule(node); }
bool Pre(const parser::Submodule &node) { return enterModule(node); }
@@ -225,7 +239,7 @@ public:
// Get rid of production wrapper
bool Pre(const parser::Statement<parser::ForallAssignmentStmt> &statement) {
- addEvaluation(std::visit(
+ addEvaluation(Fortran::common::visit(
[&](const auto &x) {
return lower::pft::Evaluation{x, pftParentStack.back(),
statement.source, statement.label};
@@ -234,7 +248,7 @@ public:
return false;
}
bool Pre(const parser::WhereBodyConstruct &whereBody) {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const parser::Statement<parser::AssignmentStmt> &stmt) {
// Not caught as other AssignmentStmt because it is not
@@ -249,15 +263,21 @@ public:
whereBody.u);
}
- // CompilerDirective have special handling in case they are top level
- // directives (i.e. they do not belong to a ProgramUnit).
+ // A CompilerDirective may appear outside any program unit, after a module
+ // or function contains statement, or inside a module or function.
bool Pre(const parser::CompilerDirective &directive) {
- assert(pftParentStack.size() > 0 &&
- "At least the Program must be a parent");
- if (pftParentStack.back().isA<lower::pft::Program>()) {
- addUnit(
- lower::pft::CompilerDirectiveUnit(directive, pftParentStack.back()));
+ assert(pftParentStack.size() > 0 && "no program");
+ lower::pft::PftNode &node = pftParentStack.back();
+ if (node.isA<lower::pft::Program>()) {
+ addUnit(lower::pft::CompilerDirectiveUnit(directive, node));
return false;
+ } else if ((node.isA<lower::pft::ModuleLikeUnit>() ||
+ node.isA<lower::pft::FunctionLikeUnit>())) {
+ assert(containsStmtStack.size() && "empty contains stack");
+ if (containsStmtStack.back()) {
+ addContainedUnit(lower::pft::CompilerDirectiveUnit{directive, node});
+ return false;
+ }
}
return enterConstructOrDirective(directive);
}
@@ -277,9 +297,10 @@ private:
/// Initialize a new module-like unit and make it the builder's focus.
template <typename A>
bool enterModule(const A &mod) {
- Fortran::lower::pft::ModuleLikeUnit &unit =
+ lower::pft::ModuleLikeUnit &unit =
addUnit(lower::pft::ModuleLikeUnit{mod, pftParentStack.back()});
- functionList = &unit.nestedFunctions;
+ containsStmtStack.push_back(false);
+ containedUnitList = &unit.containedUnitList;
pushEvaluationList(&unit.evaluationList);
pftParentStack.emplace_back(unit);
LLVM_DEBUG(dumpScope(&unit.getScope()));
@@ -287,6 +308,7 @@ private:
}
void exitModule() {
+ containsStmtStack.pop_back();
if (!evaluationListStack.empty())
popEvaluationList();
pftParentStack.pop_back();
@@ -344,12 +366,13 @@ private:
const semantics::SemanticsContext &semanticsContext) {
cleanModuleEvaluationList();
endFunctionBody(); // enclosing host subprogram body, if any
- Fortran::lower::pft::FunctionLikeUnit &unit =
- addFunction(lower::pft::FunctionLikeUnit{func, pftParentStack.back(),
- semanticsContext});
+ lower::pft::FunctionLikeUnit &unit =
+ addContainedUnit(lower::pft::FunctionLikeUnit{
+ func, pftParentStack.back(), semanticsContext});
labelEvaluationMap = &unit.labelEvaluationMap;
assignSymbolLabelMap = &unit.assignSymbolLabelMap;
- functionList = &unit.nestedFunctions;
+ containsStmtStack.push_back(false);
+ containedUnitList = &unit.containedUnitList;
pushEvaluationList(&unit.evaluationList);
pftParentStack.emplace_back(unit);
LLVM_DEBUG(dumpScope(&unit.getScope()));
@@ -361,6 +384,7 @@ private:
endFunctionBody();
analyzeBranches(nullptr, *evaluationListStack.back()); // add branch links
processEntryPoints();
+ containsStmtStack.pop_back();
popEvaluationList();
labelEvaluationMap = nullptr;
assignSymbolLabelMap = nullptr;
@@ -371,7 +395,7 @@ private:
/// Initialize a new construct or directive and make it the builder's focus.
template <typename A>
bool enterConstructOrDirective(const A &constructOrDirective) {
- Fortran::lower::pft::Evaluation &eval = addEvaluation(
+ lower::pft::Evaluation &eval = addEvaluation(
lower::pft::Evaluation{constructOrDirective, pftParentStack.back()});
eval.evaluationList.reset(new lower::pft::EvaluationList);
pushEvaluationList(eval.evaluationList.get());
@@ -381,7 +405,7 @@ private:
}
void exitConstructOrDirective() {
- auto isOpenMPLoopConstruct = [](Fortran::lower::pft::Evaluation *eval) {
+ auto isOpenMPLoopConstruct = [](lower::pft::Evaluation *eval) {
if (const auto *ompConstruct = eval->getIf<parser::OpenMPConstruct>())
if (std::holds_alternative<parser::OpenMPLoopConstruct>(
ompConstruct->u))
@@ -396,8 +420,7 @@ private:
// construct region must have an exit target inside the region.
// This is not applicable to the OpenMP loop construct since the
// end of the loop is an available target inside the region.
- Fortran::lower::pft::EvaluationList &evaluationList =
- *eval->evaluationList;
+ lower::pft::EvaluationList &evaluationList = *eval->evaluationList;
if (!evaluationList.empty() && evaluationList.back().isConstruct()) {
static const parser::ContinueStmt exitTarget{};
addEvaluation(
@@ -413,15 +436,15 @@ private:
void resetFunctionState() {
if (!pftParentStack.empty()) {
pftParentStack.back().visit(common::visitors{
+ [&](lower::pft::ModuleLikeUnit &p) {
+ containedUnitList = &p.containedUnitList;
+ },
[&](lower::pft::FunctionLikeUnit &p) {
- functionList = &p.nestedFunctions;
+ containedUnitList = &p.containedUnitList;
labelEvaluationMap = &p.labelEvaluationMap;
assignSymbolLabelMap = &p.assignSymbolLabelMap;
},
- [&](lower::pft::ModuleLikeUnit &p) {
- functionList = &p.nestedFunctions;
- },
- [&](auto &) { functionList = nullptr; },
+ [&](auto &) { containedUnitList = nullptr; },
});
}
}
@@ -433,12 +456,11 @@ private:
}
template <typename A>
- A &addFunction(A &&func) {
- if (functionList) {
- functionList->emplace_back(std::move(func));
- return functionList->back();
- }
- return addUnit(std::move(func));
+ A &addContainedUnit(A &&unit) {
+ if (!containedUnitList)
+ return addUnit(std::move(unit));
+ containedUnitList->emplace_back(std::move(unit));
+ return std::get<A>(containedUnitList->back());
}
// ActionStmt has a couple of non-conforming cases, explicitly handled here.
@@ -447,7 +469,7 @@ private:
makeEvaluationAction(const parser::ActionStmt &statement,
parser::CharBlock position,
std::optional<parser::Label> label) {
- return std::visit(
+ return Fortran::common::visit(
common::visitors{
[&](const auto &x) {
return lower::pft::Evaluation{
@@ -459,7 +481,6 @@ private:
/// Append an Evaluation to the end of the current list.
lower::pft::Evaluation &addEvaluation(lower::pft::Evaluation &&eval) {
- assert(functionList && "not in a function");
assert(!evaluationListStack.empty() && "empty evaluation list stack");
if (!constructAndDirectiveStack.empty())
eval.parentConstruct = constructAndDirectiveStack.back();
@@ -499,15 +520,15 @@ private:
/// push a new list on the stack of Evaluation lists
void pushEvaluationList(lower::pft::EvaluationList *evaluationList) {
- assert(functionList && "not in a function");
assert(evaluationList && evaluationList->empty() &&
- "evaluation list isn't correct");
+ "invalid evaluation list");
evaluationListStack.emplace_back(evaluationList);
}
/// pop the current list and return to the last Evaluation list
void popEvaluationList() {
- assert(functionList && "not in a function");
+ assert(!evaluationListStack.empty() &&
+ "trying to pop an empty evaluationListStack");
evaluationListStack.pop_back();
}
@@ -643,7 +664,7 @@ private:
};
auto analyzeSpecs{[&](const auto &specList) {
for (const auto &spec : specList) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::Format &format) {
analyzeFormatSpec(format);
@@ -1089,9 +1110,8 @@ private:
std::vector<lower::pft::PftNode> pftParentStack;
const semantics::SemanticsContext &semanticsContext;
- /// functionList points to the internal or module procedure function list
- /// of a FunctionLikeUnit or a ModuleLikeUnit. It may be null.
- std::list<lower::pft::FunctionLikeUnit> *functionList{};
+ llvm::SmallVector<bool> containsStmtStack{};
+ lower::pft::ContainedUnitList *containedUnitList{};
std::vector<lower::pft::Evaluation *> constructAndDirectiveStack{};
std::vector<lower::pft::Evaluation *> doConstructStack{};
/// evaluationListStack is the current nested construct evaluationList state.
@@ -1099,6 +1119,7 @@ private:
llvm::DenseMap<parser::Label, lower::pft::Evaluation *> *labelEvaluationMap{};
lower::pft::SymbolLabelMap *assignSymbolLabelMap{};
std::map<std::string, lower::pft::Evaluation *> constructNameMap{};
+ int specificationPartLevel{};
lower::pft::Evaluation *lastLexicalEvaluation{};
};
@@ -1151,26 +1172,27 @@ public:
void dumpPFT(llvm::raw_ostream &outputStream,
const lower::pft::Program &pft) {
for (auto &unit : pft.getUnits()) {
- std::visit(common::visitors{
- [&](const lower::pft::BlockDataUnit &unit) {
- outputStream << getNodeIndex(unit) << " ";
- outputStream << "BlockData: ";
- outputStream << "\nEnd BlockData\n\n";
- },
- [&](const lower::pft::FunctionLikeUnit &func) {
- dumpFunctionLikeUnit(outputStream, func);
- },
- [&](const lower::pft::ModuleLikeUnit &unit) {
- dumpModuleLikeUnit(outputStream, unit);
- },
- [&](const lower::pft::CompilerDirectiveUnit &unit) {
- dumpCompilerDirectiveUnit(outputStream, unit);
- },
- [&](const lower::pft::OpenACCDirectiveUnit &unit) {
- dumpOpenACCDirectiveUnit(outputStream, unit);
- },
- },
- unit);
+ Fortran::common::visit(
+ common::visitors{
+ [&](const lower::pft::BlockDataUnit &unit) {
+ outputStream << getNodeIndex(unit) << " ";
+ outputStream << "BlockData: ";
+ outputStream << "\nEnd BlockData\n\n";
+ },
+ [&](const lower::pft::FunctionLikeUnit &func) {
+ dumpFunctionLikeUnit(outputStream, func);
+ },
+ [&](const lower::pft::ModuleLikeUnit &unit) {
+ dumpModuleLikeUnit(outputStream, unit);
+ },
+ [&](const lower::pft::CompilerDirectiveUnit &unit) {
+ dumpCompilerDirectiveUnit(outputStream, unit);
+ },
+ [&](const lower::pft::OpenACCDirectiveUnit &unit) {
+ dumpOpenACCDirectiveUnit(outputStream, unit);
+ },
+ },
+ unit);
}
}
@@ -1201,11 +1223,15 @@ public:
outputStream << " -> " << eval.controlSuccessor->printIndex;
else if (eval.isA<parser::EntryStmt>() && eval.lexicalSuccessor)
outputStream << " -> " << eval.lexicalSuccessor->printIndex;
+ bool extraNewline = false;
if (!eval.position.empty())
outputStream << ": " << eval.position.ToString();
- else if (auto *dir = eval.getIf<Fortran::parser::CompilerDirective>())
+ else if (auto *dir = eval.getIf<parser::CompilerDirective>()) {
+ extraNewline = dir->source.ToString().back() == '\n';
outputStream << ": !" << dir->source.ToString();
- outputStream << '\n';
+ }
+ if (!extraNewline)
+ outputStream << '\n';
if (eval.hasNestedEvaluations()) {
dumpEvaluationList(outputStream, *eval.evaluationList, indent + 1);
outputStream << indentString << "<<End " << name << bang << ">>\n";
@@ -1265,13 +1291,7 @@ public:
outputStream << ": " << header;
outputStream << '\n';
dumpEvaluationList(outputStream, functionLikeUnit.evaluationList);
- if (!functionLikeUnit.nestedFunctions.empty()) {
- outputStream << "\nContains\n";
- for (const lower::pft::FunctionLikeUnit &func :
- functionLikeUnit.nestedFunctions)
- dumpFunctionLikeUnit(outputStream, func);
- outputStream << "End Contains\n";
- }
+ dumpContainedUnitList(outputStream, functionLikeUnit.containedUnitList);
outputStream << "End " << unitKind << ' ' << name << "\n\n";
}
@@ -1298,11 +1318,8 @@ public:
});
outputStream << unitKind << ' ' << name << ": " << header << '\n';
dumpEvaluationList(outputStream, moduleLikeUnit.evaluationList);
- outputStream << "Contains\n";
- for (const lower::pft::FunctionLikeUnit &func :
- moduleLikeUnit.nestedFunctions)
- dumpFunctionLikeUnit(outputStream, func);
- outputStream << "End Contains\nEnd " << unitKind << ' ' << name << "\n\n";
+ dumpContainedUnitList(outputStream, moduleLikeUnit.containedUnitList);
+ outputStream << "End " << unitKind << ' ' << name << "\n\n";
}
// Top level directives
@@ -1311,9 +1328,34 @@ public:
const lower::pft::CompilerDirectiveUnit &directive) {
outputStream << getNodeIndex(directive) << " ";
outputStream << "CompilerDirective: !";
- outputStream << directive.get<Fortran::parser::CompilerDirective>()
- .source.ToString();
- outputStream << "\nEnd CompilerDirective\n\n";
+ bool extraNewline =
+ directive.get<parser::CompilerDirective>().source.ToString().back() ==
+ '\n';
+ outputStream
+ << directive.get<parser::CompilerDirective>().source.ToString();
+ if (!extraNewline)
+ outputStream << "\n";
+ outputStream << "\n";
+ }
+
+ void dumpContainedUnitList(
+ llvm::raw_ostream &outputStream,
+ const lower::pft::ContainedUnitList &containedUnitList) {
+ if (containedUnitList.empty())
+ return;
+ outputStream << "\nContains\n";
+ for (const lower::pft::ContainedUnit &unit : containedUnitList)
+ if (const auto *func = std::get_if<lower::pft::FunctionLikeUnit>(&unit)) {
+ dumpFunctionLikeUnit(outputStream, *func);
+ } else if (const auto *dir =
+ std::get_if<lower::pft::CompilerDirectiveUnit>(&unit)) {
+ outputStream << getNodeIndex(*dir) << " ";
+ dumpEvaluation(outputStream,
+ lower::pft::Evaluation{
+ dir->get<parser::CompilerDirective>(), dir->parent});
+ outputStream << "\n";
+ }
+ outputStream << "End Contains\n";
}
void
@@ -1321,8 +1363,8 @@ public:
const lower::pft::OpenACCDirectiveUnit &directive) {
outputStream << getNodeIndex(directive) << " ";
outputStream << "OpenACCDirective: !$acc ";
- outputStream << directive.get<Fortran::parser::OpenACCRoutineConstruct>()
- .source.ToString();
+ outputStream
+ << directive.get<parser::OpenACCRoutineConstruct>().source.ToString();
outputStream << "\nEnd OpenACCDirective\n\n";
}
diff --git a/flang/lib/Lower/VectorSubscripts.cpp b/flang/lib/Lower/VectorSubscripts.cpp
index d7a311d32d59..389a89ddcf10 100644
--- a/flang/lib/Lower/VectorSubscripts.cpp
+++ b/flang/lib/Lower/VectorSubscripts.cpp
@@ -55,10 +55,11 @@ private:
using Designator = Fortran::evaluate::Designator<T>;
if constexpr (Fortran::common::HasMember<Designator, ExprVariant>) {
const auto &designator = std::get<Designator>(expr.u);
- return std::visit([&](const auto &x) { return gen(x); }, designator.u);
+ return Fortran::common::visit([&](const auto &x) { return gen(x); },
+ designator.u);
} else {
- return std::visit([&](const auto &x) { return genDesignator(x); },
- expr.u);
+ return Fortran::common::visit(
+ [&](const auto &x) { return genDesignator(x); }, expr.u);
}
}
@@ -66,8 +67,8 @@ private:
// type of X elements.
mlir::Type gen(const Fortran::evaluate::DataRef &dataRef) {
- return std::visit([&](const auto &ref) -> mlir::Type { return gen(ref); },
- dataRef.u);
+ return Fortran::common::visit(
+ [&](const auto &ref) -> mlir::Type { return gen(ref); }, dataRef.u);
}
mlir::Type gen(const Fortran::evaluate::SymbolRef &symRef) {
@@ -128,7 +129,7 @@ private:
mlir::Type gen(const Fortran::evaluate::ArrayRef &arrayRef) {
auto isTripletOrVector =
[](const Fortran::evaluate::Subscript &subscript) -> bool {
- return std::visit(
+ return Fortran::common::visit(
Fortran::common::visitors{
[](const Fortran::evaluate::IndirectSubscriptIntegerExpr &expr) {
return expr.value().Rank() != 0;
@@ -165,7 +166,7 @@ private:
mlir::Type idxTy = builder.getIndexType();
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
for (const auto &subscript : llvm::enumerate(arrayRef.subscript())) {
- std::visit(
+ Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::evaluate::IndirectSubscriptIntegerExpr &expr) {
if (expr.value().Rank() == 0) {
@@ -327,24 +328,24 @@ Fortran::lower::VectorSubscriptBox::createSlice(fir::FirOpBuilder &builder,
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
auto undef = builder.create<fir::UndefOp>(loc, idxTy);
for (const LoweredSubscript &subscript : loweredSubscripts)
- std::visit(Fortran::common::visitors{
- [&](const LoweredTriplet &triplet) {
- triples.emplace_back(triplet.lb);
- triples.emplace_back(triplet.ub);
- triples.emplace_back(triplet.stride);
- },
- [&](const LoweredVectorSubscript &vector) {
- triples.emplace_back(one);
- triples.emplace_back(vector.size);
- triples.emplace_back(one);
- },
- [&](const mlir::Value &i) {
- triples.emplace_back(i);
- triples.emplace_back(undef);
- triples.emplace_back(undef);
- },
- },
- subscript);
+ Fortran::common::visit(Fortran::common::visitors{
+ [&](const LoweredTriplet &triplet) {
+ triples.emplace_back(triplet.lb);
+ triples.emplace_back(triplet.ub);
+ triples.emplace_back(triplet.stride);
+ },
+ [&](const LoweredVectorSubscript &vector) {
+ triples.emplace_back(one);
+ triples.emplace_back(vector.size);
+ triples.emplace_back(one);
+ },
+ [&](const mlir::Value &i) {
+ triples.emplace_back(i);
+ triples.emplace_back(undef);
+ triples.emplace_back(undef);
+ },
+ },
+ subscript);
return builder.create<fir::SliceOp>(loc, triples, componentPath);
}
@@ -390,28 +391,28 @@ fir::ExtendedValue Fortran::lower::VectorSubscriptBox::getElementAt(
llvm::SmallVector<mlir::Value> indexes;
size_t inductionIdx = inductionVariables.size() - 1;
for (const LoweredSubscript &subscript : loweredSubscripts)
- std::visit(Fortran::common::visitors{
- [&](const LoweredTriplet &triplet) {
- indexes.emplace_back(inductionVariables[inductionIdx--]);
- },
- [&](const LoweredVectorSubscript &vector) {
- mlir::Value vecIndex = inductionVariables[inductionIdx--];
- mlir::Value vecBase = fir::getBase(vector.vector);
- mlir::Type vecEleTy = fir::unwrapSequenceType(
- fir::unwrapPassByRefType(vecBase.getType()));
- mlir::Type refTy = builder.getRefType(vecEleTy);
- auto vecEltRef = builder.create<fir::CoordinateOp>(
- loc, refTy, vecBase, vecIndex);
- auto vecElt =
- builder.create<fir::LoadOp>(loc, vecEleTy, vecEltRef);
- indexes.emplace_back(
- builder.createConvert(loc, idxTy, vecElt));
- },
- [&](const mlir::Value &i) {
- indexes.emplace_back(builder.createConvert(loc, idxTy, i));
- },
- },
- subscript);
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const LoweredTriplet &triplet) {
+ indexes.emplace_back(inductionVariables[inductionIdx--]);
+ },
+ [&](const LoweredVectorSubscript &vector) {
+ mlir::Value vecIndex = inductionVariables[inductionIdx--];
+ mlir::Value vecBase = fir::getBase(vector.vector);
+ mlir::Type vecEleTy = fir::unwrapSequenceType(
+ fir::unwrapPassByRefType(vecBase.getType()));
+ mlir::Type refTy = builder.getRefType(vecEleTy);
+ auto vecEltRef = builder.create<fir::CoordinateOp>(
+ loc, refTy, vecBase, vecIndex);
+ auto vecElt =
+ builder.create<fir::LoadOp>(loc, vecEleTy, vecEltRef);
+ indexes.emplace_back(builder.createConvert(loc, idxTy, vecElt));
+ },
+ [&](const mlir::Value &i) {
+ indexes.emplace_back(builder.createConvert(loc, idxTy, i));
+ },
+ },
+ subscript);
mlir::Type refTy = builder.getRefType(getElementType());
auto elementAddr = builder.create<fir::ArrayCoorOp>(
loc, refTy, fir::getBase(loweredBase), shape, slice, indexes,
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 31e2c4082b32..8d0ae2f19517 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -882,10 +882,15 @@ static fir::ExtendedValue translateVariableToExtendedValue(
mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity variable,
bool forceHlfirBase = false, bool contiguousHint = false) {
assert(variable.isVariable() && "must be a variable");
- /// When going towards FIR, use the original base value to avoid
- /// introducing descriptors at runtime when they are not required.
- mlir::Value base =
- forceHlfirBase ? variable.getBase() : variable.getFirBase();
+ // When going towards FIR, use the original base value to avoid
+ // introducing descriptors at runtime when they are not required.
+ // This is not done for assumed-rank since the fir::ExtendedValue cannot
+ // held the related lower bounds in an vector. The lower bounds of the
+ // descriptor must always be used instead.
+
+ mlir::Value base = (forceHlfirBase || variable.isAssumedRank())
+ ? variable.getBase()
+ : variable.getFirBase();
if (variable.isMutableBox())
return fir::MutableBoxValue(base, getExplicitTypeParams(variable),
fir::MutableProperties{});
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 861b26de0637..8dd1904939f3 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -224,6 +224,7 @@ static constexpr IntrinsicHandler handlers[]{
{"boundary", asBox, handleDynamicOptional},
{"dim", asValue}}},
/*isElemental=*/false},
+ {"erfc_scaled", &I::genErfcScaled},
{"etime",
&I::genEtime,
{{{"values", asBox}, {"time", asBox}}},
@@ -526,8 +527,8 @@ static constexpr IntrinsicHandler handlers[]{
{"operation", asAddr},
{"dim", asValue},
{"mask", asBox, handleDynamicOptional},
- {"identity", asValue},
- {"ordered", asValue}}},
+ {"identity", asAddr, handleDynamicOptional},
+ {"ordered", asValue, handleDynamicOptional}}},
/*isElemental=*/false},
{"repeat",
&I::genRepeat,
@@ -1787,7 +1788,7 @@ IntrinsicLibrary::genIntrinsicCall(llvm::StringRef specificName,
llvm::StringRef name = genericName(specificName);
if (const IntrinsicHandler *handler = findIntrinsicHandler(name)) {
bool outline = handler->outline || outlineAllIntrinsics;
- return {std::visit(
+ return {Fortran::common::visit(
[&](auto &generator) -> fir::ExtendedValue {
return invokeHandler(generator, *handler, resultType, args,
outline, *this);
@@ -1801,7 +1802,7 @@ IntrinsicLibrary::genIntrinsicCall(llvm::StringRef specificName,
if (fir::getTargetTriple(mod).isPPC()) {
if (const IntrinsicHandler *ppcHandler = findPPCIntrinsicHandler(name)) {
bool outline = ppcHandler->outline || outlineAllIntrinsics;
- return {std::visit(
+ return {Fortran::common::visit(
[&](auto &generator) -> fir::ExtendedValue {
return invokeHandler(generator, *ppcHandler, resultType,
args, outline, *this);
@@ -2135,7 +2136,7 @@ mlir::SymbolRefAttr IntrinsicLibrary::getUnrestrictedIntrinsicSymbolRefAttr(
bool loadRefArguments = true;
mlir::func::FuncOp funcOp;
if (const IntrinsicHandler *handler = findIntrinsicHandler(name))
- funcOp = std::visit(
+ funcOp = Fortran::common::visit(
[&](auto generator) {
return getWrapper(generator, name, signature, loadRefArguments);
},
@@ -5736,7 +5737,91 @@ void IntrinsicLibrary::genRandomSeed(llvm::ArrayRef<fir::ExtendedValue> args) {
fir::ExtendedValue
IntrinsicLibrary::genReduce(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
- TODO(loc, "intrinsic: reduce");
+ assert(args.size() == 6);
+
+ fir::BoxValue arrayTmp = builder.createBox(loc, args[0]);
+ mlir::Value array = fir::getBase(arrayTmp);
+ mlir::Value operation = fir::getBase(args[1]);
+ int rank = arrayTmp.rank();
+ assert(rank >= 1);
+
+ // Arguements to the reduction operation are passed by reference or value?
+ bool argByRef = true;
+ if (!operation.getDefiningOp())
+ TODO(loc, "Distinguigh dummy procedure arguments");
+ if (auto embox =
+ mlir::dyn_cast_or_null<fir::EmboxProcOp>(operation.getDefiningOp())) {
+ auto fctTy = mlir::dyn_cast<mlir::FunctionType>(embox.getFunc().getType());
+ argByRef = mlir::isa<fir::ReferenceType>(fctTy.getInput(0));
+ } else if (auto load = mlir::dyn_cast_or_null<fir::LoadOp>(
+ operation.getDefiningOp())) {
+ auto boxProcTy = mlir::dyn_cast_or_null<fir::BoxProcType>(load.getType());
+ assert(boxProcTy && "expect BoxProcType");
+ auto fctTy = mlir::dyn_cast<mlir::FunctionType>(boxProcTy.getEleTy());
+ argByRef = mlir::isa<fir::ReferenceType>(fctTy.getInput(0));
+ }
+
+ mlir::Type ty = array.getType();
+ mlir::Type arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
+ mlir::Type eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+
+ // Handle optional arguments
+ bool absentDim = isStaticallyAbsent(args[2]);
+
+ auto mask = isStaticallyAbsent(args[3])
+ ? builder.create<fir::AbsentOp>(
+ loc, fir::BoxType::get(builder.getI1Type()))
+ : builder.createBox(loc, args[3]);
+
+ mlir::Value identity =
+ isStaticallyAbsent(args[4])
+ ? builder.create<fir::AbsentOp>(loc, fir::ReferenceType::get(eleTy))
+ : fir::getBase(args[4]);
+
+ mlir::Value ordered = isStaticallyAbsent(args[5])
+ ? builder.createBool(loc, false)
+ : fir::getBase(args[5]);
+
+ // We call the type specific versions because the result is scalar
+ // in the case below.
+ if (absentDim || rank == 1) {
+ if (fir::isa_complex(eleTy) || fir::isa_derived(eleTy)) {
+ mlir::Value result = builder.createTemporary(loc, eleTy);
+ fir::runtime::genReduce(builder, loc, array, operation, mask, identity,
+ ordered, result, argByRef);
+ if (fir::isa_derived(eleTy))
+ return result;
+ return builder.create<fir::LoadOp>(loc, result);
+ }
+ if (fir::isa_char(eleTy)) {
+ auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(resultType);
+ assert(charTy && "expect CharacterType");
+ fir::factory::CharacterExprHelper charHelper(builder, loc);
+ mlir::Value len;
+ if (charTy.hasDynamicLen())
+ len = charHelper.readLengthFromBox(fir::getBase(arrayTmp), charTy);
+ else
+ len = builder.createIntegerConstant(loc, builder.getI32Type(),
+ charTy.getLen());
+ fir::CharBoxValue temp = charHelper.createCharacterTemp(eleTy, len);
+ fir::runtime::genReduce(builder, loc, array, operation, mask, identity,
+ ordered, temp.getBuffer(), argByRef);
+ return temp;
+ }
+ return fir::runtime::genReduce(builder, loc, array, operation, mask,
+ identity, ordered, argByRef);
+ }
+ // Handle cases that have an array result.
+ // Create mutable fir.box to be passed to the runtime for the result.
+ mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, rank - 1);
+ fir::MutableBoxValue resultMutableBox =
+ fir::factory::createTempMutableBox(builder, loc, resultArrayType);
+ mlir::Value resultIrBox =
+ fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
+ mlir::Value dim = fir::getBase(args[2]);
+ fir::runtime::genReduceDim(builder, loc, array, operation, dim, mask,
+ identity, ordered, resultIrBox, argByRef);
+ return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE");
}
// REPEAT
@@ -5814,6 +5899,16 @@ mlir::Value IntrinsicLibrary::genRRSpacing(mlir::Type resultType,
fir::runtime::genRRSpacing(builder, loc, fir::getBase(args[0])));
}
+// ERFC_SCALED
+mlir::Value IntrinsicLibrary::genErfcScaled(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+
+ return builder.createConvert(
+ loc, resultType,
+ fir::runtime::genErfcScaled(builder, loc, fir::getBase(args[0])));
+}
+
// SAME_TYPE_AS
fir::ExtendedValue
IntrinsicLibrary::genSameTypeAs(mlir::Type resultType,
@@ -5992,15 +6087,93 @@ mlir::Value IntrinsicLibrary::genSetExponent(mlir::Type resultType,
fir::getBase(args[1])));
}
+/// Create a fir.box to be passed to the LBOUND/UBOUND runtime.
+/// This ensure that local lower bounds of assumed shape are propagated and that
+/// a fir.box with equivalent LBOUNDs.
+static mlir::Value
+createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder,
+ const fir::ExtendedValue &array) {
+ // Assumed-rank descriptor must always carry accurate lower bound information
+ // in lowering since they cannot be tracked on the side in a vector at compile
+ // time.
+ if (array.hasAssumedRank())
+ return builder.createBox(loc, array);
+
+ return array.match(
+ [&](const fir::BoxValue &boxValue) -> mlir::Value {
+ // This entity is mapped to a fir.box that may not contain the local
+ // lower bound information if it is a dummy. Rebox it with the local
+ // shape information.
+ mlir::Value localShape = builder.createShape(loc, array);
+ mlir::Value oldBox = boxValue.getAddr();
+ return builder.create<fir::ReboxOp>(loc, oldBox.getType(), oldBox,
+ localShape,
+ /*slice=*/mlir::Value{});
+ },
+ [&](const auto &) -> mlir::Value {
+ // This is a pointer/allocatable, or an entity not yet tracked with a
+ // fir.box. For pointer/allocatable, createBox will forward the
+ // descriptor that contains the correct lower bound information. For
+ // other entities, a new fir.box will be made with the local lower
+ // bounds.
+ return builder.createBox(loc, array);
+ });
+}
+
+/// Generate runtime call to inquire about all the bounds/extents of an
+/// array (or an assumed-rank).
+template <typename Func>
+static fir::ExtendedValue
+genBoundInquiry(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args,
+ int kindPos, Func genRtCall, bool needAccurateLowerBound) {
+ const fir::ExtendedValue &array = args[0];
+ const bool hasAssumedRank = array.hasAssumedRank();
+ mlir::Type resultElementType = fir::unwrapSequenceType(resultType);
+ // For assumed-rank arrays, allocate an array with the maximum rank, that is
+ // big enough to hold the result but still "small" (15 elements). Static size
+ // alloca make stack analysis/manipulation easier.
+ int rank = hasAssumedRank ? Fortran::common::maxRank : array.rank();
+ mlir::Type allocSeqType = fir::SequenceType::get(rank, resultElementType);
+ mlir::Value resultStorage = builder.createTemporary(loc, allocSeqType);
+ mlir::Value arrayBox =
+ needAccurateLowerBound
+ ? createBoxForRuntimeBoundInquiry(loc, builder, array)
+ : builder.createBox(loc, array);
+ mlir::Value kind = isStaticallyAbsent(args, kindPos)
+ ? builder.createIntegerConstant(
+ loc, builder.getI32Type(),
+ builder.getKindMap().defaultIntegerKind())
+ : fir::getBase(args[kindPos]);
+ genRtCall(builder, loc, resultStorage, arrayBox, kind);
+ if (hasAssumedRank) {
+ // Cast to fir.ref<array<?xik>> since the result extent is not a compile
+ // time constant.
+ mlir::Type baseType =
+ fir::ReferenceType::get(builder.getVarLenSeqTy(resultElementType));
+ mlir::Value resultBase =
+ builder.createConvert(loc, baseType, resultStorage);
+ mlir::Value rankValue =
+ builder.create<fir::BoxRankOp>(loc, builder.getIndexType(), arrayBox);
+ return fir::ArrayBoxValue{resultBase, {rankValue}};
+ }
+ // Result extent is a compile time constant in the other cases.
+ mlir::Value rankValue =
+ builder.createIntegerConstant(loc, builder.getIndexType(), rank);
+ return fir::ArrayBoxValue{resultStorage, {rankValue}};
+}
+
// SHAPE
fir::ExtendedValue
IntrinsicLibrary::genShape(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() >= 1);
const fir::ExtendedValue &array = args[0];
+ if (array.hasAssumedRank())
+ return genBoundInquiry(builder, loc, resultType, args,
+ /*kindPos=*/1, fir::runtime::genShape,
+ /*needAccurateLowerBound=*/false);
int rank = array.rank();
- if (rank == 0)
- TODO(loc, "shape intrinsic lowering with assumed-rank source");
mlir::Type indexType = builder.getIndexType();
mlir::Type extentType = fir::unwrapSequenceType(resultType);
mlir::Type seqType = fir::SequenceType::get(
@@ -6235,49 +6408,26 @@ static mlir::Value computeLBOUND(fir::FirOpBuilder &builder, mlir::Location loc,
return builder.create<mlir::arith::SelectOp>(loc, dimIsEmpty, one, lb);
}
-/// Create a fir.box to be passed to the LBOUND/UBOUND runtime.
-/// This ensure that local lower bounds of assumed shape are propagated and that
-/// a fir.box with equivalent LBOUNDs.
-static mlir::Value
-createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder,
- const fir::ExtendedValue &array) {
- return array.match(
- [&](const fir::BoxValue &boxValue) -> mlir::Value {
- // This entity is mapped to a fir.box that may not contain the local
- // lower bound information if it is a dummy. Rebox it with the local
- // shape information.
- mlir::Value localShape = builder.createShape(loc, array);
- mlir::Value oldBox = boxValue.getAddr();
- return builder.create<fir::ReboxOp>(loc, oldBox.getType(), oldBox,
- localShape,
- /*slice=*/mlir::Value{});
- },
- [&](const auto &) -> mlir::Value {
- // This is a pointer/allocatable, or an entity not yet tracked with a
- // fir.box. For pointer/allocatable, createBox will forward the
- // descriptor that contains the correct lower bound information. For
- // other entities, a new fir.box will be made with the local lower
- // bounds.
- return builder.createBox(loc, array);
- });
-}
-
// LBOUND
fir::ExtendedValue
IntrinsicLibrary::genLbound(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 2 || args.size() == 3);
const fir::ExtendedValue &array = args[0];
- if (const auto *boxValue = array.getBoxOf<fir::BoxValue>())
- if (boxValue->hasAssumedRank())
- TODO(loc, "intrinsic: lbound with assumed rank argument");
+ // Semantics builds signatures for LBOUND calls as either
+ // LBOUND(array, dim, [kind]) or LBOUND(array, [kind]).
+ const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
+ if (array.hasAssumedRank() && dimIsAbsent) {
+ int kindPos = args.size() == 2 ? 1 : 2;
+ return genBoundInquiry(builder, loc, resultType, args, kindPos,
+ fir::runtime::genLbound,
+ /*needAccurateLowerBound=*/true);
+ }
mlir::Type indexType = builder.getIndexType();
- // Semantics builds signatures for LBOUND calls as either
- // LBOUND(array, dim, [kind]) or LBOUND(array, [kind]).
- if (args.size() == 2 || isStaticallyAbsent(args, 1)) {
- // DIM is absent.
+ if (dimIsAbsent) {
+ // DIM is absent and the rank of array is a compile time constant.
mlir::Type lbType = fir::unwrapSequenceType(resultType);
unsigned rank = array.rank();
mlir::Type lbArrayType = fir::SequenceType::get(
@@ -6302,13 +6452,16 @@ IntrinsicLibrary::genLbound(mlir::Type resultType,
// DIM is present.
mlir::Value dim = fir::getBase(args[1]);
- // If it is a compile time constant, skip the runtime call.
- if (std::optional<std::int64_t> cstDim = fir::getIntIfConstant(dim)) {
- mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
- mlir::Value zero = builder.createIntegerConstant(loc, indexType, 0);
- mlir::Value lb = computeLBOUND(builder, loc, array, *cstDim - 1, zero, one);
- return builder.createConvert(loc, resultType, lb);
- }
+ // If it is a compile time constant and the rank is known, skip the runtime
+ // call.
+ if (!array.hasAssumedRank())
+ if (std::optional<std::int64_t> cstDim = fir::getIntIfConstant(dim)) {
+ mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
+ mlir::Value zero = builder.createIntegerConstant(loc, indexType, 0);
+ mlir::Value lb =
+ computeLBOUND(builder, loc, array, *cstDim - 1, zero, one);
+ return builder.createConvert(loc, resultType, lb);
+ }
fir::ExtendedValue box = createBoxForRuntimeBoundInquiry(loc, builder, array);
return builder.createConvert(
@@ -6321,7 +6474,8 @@ fir::ExtendedValue
IntrinsicLibrary::genUbound(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 3 || args.size() == 2);
- if (args.size() == 3) {
+ const bool dimIsAbsent = args.size() == 2 || isStaticallyAbsent(args, 1);
+ if (!dimIsAbsent) {
// Handle calls to UBOUND with the DIM argument, which return a scalar
mlir::Value extent = fir::getBase(genSize(resultType, args));
mlir::Value lbound = fir::getBase(genLbound(resultType, args));
@@ -6329,28 +6483,12 @@ IntrinsicLibrary::genUbound(mlir::Type resultType,
mlir::Value one = builder.createIntegerConstant(loc, resultType, 1);
mlir::Value ubound = builder.create<mlir::arith::SubIOp>(loc, lbound, one);
return builder.create<mlir::arith::AddIOp>(loc, ubound, extent);
- } else {
- // Handle calls to UBOUND without the DIM argument, which return an array
- mlir::Value kind = isStaticallyAbsent(args[1])
- ? builder.createIntegerConstant(
- loc, builder.getIndexType(),
- builder.getKindMap().defaultIntegerKind())
- : fir::getBase(args[1]);
-
- // Create mutable fir.box to be passed to the runtime for the result.
- mlir::Type type = builder.getVarLenSeqTy(resultType, /*rank=*/1);
- fir::MutableBoxValue resultMutableBox =
- fir::factory::createTempMutableBox(builder, loc, type);
- mlir::Value resultIrBox =
- fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
-
- fir::ExtendedValue box =
- createBoxForRuntimeBoundInquiry(loc, builder, args[0]);
- fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(box), kind);
-
- return readAndAddCleanUp(resultMutableBox, resultType, "UBOUND");
}
- return mlir::Value();
+ // Handle calls to UBOUND without the DIM argument, which return an array
+ int kindPos = args.size() == 2 ? 1 : 2;
+ return genBoundInquiry(builder, loc, resultType, args, kindPos,
+ fir::runtime::genUbound,
+ /*needAccurateLowerBound=*/true);
}
// SPACING
diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp
index 16e543fe86a7..fcb9ddcf4138 100644
--- a/flang/lib/Optimizer/Builder/MutableBox.cpp
+++ b/flang/lib/Optimizer/Builder/MutableBox.cpp
@@ -329,7 +329,18 @@ private:
mlir::Value fir::factory::createUnallocatedBox(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type boxType,
mlir::ValueRange nonDeferredParams, mlir::Value typeSourceBox) {
- auto baseAddrType = mlir::dyn_cast<fir::BaseBoxType>(boxType).getEleTy();
+ auto baseBoxType = mlir::cast<fir::BaseBoxType>(boxType);
+ // Giving unallocated/disassociated status to assumed-rank POINTER/
+ // ALLOCATABLE is not directly possible to a Fortran user. But the
+ // compiler may need to create such temporary descriptor to deal with
+ // cases like ENTRY or host association. In such case, all that mater
+ // is that the base address is set to zero and the rank is set to
+ // some defined value. Hence, a scalar descriptor is created and
+ // cast to assumed-rank.
+ const bool isAssumedRank = baseBoxType.isAssumedRank();
+ if (isAssumedRank)
+ baseBoxType = baseBoxType.getBoxTypeWithNewShape(/*rank=*/0);
+ auto baseAddrType = baseBoxType.getEleTy();
if (!fir::isa_ref_type(baseAddrType))
baseAddrType = builder.getRefType(baseAddrType);
auto type = fir::unwrapRefType(baseAddrType);
@@ -361,8 +372,11 @@ mlir::Value fir::factory::createUnallocatedBox(
}
}
mlir::Value emptySlice;
- return builder.create<fir::EmboxOp>(loc, boxType, nullAddr, shape, emptySlice,
- lenParams, typeSourceBox);
+ auto embox = builder.create<fir::EmboxOp>(
+ loc, baseBoxType, nullAddr, shape, emptySlice, lenParams, typeSourceBox);
+ if (isAssumedRank)
+ return builder.createConvert(loc, boxType, embox);
+ return embox;
}
fir::MutableBoxValue fir::factory::createTempMutableBox(
@@ -527,7 +541,14 @@ void fir::factory::associateMutableBox(fir::FirOpBuilder &builder,
mlir::ValueRange newLbounds = lbounds.empty()
? mlir::ValueRange{arr.getLBounds()}
: mlir::ValueRange{lbounds};
- if (box.isDescribedByVariables()) {
+ if (box.hasAssumedRank()) {
+ assert(arr.hasAssumedRank() &&
+ "expect both arr and box to be assumed-rank");
+ mlir::Value reboxed = builder.create<fir::ReboxAssumedRankOp>(
+ loc, box.getBoxTy(), arr.getAddr(),
+ fir::LowerBoundModifierAttribute::Preserve);
+ writer.updateWithIrBox(reboxed);
+ } else if (box.isDescribedByVariables()) {
// LHS is a contiguous pointer described by local variables. Open RHS
// fir.box to update the LHS.
auto rawAddr = builder.create<fir::BoxAddrOp>(loc, arr.getMemTy(),
diff --git a/flang/lib/Optimizer/Builder/Runtime/Assign.cpp b/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
index ad0c2af85cdf..62f03f7d4866 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
@@ -69,19 +69,29 @@ void fir::runtime::genAssignTemporary(fir::FirOpBuilder &builder,
builder.create<fir::CallOp>(loc, func, args);
}
+void fir::runtime::genCopyInAssign(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value destBox,
+ mlir::Value sourceBox) {
+ auto func = fir::runtime::getRuntimeFunc<mkRTKey(CopyInAssign)>(loc, builder);
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
+ auto args = fir::runtime::createArguments(builder, loc, fTy, destBox,
+ sourceBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
void fir::runtime::genCopyOutAssign(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value destBox,
- mlir::Value sourceBox, bool skipToInit) {
+ mlir::Value sourceBox) {
auto func =
fir::runtime::getRuntimeFunc<mkRTKey(CopyOutAssign)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
- fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
- auto i1Ty = builder.getIntegerType(1);
- auto skipToInitVal = builder.createIntegerConstant(loc, i1Ty, skipToInit);
- auto args =
- fir::runtime::createArguments(builder, loc, fTy, destBox, sourceBox,
- skipToInitVal, sourceFile, sourceLine);
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
+ auto args = fir::runtime::createArguments(builder, loc, fTy, destBox,
+ sourceBox, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Inquiry.cpp b/flang/lib/Optimizer/Builder/Runtime/Inquiry.cpp
index 16f63bea4617..e01a6f05b5fd 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Inquiry.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Inquiry.cpp
@@ -29,6 +29,20 @@ mlir::Value fir::runtime::genLboundDim(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, lboundFunc, args).getResult(0);
}
+void fir::runtime::genLbound(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultAddr, mlir::Value array,
+ mlir::Value kind) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(Lbound)>(loc, builder);
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, resultAddr, array, kind, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
+
/// Generate call to `Ubound` runtime routine. Calls to UBOUND with a DIM
/// argument get transformed into an expression equivalent to
/// SIZE() + LBOUND() - 1, so they don't have an intrinsic in the runtime.
@@ -87,3 +101,17 @@ mlir::Value fir::runtime::genIsContiguous(fir::FirOpBuilder &builder,
auto args = fir::runtime::createArguments(builder, loc, fTy, array);
return builder.create<fir::CallOp>(loc, isContiguousFunc, args).getResult(0);
}
+
+void fir::runtime::genShape(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultAddr, mlir::Value array,
+ mlir::Value kind) {
+ mlir::func::FuncOp func =
+ fir::runtime::getRuntimeFunc<mkRTKey(Shape)>(loc, builder);
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, resultAddr, array, kind, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
diff --git a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
index 8ac9d64f576b..1d13248db598 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
@@ -22,6 +22,28 @@ using namespace Fortran::runtime;
// may not have them in their runtime library. This can occur in the
// case of cross compilation, for example.
+/// Placeholder for real*10 version of ErfcScaled Intrinsic
+struct ForcedErfcScaled10 {
+ static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ErfcScaled10));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF80(ctx);
+ return mlir::FunctionType::get(ctx, {ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for real*16 version of ErfcScaled Intrinsic
+struct ForcedErfcScaled16 {
+ static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ErfcScaled16));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF128(ctx);
+ return mlir::FunctionType::get(ctx, {ty}, {ty});
+ };
+ }
+};
+
/// Placeholder for real*10 version of Exponent Intrinsic
struct ForcedExponent10_4 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Exponent10_4));
@@ -444,6 +466,30 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
+/// Generate call to ErfcScaled intrinsic runtime routine.
+mlir::Value fir::runtime::genErfcScaled(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value x) {
+ mlir::func::FuncOp func;
+ mlir::Type fltTy = x.getType();
+
+ if (fltTy.isF32())
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ErfcScaled4)>(loc, builder);
+ else if (fltTy.isF64())
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ErfcScaled8)>(loc, builder);
+ else if (fltTy.isF80())
+ func = fir::runtime::getRuntimeFunc<ForcedErfcScaled10>(loc, builder);
+ else if (fltTy.isF128())
+ func = fir::runtime::getRuntimeFunc<ForcedErfcScaled16>(loc, builder);
+ else
+ fir::intrinsicTypeTODO(builder, fltTy, loc, "ERFC_SCALED");
+
+ auto funcTy = func.getFunctionType();
+ llvm::SmallVector<mlir::Value> args = {
+ builder.createConvert(loc, funcTy.getInput(0), x)};
+
+ return builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
+
/// Generate call to Scale intrinsic runtime routine.
mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value x,
diff --git a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
index d4076067bf10..18eff9372785 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
@@ -12,6 +12,7 @@
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Support/Utils.h"
+#include "flang/Runtime/reduce.h"
#include "flang/Runtime/reduction.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -466,6 +467,430 @@ struct ForcedIParity16 {
}
};
+/// Placeholder for real*10 version of Reduce Intrinsic
+struct ForcedReduceReal10 {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal10Ref));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF80(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for real*10 version of Reduce Intrinsic
+struct ForcedReduceReal10Value {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal10Value));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF80(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for real*16 version of Reduce Intrinsic
+struct ForcedReduceReal16 {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal16Ref));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF128(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for real*16 version of Reduce Intrinsic
+struct ForcedReduceReal16Value {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal16Value));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF128(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for DIM real*10 version of Reduce Intrinsic
+struct ForcedReduceReal10Dim {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal10DimRef));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF80(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for DIM real*10 with value version of Reduce Intrinsic
+struct ForcedReduceReal10DimValue {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal10DimValue));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF80(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for DIM real*16 version of Reduce Intrinsic
+struct ForcedReduceReal16Dim {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal16DimRef));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF128(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for DIM real*16 with value version of Reduce Intrinsic
+struct ForcedReduceReal16DimValue {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceReal16DimValue));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::FloatType::getF128(ctx);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for integer*16 version of Reduce Intrinsic
+struct ForcedReduceInteger16 {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceInteger16Ref));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::IntegerType::get(ctx, 128);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for integer*16 with value version of Reduce Intrinsic
+struct ForcedReduceInteger16Value {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceInteger16Value));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::IntegerType::get(ctx, 128);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
+ };
+ }
+};
+
+/// Placeholder for DIM integer*16 version of Reduce Intrinsic
+struct ForcedReduceInteger16Dim {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceInteger16DimRef));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::IntegerType::get(ctx, 128);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for DIM integer*16 with value version of Reduce Intrinsic
+struct ForcedReduceInteger16DimValue {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(ReduceInteger16DimValue));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::IntegerType::get(ctx, 128);
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for complex(10) version of Reduce Intrinsic
+struct ForcedReduceComplex10 {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex10Ref));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for complex(10) with value version of Reduce Intrinsic
+struct ForcedReduceComplex10Value {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex10Value));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for Dim complex(10) version of Reduce Intrinsic
+struct ForcedReduceComplex10Dim {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimRef));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for Dim complex(10) with value version of Reduce Intrinsic
+struct ForcedReduceComplex10DimValue {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimValue));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for complex(16) version of Reduce Intrinsic
+struct ForcedReduceComplex16 {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex16Ref));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for complex(16) with value version of Reduce Intrinsic
+struct ForcedReduceComplex16Value {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex16Value));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for Dim complex(16) version of Reduce Intrinsic
+struct ForcedReduceComplex16Dim {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimRef));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
+/// Placeholder for Dim complex(16) with value version of Reduce Intrinsic
+struct ForcedReduceComplex16DimValue {
+ static constexpr const char *name =
+ ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimValue));
+ static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+ return [](mlir::MLIRContext *ctx) {
+ auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
+ auto boxTy =
+ fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
+ auto refTy = fir::ReferenceType::get(ty);
+ auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
+ auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
+ auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
+ auto refBoxTy = fir::ReferenceType::get(boxTy);
+ auto i1Ty = mlir::IntegerType::get(ctx, 1);
+ return mlir::FunctionType::get(
+ ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
+ {});
+ };
+ }
+};
+
/// Generate call to specialized runtime function that takes a mask and
/// dim argument. The All, Any, and Count intrinsics use this pattern.
template <typename FN>
@@ -1237,3 +1662,378 @@ void fir::runtime::genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
/// Generate call to `IParity` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
GEN_IALL_IANY_IPARITY(IParity)
+
+/// Generate call to `Reduce` intrinsic runtime routine. This is the version
+/// that does not take a DIM argument and store result in the passed result
+/// value.
+void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value arrayBox, mlir::Value operation,
+ mlir::Value maskBox, mlir::Value identity,
+ mlir::Value ordered, mlir::Value resultBox,
+ bool argByRef) {
+ mlir::func::FuncOp func;
+ auto ty = arrayBox.getType();
+ auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
+ auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+ auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
+
+ assert(resultBox && "expect non null value for the result");
+ assert((fir::isa_char(eleTy) || fir::isa_complex(eleTy) ||
+ fir::isa_derived(eleTy)) &&
+ "expect character, complex or derived-type");
+
+ mlir::MLIRContext *ctx = builder.getContext();
+ fir::factory::CharacterExprHelper charHelper{builder, loc};
+
+ if (eleTy == fir::ComplexType::get(ctx, 2) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2Ref)>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 2) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2Value)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 3) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3Ref)>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 3) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3Value)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 4) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4Ref)>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 4) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4Value)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 8) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8Ref)>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 8) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8Value)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 10) && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10>(loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 10) && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<ForcedReduceComplex10Value>(loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 16) && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16>(loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 16) && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<ForcedReduceComplex16Value>(loc, builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar4)>(loc, builder);
+ else if (fir::isa_derived(eleTy))
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);
+ else
+ fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
+
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
+ dim, maskBox, identity, ordered);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// Generate call to `Reduce` intrinsic runtime routine. This is the version
+/// that does not take DIM argument and return a scalar result.
+mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value arrayBox,
+ mlir::Value operation, mlir::Value maskBox,
+ mlir::Value identity, mlir::Value ordered,
+ bool argByRef) {
+ mlir::func::FuncOp func;
+ auto ty = arrayBox.getType();
+ auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
+ auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+ auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
+
+ mlir::MLIRContext *ctx = builder.getContext();
+ fir::factory::CharacterExprHelper charHelper{builder, loc};
+
+ assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) ||
+ mlir::isa<fir::LogicalType>(eleTy)) &&
+ "expect real, interger or logical");
+
+ if (eleTy.isF16() && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2Ref)>(loc, builder);
+ else if (eleTy.isF16() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2Value)>(loc, builder);
+ else if (eleTy.isBF16() && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3Ref)>(loc, builder);
+ else if (eleTy.isBF16() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3Value)>(loc, builder);
+ else if (eleTy.isF32() && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4Ref)>(loc, builder);
+ else if (eleTy.isF32() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4Value)>(loc, builder);
+ else if (eleTy.isF64() && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8Ref)>(loc, builder);
+ else if (eleTy.isF64() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8Value)>(loc, builder);
+ else if (eleTy.isF80() && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal10>(loc, builder);
+ else if (eleTy.isF80() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal10Value>(loc, builder);
+ else if (eleTy.isF128() && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal16>(loc, builder);
+ else if (eleTy.isF128() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal16Value>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
+ argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1Ref)>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1Value)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
+ argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2Ref)>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2Value)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
+ argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4Ref)>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4Value)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
+ argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8Ref)>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8Value)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
+ !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<ForcedReduceInteger16Value>(loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 1) && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1Ref)>(loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 1) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1Value)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 2) && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2Ref)>(loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 2) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2Value)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 4) && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4Ref)>(loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 4) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4Value)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 8) && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8Ref)>(loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 8) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8Value)>(loc,
+ builder);
+ else
+ fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
+
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
+ auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(1), operation);
+ auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox, opAddr,
+ sourceFile, sourceLine, dim,
+ maskBox, identity, ordered);
+ return builder.create<fir::CallOp>(loc, func, args).getResult(0);
+}
+
+void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value arrayBox, mlir::Value operation,
+ mlir::Value dim, mlir::Value maskBox,
+ mlir::Value identity, mlir::Value ordered,
+ mlir::Value resultBox, bool argByRef) {
+ mlir::func::FuncOp func;
+ auto ty = arrayBox.getType();
+ auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
+ auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getEleTy();
+
+ mlir::MLIRContext *ctx = builder.getContext();
+ fir::factory::CharacterExprHelper charHelper{builder, loc};
+
+ if (eleTy.isF16() && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2DimRef)>(loc, builder);
+ else if (eleTy.isF16() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal2DimValue)>(loc,
+ builder);
+ else if (eleTy.isBF16() && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3DimRef)>(loc, builder);
+ else if (eleTy.isBF16() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal3DimValue)>(loc,
+ builder);
+ else if (eleTy.isF32() && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4DimRef)>(loc, builder);
+ else if (eleTy.isF32() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal4DimValue)>(loc,
+ builder);
+ else if (eleTy.isF64() && argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8DimRef)>(loc, builder);
+ else if (eleTy.isF64() && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceReal8DimValue)>(loc,
+ builder);
+ else if (eleTy.isF80() && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal10Dim>(loc, builder);
+ else if (eleTy.isF80() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<ForcedReduceReal10DimValue>(loc, builder);
+ else if (eleTy.isF128() && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceReal16Dim>(loc, builder);
+ else if (eleTy.isF128() && !argByRef)
+ func =
+ fir::runtime::getRuntimeFunc<ForcedReduceReal16DimValue>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1DimRef)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger1DimValue)>(
+ loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2DimRef)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger2DimValue)>(
+ loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4DimRef)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger4DimValue)>(
+ loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8DimRef)>(loc,
+ builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceInteger8DimValue)>(
+ loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
+ argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16Dim>(loc, builder);
+ else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)) &&
+ !argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceInteger16DimValue>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 2) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2DimRef)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 2) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex2DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 3) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3DimRef)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 3) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex3DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 4) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4DimRef)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 4) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex4DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 8) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8DimRef)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 8) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(CppReduceComplex8DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 10) && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10Dim>(loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 10) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex10DimValue>(loc,
+ builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 16) && argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16Dim>(loc, builder);
+ else if (eleTy == fir::ComplexType::get(ctx, 16) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<ForcedReduceComplex16DimValue>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 1) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1DimRef)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 1) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical1DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 2) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2DimRef)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 2) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical2DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 4) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4DimRef)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 4) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical4DimValue)>(
+ loc, builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 8) && argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8DimRef)>(loc,
+ builder);
+ else if (eleTy == fir::LogicalType::get(ctx, 8) && !argByRef)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceLogical8DimValue)>(
+ loc, builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter1Dim)>(loc,
+ builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter2Dim)>(loc,
+ builder);
+ else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter4Dim)>(loc,
+ builder);
+ else if (fir::isa_derived(eleTy))
+ func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedTypeDim)>(loc,
+ builder);
+ else
+ fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
+
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
+ dim, maskBox, identity, ordered);
+ builder.create<fir::CallOp>(loc, func, args);
+}
diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index 879bc28d017a..650448eee109 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -27,6 +27,7 @@ add_flang_library(FIRCodeGen
MLIRMathToLLVM
MLIRMathToLibm
MLIROpenMPToLLVM
+ MLIROpenACCDialect
MLIRBuiltinToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
MLIRTargetLLVMIRExport
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 9f21c6b0cf09..5f35825783c5 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -218,7 +218,7 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
chrTy.getContext(), chrTy.getFKind());
llvmObjectType = convertType(rawCharTy);
assert(end == 1);
- size = integerCast(loc, rewriter, ity, lenParams[0]);
+ size = integerCast(loc, rewriter, ity, lenParams[0], /*fold=*/true);
} else if (auto recTy = mlir::dyn_cast<fir::RecordType>(scalarType)) {
mlir::LLVM::LLVMFuncOp memSizeFn =
getDependentTypeMemSizeFn(recTy, alloc, rewriter);
@@ -236,17 +236,29 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
}
}
if (auto scaleSize = genAllocationScaleSize(alloc, ity, rewriter))
- size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
+ size =
+ rewriter.createOrFold<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
if (alloc.hasShapeOperands()) {
unsigned end = operands.size();
for (; i < end; ++i)
- size = rewriter.create<mlir::LLVM::MulOp>(
- loc, ity, size, integerCast(loc, rewriter, ity, operands[i]));
+ size = rewriter.createOrFold<mlir::LLVM::MulOp>(
+ loc, ity, size,
+ integerCast(loc, rewriter, ity, operands[i], /*fold=*/true));
}
unsigned allocaAs = getAllocaAddressSpace(rewriter);
unsigned programAs = getProgramAddressSpace(rewriter);
+ if (mlir::isa<mlir::LLVM::ConstantOp>(size.getDefiningOp())) {
+ // Set the Block in which the llvm alloca should be inserted.
+ mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
+ mlir::Region *parentRegion = rewriter.getInsertionBlock()->getParent();
+ mlir::Block *insertBlock =
+ getBlockForAllocaInsert(parentOp, parentRegion);
+ size.getDefiningOp()->moveBefore(&insertBlock->front());
+ rewriter.setInsertionPointAfter(size.getDefiningOp());
+ }
+
// NOTE: we used to pass alloc->getAttrs() in the builder for non opaque
// pointers! Only propagate pinned and bindc_name to help debugging, but
// this should have no functional purpose (and passing the operand segment
@@ -3131,23 +3143,32 @@ struct StoreOpConversion : public fir::FIROpConversion<fir::StoreOp> {
mlir::ConversionPatternRewriter &rewriter) const override {
mlir::Location loc = store.getLoc();
mlir::Type storeTy = store.getValue().getType();
- mlir::LLVM::StoreOp newStoreOp;
+ mlir::Value llvmValue = adaptor.getValue();
+ mlir::Value llvmMemref = adaptor.getMemref();
+ mlir::LLVM::AliasAnalysisOpInterface newOp;
if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(storeTy)) {
- // fir.box value is actually in memory, load it first before storing it.
mlir::Type llvmBoxTy = lowerTy().convertBoxTypeAsStruct(boxTy);
- auto val = rewriter.create<mlir::LLVM::LoadOp>(loc, llvmBoxTy,
- adaptor.getOperands()[0]);
- attachTBAATag(val, boxTy, boxTy, nullptr);
- newStoreOp = rewriter.create<mlir::LLVM::StoreOp>(
- loc, val, adaptor.getOperands()[1]);
+ // fir.box value is actually in memory, load it first before storing it,
+ // or do a memcopy for assumed-rank descriptors.
+ if (boxTy.isAssumedRank()) {
+ TypePair boxTypePair{boxTy, llvmBoxTy};
+ mlir::Value boxSize =
+ computeBoxSize(loc, boxTypePair, llvmValue, rewriter);
+ newOp = rewriter.create<mlir::LLVM::MemcpyOp>(
+ loc, llvmMemref, llvmValue, boxSize, /*isVolatile=*/false);
+ } else {
+ auto val =
+ rewriter.create<mlir::LLVM::LoadOp>(loc, llvmBoxTy, llvmValue);
+ attachTBAATag(val, boxTy, boxTy, nullptr);
+ newOp = rewriter.create<mlir::LLVM::StoreOp>(loc, val, llvmMemref);
+ }
} else {
- newStoreOp = rewriter.create<mlir::LLVM::StoreOp>(
- loc, adaptor.getOperands()[0], adaptor.getOperands()[1]);
+ newOp = rewriter.create<mlir::LLVM::StoreOp>(loc, llvmValue, llvmMemref);
}
if (std::optional<mlir::ArrayAttr> optionalTag = store.getTbaa())
- newStoreOp.setTBAATags(*optionalTag);
+ newOp.setTBAATags(*optionalTag);
else
- attachTBAATag(newStoreOp, storeTy, storeTy, nullptr);
+ attachTBAATag(newOp, storeTy, storeTy, nullptr);
rewriter.eraseOp(store);
return mlir::success();
}
diff --git a/flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp b/flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp
index 72e072db3743..b9a28b89d9a5 100644
--- a/flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp
+++ b/flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp
@@ -62,10 +62,9 @@ mlir::LLVM::ConstantOp ConvertFIRToLLVMPattern::genConstantOffset(
/// to the specific target may involve some sign-extending or truncation of
/// values, particularly to fit them from abstract box types to the
/// appropriate reified structures.
-mlir::Value
-ConvertFIRToLLVMPattern::integerCast(mlir::Location loc,
- mlir::ConversionPatternRewriter &rewriter,
- mlir::Type ty, mlir::Value val) const {
+mlir::Value ConvertFIRToLLVMPattern::integerCast(
+ mlir::Location loc, mlir::ConversionPatternRewriter &rewriter,
+ mlir::Type ty, mlir::Value val, bool fold) const {
auto valTy = val.getType();
// If the value was not yet lowered, lower its type so that it can
// be used in getPrimitiveTypeSizeInBits.
@@ -73,10 +72,17 @@ ConvertFIRToLLVMPattern::integerCast(mlir::Location loc,
valTy = convertType(valTy);
auto toSize = mlir::LLVM::getPrimitiveTypeSizeInBits(ty);
auto fromSize = mlir::LLVM::getPrimitiveTypeSizeInBits(valTy);
- if (toSize < fromSize)
- return rewriter.create<mlir::LLVM::TruncOp>(loc, ty, val);
- if (toSize > fromSize)
- return rewriter.create<mlir::LLVM::SExtOp>(loc, ty, val);
+ if (fold) {
+ if (toSize < fromSize)
+ return rewriter.createOrFold<mlir::LLVM::TruncOp>(loc, ty, val);
+ if (toSize > fromSize)
+ return rewriter.createOrFold<mlir::LLVM::SExtOp>(loc, ty, val);
+ } else {
+ if (toSize < fromSize)
+ return rewriter.create<mlir::LLVM::TruncOp>(loc, ty, val);
+ if (toSize > fromSize)
+ return rewriter.create<mlir::LLVM::SExtOp>(loc, ty, val);
+ }
return val;
}
@@ -274,16 +280,19 @@ mlir::Value ConvertFIRToLLVMPattern::computeBoxSize(
// Find the Block in which the alloca should be inserted.
// The order to recursively find the proper block:
// 1. An OpenMP Op that will be outlined.
-// 2. A LLVMFuncOp
-// 3. The first ancestor that is an OpenMP Op or a LLVMFuncOp
-mlir::Block *
-ConvertFIRToLLVMPattern::getBlockForAllocaInsert(mlir::Operation *op) const {
+// 2. An OpenMP or OpenACC Op with one or more regions holding executable code.
+// 3. A LLVMFuncOp
+// 4. The first ancestor that is one of the above.
+mlir::Block *ConvertFIRToLLVMPattern::getBlockForAllocaInsert(
+ mlir::Operation *op, mlir::Region *parentRegion) const {
if (auto iface = mlir::dyn_cast<mlir::omp::OutlineableOpenMPOpInterface>(op))
return iface.getAllocaBlock();
+ if (auto recipeIface = mlir::dyn_cast<mlir::accomp::RecipeInterface>(op))
+ return recipeIface.getAllocaBlock(*parentRegion);
if (auto llvmFuncOp = mlir::dyn_cast<mlir::LLVM::LLVMFuncOp>(op))
return &llvmFuncOp.front();
- return getBlockForAllocaInsert(op->getParentOp());
+ return getBlockForAllocaInsert(op->getParentOp(), parentRegion);
}
// Generate an alloca of size 1 for an object of type \p llvmObjectTy in the
@@ -297,16 +306,9 @@ mlir::Value ConvertFIRToLLVMPattern::genAllocaAndAddrCastWithType(
mlir::ConversionPatternRewriter &rewriter) const {
auto thisPt = rewriter.saveInsertionPoint();
mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp();
- if (mlir::isa<mlir::omp::DeclareReductionOp>(parentOp) ||
- mlir::isa<mlir::omp::PrivateClauseOp>(parentOp)) {
- // DeclareReductionOp & PrivateClauseOp have multiple child regions. We want
- // to get the first block of whichever of those regions we are currently in
- mlir::Region *parentRegion = rewriter.getInsertionBlock()->getParent();
- rewriter.setInsertionPointToStart(&parentRegion->front());
- } else {
- mlir::Block *insertBlock = getBlockForAllocaInsert(parentOp);
- rewriter.setInsertionPointToStart(insertBlock);
- }
+ mlir::Region *parentRegion = rewriter.getInsertionBlock()->getParent();
+ mlir::Block *insertBlock = getBlockForAllocaInsert(parentOp, parentRegion);
+ rewriter.setInsertionPointToStart(insertBlock);
auto size = genI32Constant(loc, rewriter, 1);
unsigned allocaAs = getAllocaAddressSpace(rewriter);
unsigned programAs = getProgramAddressSpace(rewriter);
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
index 07d3bd713ce4..501a36f5b68b 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
@@ -13,9 +13,9 @@
#define DEBUG_TYPE "flang-type-conversion"
#include "flang/Optimizer/CodeGen/TypeConverter.h"
-#include "DescriptorModel.h"
#include "flang/Common/Fortran.h"
#include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done
+#include "flang/Optimizer/CodeGen/DescriptorModel.h"
#include "flang/Optimizer/CodeGen/TBAABuilder.h"
#include "flang/Optimizer/CodeGen/Target.h"
#include "flang/Optimizer/Dialect/FIRType.h"
diff --git a/flang/lib/Optimizer/Dialect/CUF/CUFOps.cpp b/flang/lib/Optimizer/Dialect/CUF/CUFOps.cpp
index 2c0c4c2cfae3..4fa1d3986b21 100644
--- a/flang/lib/Optimizer/Dialect/CUF/CUFOps.cpp
+++ b/flang/lib/Optimizer/Dialect/CUF/CUFOps.cpp
@@ -13,6 +13,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
@@ -97,13 +98,15 @@ mlir::LogicalResult cuf::DataTransferOp::verify() {
mlir::Type srcTy = getSrc().getType();
mlir::Type dstTy = getDst().getType();
if ((fir::isa_ref_type(srcTy) && fir::isa_ref_type(dstTy)) ||
- (fir::isa_box_type(srcTy) && fir::isa_box_type(dstTy)))
+ (fir::isa_box_type(srcTy) && fir::isa_box_type(dstTy)) ||
+ (fir::isa_ref_type(srcTy) && fir::isa_box_type(dstTy)) ||
+ (fir::isa_box_type(srcTy) && fir::isa_ref_type(dstTy)))
return mlir::success();
if (fir::isa_trivial(srcTy) &&
matchPattern(getSrc().getDefiningOp(), mlir::m_Constant()))
return mlir::success();
return emitOpError()
- << "expect src and dst to be both references or descriptors or src to "
+ << "expect src and dst to be references or descriptors or src to "
"be a constant";
}
@@ -227,7 +230,17 @@ mlir::LogicalResult cuf::KernelOp::verify() {
getLowerbound().size() != getStep().size())
return emitOpError(
"expect same number of values in lowerbound, upperbound and step");
-
+ auto reduceAttrs = getReduceAttrs();
+ std::size_t reduceAttrsSize = reduceAttrs ? reduceAttrs->size() : 0;
+ if (getReduceOperands().size() != reduceAttrsSize)
+ return emitOpError("expect same number of values in reduce operands and "
+ "reduce attributes");
+ if (reduceAttrs) {
+ for (const auto &attr : reduceAttrs.value()) {
+ if (!mlir::isa<fir::ReduceAttr>(attr))
+ return emitOpError("expect reduce attributes to be ReduceAttr");
+ }
+ }
return mlir::success();
}
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 75ca738211ab..84711c540658 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -272,8 +272,6 @@ mlir::LogicalResult fir::AllocaOp::verify() {
mlir::Type outType = getType();
if (!mlir::isa<fir::ReferenceType>(outType))
return emitOpError("must be a !fir.ref type");
- if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
- return emitOpError("cannot allocate !fir.box of unknown rank or type");
return mlir::success();
}
@@ -1060,9 +1058,9 @@ void fir::BoxRankOp::getEffects(
llvm::SmallVectorImpl<
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
&effects) {
- mlir::Value inputBox = getBox();
- if (fir::isBoxAddress(inputBox.getType()))
- effects.emplace_back(mlir::MemoryEffects::Read::get(), inputBox,
+ mlir::OpOperand &inputBox = getBoxMutable();
+ if (fir::isBoxAddress(inputBox.get().getType()))
+ effects.emplace_back(mlir::MemoryEffects::Read::get(), &inputBox,
mlir::SideEffects::DefaultResource::get());
}
@@ -1432,7 +1430,8 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
mlir::LogicalResult fir::ConvertOp::verify() {
if (canBeConverted(getValue().getType(), getType()))
return mlir::success();
- return emitOpError("invalid type conversion");
+ return emitOpError("invalid type conversion")
+ << getValue().getType() << " / " << getType();
}
//===----------------------------------------------------------------------===//
@@ -2902,9 +2901,9 @@ void fir::ReboxAssumedRankOp::getEffects(
llvm::SmallVectorImpl<
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
&effects) {
- mlir::Value inputBox = getBox();
- if (fir::isBoxAddress(inputBox.getType()))
- effects.emplace_back(mlir::MemoryEffects::Read::get(), inputBox,
+ mlir::OpOperand &inputBox = getBoxMutable();
+ if (fir::isBoxAddress(inputBox.get().getType()))
+ effects.emplace_back(mlir::MemoryEffects::Read::get(), &inputBox,
mlir::SideEffects::DefaultResource::get());
}
@@ -3792,8 +3791,6 @@ void fir::StoreOp::print(mlir::OpAsmPrinter &p) {
mlir::LogicalResult fir::StoreOp::verify() {
if (getValue().getType() != fir::dyn_cast_ptrEleTy(getMemref().getType()))
return emitOpError("store value type must match memory reference type");
- if (fir::isa_unknown_size_box(getValue().getType()))
- return emitOpError("cannot store !fir.box of unknown rank or type");
return mlir::success();
}
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index b6adb31213cd..b3f2ec848a2d 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -1335,6 +1335,26 @@ fir::BaseBoxType fir::BaseBoxType::getBoxTypeWithNewShape(int rank) const {
return mlir::cast<fir::BaseBoxType>(changeTypeShape(*this, newShape));
}
+fir::BaseBoxType fir::BaseBoxType::getBoxTypeWithNewAttr(
+ fir::BaseBoxType::Attribute attr) const {
+ mlir::Type baseType = fir::unwrapRefType(getEleTy());
+ switch (attr) {
+ case fir::BaseBoxType::Attribute::None:
+ break;
+ case fir::BaseBoxType::Attribute::Allocatable:
+ baseType = fir::HeapType::get(baseType);
+ break;
+ case fir::BaseBoxType::Attribute::Pointer:
+ baseType = fir::PointerType::get(baseType);
+ break;
+ }
+ return llvm::TypeSwitch<fir::BaseBoxType, fir::BaseBoxType>(*this)
+ .Case<fir::BoxType>(
+ [baseType](auto) { return fir::BoxType::get(baseType); })
+ .Case<fir::ClassType>(
+ [baseType](auto) { return fir::ClassType::get(baseType); });
+}
+
bool fir::BaseBoxType::isAssumedRank() const {
if (auto seqTy =
mlir::dyn_cast<fir::SequenceType>(fir::unwrapRefType(getEleTy())))
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 218b38e9ba79..cbe789fed116 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -45,7 +45,7 @@ getIntrinsicEffects(mlir::Operation *self,
"hlfir intrinsic ops only produce 1 result");
if (mlir::isa<hlfir::ExprType>(self->getResult(0).getType()))
effects.emplace_back(mlir::MemoryEffects::Allocate::get(),
- self->getResult(0),
+ self->getOpResult(0),
mlir::SideEffects::DefaultResource::get());
// read effect if we read from a pointer or refference type
@@ -59,10 +59,10 @@ getIntrinsicEffects(mlir::Operation *self,
// } to {
// hlfir.yield %0#0 : !fir.box<!fir.array<?x?xf32>>
// }
- for (mlir::Value operand : self->getOperands()) {
- mlir::Type opTy = operand.getType();
+ for (mlir::OpOperand &operand : self->getOpOperands()) {
+ mlir::Type opTy = operand.get().getType();
if (fir::isa_ref_type(opTy) || fir::isa_box_type(opTy))
- effects.emplace_back(mlir::MemoryEffects::Read::get(), operand,
+ effects.emplace_back(mlir::MemoryEffects::Read::get(), &operand,
mlir::SideEffects::DefaultResource::get());
}
}
@@ -1495,9 +1495,9 @@ mlir::LogicalResult hlfir::DestroyOp::verify() {
void hlfir::CopyInOp::build(mlir::OpBuilder &builder,
mlir::OperationState &odsState, mlir::Value var,
- mlir::Value var_is_present) {
+ mlir::Value tempBox, mlir::Value var_is_present) {
return build(builder, odsState, {var.getType(), builder.getI1Type()}, var,
- var_is_present);
+ tempBox, var_is_present);
}
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index b48b993ddc5a..74bbab0d72e9 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -31,28 +31,6 @@ namespace hlfir {
using namespace mlir;
-static mlir::Value genAllocatableTempFromSourceBox(mlir::Location loc,
- fir::FirOpBuilder &builder,
- mlir::Value sourceBox) {
- assert(mlir::isa<fir::BaseBoxType>(sourceBox.getType()) &&
- "must be a base box type");
- // Use the runtime to make a quick and dirty temp with the rhs value.
- // Overkill for scalar rhs that could be done in much more clever ways.
- // Note that temp descriptor must have the allocatable flag set so that
- // the runtime will allocate it with the shape and type parameters of
- // the RHS.
- // This has the huge benefit of dealing with all cases, including
- // polymorphic entities.
- mlir::Type fromHeapType = fir::HeapType::get(fir::unwrapRefType(
- mlir::cast<fir::BaseBoxType>(sourceBox.getType()).getEleTy()));
- mlir::Type fromBoxHeapType = fir::BoxType::get(fromHeapType);
- mlir::Value fromMutableBox =
- fir::factory::genNullBoxStorage(builder, loc, fromBoxHeapType);
- fir::runtime::genAssignTemporary(builder, loc, fromMutableBox, sourceBox);
- mlir::Value copy = builder.create<fir::LoadOp>(loc, fromMutableBox);
- return copy;
-}
-
namespace {
/// May \p lhs alias with \p rhs?
/// TODO: implement HLFIR alias analysis.
@@ -211,13 +189,19 @@ public:
// check (for IsContiguous) the copy loops can hardly provide any
// value to optimizations, instead, the optimizer just wastes
// compilation time on these loops.
- mlir::Value temp =
- genAllocatableTempFromSourceBox(loc, builder, inputVariable);
+ mlir::Value temp = copyInOp.getTempBox();
+ fir::runtime::genCopyInAssign(builder, loc, temp, inputVariable);
+ mlir::Value copy = builder.create<fir::LoadOp>(loc, temp);
// Get rid of allocatable flag in the fir.box.
- temp = builder.create<fir::ReboxOp>(loc, resultAddrType, temp,
- /*shape=*/mlir::Value{},
- /*slice=*/mlir::Value{});
- builder.create<fir::ResultOp>(loc, temp);
+ if (mlir::cast<fir::BaseBoxType>(resultAddrType).isAssumedRank())
+ copy = builder.create<fir::ReboxAssumedRankOp>(
+ loc, resultAddrType, copy,
+ fir::LowerBoundModifierAttribute::Preserve);
+ else
+ copy = builder.create<fir::ReboxOp>(loc, resultAddrType, copy,
+ /*shape=*/mlir::Value{},
+ /*slice=*/mlir::Value{});
+ builder.create<fir::ResultOp>(loc, copy);
})
.getResults()[0];
return {addr, builder.genNot(loc, isContiguous)};
@@ -274,34 +258,26 @@ public:
builder.genIfThen(loc, copyOutOp.getWasCopied())
.genThen([&]() {
mlir::Value temp = copyOutOp.getTemp();
+ mlir::Value varMutableBox;
+ // Generate CopyOutAssign runtime call.
if (mlir::Value var = copyOutOp.getVar()) {
- auto mutableBoxTo = builder.createTemporary(loc, var.getType());
- builder.create<fir::StoreOp>(loc, var, mutableBoxTo);
- // Generate CopyOutAssign() call to copy data from the temporary
- // to the actualArg. Note that in case the actual argument
- // is ALLOCATABLE/POINTER the CopyOutAssign() implementation
- // should not engage its reallocation, because the temporary
- // is rank, shape and type compatible with it.
- // Moreover, CopyOutAssign() guarantees that there will be no
- // finalization for the LHS even if it is of a derived type
- // with finalization.
- fir::runtime::genCopyOutAssign(builder, loc, mutableBoxTo, temp,
- /*skipToInit=*/true);
+ // Set the variable descriptor pointer in order to copy data from
+ // the temporary to the actualArg. Note that in case the actual
+ // argument is ALLOCATABLE/POINTER the CopyOutAssign()
+ // implementation should not engage its reallocation, because the
+ // temporary is rank, shape and type compatible with it. Moreover,
+ // CopyOutAssign() guarantees that there will be no finalization for
+ // the LHS even if it is of a derived type with finalization.
+ varMutableBox = builder.createTemporary(loc, var.getType());
+ builder.create<fir::StoreOp>(loc, var, varMutableBox);
+ } else {
+ // Even when there is no need to copy back the data (e.g., the dummy
+ // argument was intent(in), CopyOutAssign is called to
+ // destroy/deallocate the temporary.
+ varMutableBox = builder.create<fir::ZeroOp>(loc, temp.getType());
}
- // Destroy components of the temporary (if any).
- fir::runtime::genDerivedTypeDestroyWithoutFinalization(builder, loc,
- temp);
- mlir::Type heapType =
- fir::HeapType::get(fir::dyn_cast_ptrOrBoxEleTy(temp.getType()));
- mlir::Value tempAddr =
- builder.create<fir::BoxAddrOp>(loc, heapType, temp);
-
- // Deallocate the top-level entity of the temporary.
- //
- // Note that this FreeMemOp is coupled with the runtime
- // allocation engaged by the code generated by
- // genAllocatableTempFromSourceBox().
- builder.create<fir::FreeMemOp>(loc, tempAddr);
+ fir::runtime::genCopyOutAssign(builder, loc, varMutableBox,
+ copyOutOp.getTemp());
})
.end();
rewriter.eraseOp(copyOutOp);
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/InlineElementals.cpp b/flang/lib/Optimizer/HLFIR/Transforms/InlineElementals.cpp
index 6c8e3e119374..4b0b8594c3cc 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/InlineElementals.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/InlineElementals.cpp
@@ -119,7 +119,8 @@ public:
mlir::GreedyRewriteConfig config;
// Prevent the pattern driver from merging blocks.
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
mlir::RewritePatternSet patterns(context);
patterns.insert<InlineElementalConversion>(context);
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
index 707c0feffbb3..0347bec3a9a2 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
@@ -486,7 +486,8 @@ public:
// Pattern rewriting only requires that the resulting IR is still valid
mlir::GreedyRewriteConfig config;
// Prevent the pattern driver from merging blocks
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
if (mlir::failed(mlir::applyPatternsAndFoldGreedily(
module, std::move(patterns), config))) {
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
index 3c8424ca564e..1dfa2f9d093b 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
@@ -1042,7 +1042,8 @@ public:
mlir::GreedyRewriteConfig config;
// Prevent the pattern driver from merging blocks
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
mlir::RewritePatternSet patterns(context);
// TODO: right now the patterns are non-conflicting,
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
index 2c840ce4ffe8..efe59b8ef988 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
@@ -225,14 +225,14 @@ static void gatherMemoryEffects(
/// Return the entity yielded by a region, or a null value if the region
/// is not terminated by a yield.
-static mlir::Value getYieldedEntity(mlir::Region &region) {
+static mlir::OpOperand *getYieldedEntity(mlir::Region &region) {
if (region.empty() || region.back().empty())
return nullptr;
if (auto yield = mlir::dyn_cast<hlfir::YieldOp>(region.back().back()))
- return yield.getEntity();
+ return &yield.getEntityMutable();
if (auto elementalAddr =
mlir::dyn_cast<hlfir::ElementalAddrOp>(region.back().back()))
- return elementalAddr.getYieldOp().getEntity();
+ return &elementalAddr.getYieldOp().getEntityMutable();
return nullptr;
}
@@ -244,7 +244,7 @@ static void gatherAssignEffects(
hlfir::RegionAssignOp regionAssign,
bool userDefAssignmentMayOnlyWriteToAssignedVariable,
llvm::SmallVectorImpl<mlir::MemoryEffects::EffectInstance> &assignEffects) {
- mlir::Value assignedVar = getYieldedEntity(regionAssign.getLhsRegion());
+ mlir::OpOperand *assignedVar = getYieldedEntity(regionAssign.getLhsRegion());
assert(assignedVar && "lhs cannot be an empty region");
assignEffects.emplace_back(mlir::MemoryEffects::Write::get(), assignedVar);
@@ -389,8 +389,8 @@ void Scheduler::saveEvaluationIfConflict(mlir::Region &yieldRegion,
// with a finalizer, or a user defined assignment where the LHS is
// intent(inout)).
if (yieldIsImplicitRead) {
- mlir::Value entity = getYieldedEntity(yieldRegion);
- if (entity && hlfir::isFortranVariableType(entity.getType()))
+ mlir::OpOperand *entity = getYieldedEntity(yieldRegion);
+ if (entity && hlfir::isFortranVariableType(entity->get().getType()))
effects.emplace_back(mlir::MemoryEffects::Read::get(), entity);
}
if (!leafRegionsMayOnlyRead && anyWrite(effects)) {
@@ -600,9 +600,9 @@ hlfir::buildEvaluationSchedule(hlfir::OrderedAssignmentTreeOpInterface root,
}
mlir::Value hlfir::SaveEntity::getSavedValue() {
- mlir::Value saved = getYieldedEntity(*yieldRegion);
+ mlir::OpOperand *saved = getYieldedEntity(*yieldRegion);
assert(saved && "SaveEntity must contain region terminated by YieldOp");
- return saved;
+ return saved->get();
}
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/Transforms/AssumedRankOpConversion.cpp b/flang/lib/Optimizer/Transforms/AssumedRankOpConversion.cpp
index 2c545d66ebd8..5dfc5009d235 100644
--- a/flang/lib/Optimizer/Transforms/AssumedRankOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/AssumedRankOpConversion.cpp
@@ -84,7 +84,9 @@ public:
auto oldBoxType = mlir::cast<fir::BaseBoxType>(
fir::unwrapRefType(rebox.getBox().getType()));
auto newDerivedType = mlir::dyn_cast<fir::RecordType>(newEleType);
- if (newDerivedType && (newEleType != oldBoxType.unwrapInnerType()) &&
+ if (newDerivedType && !fir::isPolymorphicType(newBoxType) &&
+ (fir::isPolymorphicType(oldBoxType) ||
+ (newEleType != oldBoxType.unwrapInnerType())) &&
!fir::isPolymorphicType(newBoxType)) {
newDtype = builder.create<fir::TypeDescOp>(
loc, mlir::TypeAttr::get(newDerivedType));
@@ -150,7 +152,8 @@ public:
patterns.insert<ReboxAssumedRankConv>(context, &symbolTable, kindMap);
patterns.insert<IsAssumedSizeConv>(context, &symbolTable, kindMap);
mlir::GreedyRewriteConfig config;
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
(void)applyPatternsAndFoldGreedily(mod, std::move(patterns), config);
}
};
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 5ef930fdb2c2..94d94398d696 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(FIRTransforms
AnnotateConstant.cpp
AssumedRankOpConversion.cpp
CharacterConversion.cpp
+ ConstantArgumentGlobalisation.cpp
ControlFlowConverter.cpp
ArrayValueCopy.cpp
ExternalNameConversion.cpp
@@ -21,6 +22,7 @@ add_flang_library(FIRTransforms
OMPFunctionFiltering.cpp
OMPMapInfoFinalization.cpp
OMPMarkDeclareTarget.cpp
+ StackReclaim.cpp
VScaleAttr.cpp
FunctionAttr.cpp
DebugTypeGenerator.cpp
diff --git a/flang/lib/Optimizer/Transforms/ConstantArgumentGlobalisation.cpp b/flang/lib/Optimizer/Transforms/ConstantArgumentGlobalisation.cpp
new file mode 100644
index 000000000000..f7074a79a8a8
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/ConstantArgumentGlobalisation.cpp
@@ -0,0 +1,185 @@
+//===- ConstantArgumentGlobalisation.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Dominance.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+namespace fir {
+#define GEN_PASS_DEF_CONSTANTARGUMENTGLOBALISATIONOPT
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+#define DEBUG_TYPE "flang-constant-argument-globalisation-opt"
+
+namespace {
+unsigned uniqueLitId = 1;
+
+class CallOpRewriter : public mlir::OpRewritePattern<fir::CallOp> {
+protected:
+ const mlir::DominanceInfo &di;
+
+public:
+ using OpRewritePattern::OpRewritePattern;
+
+ CallOpRewriter(mlir::MLIRContext *ctx, const mlir::DominanceInfo &_di)
+ : OpRewritePattern(ctx), di(_di) {}
+
+ mlir::LogicalResult
+ matchAndRewrite(fir::CallOp callOp,
+ mlir::PatternRewriter &rewriter) const override {
+ LLVM_DEBUG(llvm::dbgs() << "Processing call op: " << callOp << "\n");
+ auto module = callOp->getParentOfType<mlir::ModuleOp>();
+ bool needUpdate = false;
+ fir::FirOpBuilder builder(rewriter, module);
+ llvm::SmallVector<mlir::Value> newOperands;
+ llvm::SmallVector<std::pair<mlir::Operation *, mlir::Operation *>> allocas;
+ for (const mlir::Value &a : callOp.getArgs()) {
+ auto alloca = mlir::dyn_cast_or_null<fir::AllocaOp>(a.getDefiningOp());
+ // We can convert arguments that are alloca, and that has
+ // the value by reference attribute. All else is just added
+ // to the argument list.
+ if (!alloca || !alloca->hasAttr(fir::getAdaptToByRefAttrName())) {
+ newOperands.push_back(a);
+ continue;
+ }
+
+ mlir::Type varTy = alloca.getInType();
+ assert(!fir::hasDynamicSize(varTy) &&
+ "only expect statically sized scalars to be by value");
+
+ // Find immediate store with const argument
+ mlir::Operation *store = nullptr;
+ for (mlir::Operation *s : alloca->getUsers()) {
+ if (mlir::isa<fir::StoreOp>(s) && di.dominates(s, callOp)) {
+ // We can only deal with ONE store - if already found one,
+ // set to nullptr and exit the loop.
+ if (store) {
+ store = nullptr;
+ break;
+ }
+ store = s;
+ }
+ }
+
+ // If we didn't find any store, or multiple stores, add argument as is
+ // and move on.
+ if (!store) {
+ newOperands.push_back(a);
+ continue;
+ }
+
+ LLVM_DEBUG(llvm::dbgs() << " found store " << *store << "\n");
+
+ mlir::Operation *definingOp = store->getOperand(0).getDefiningOp();
+ // If not a constant, add to operands and move on.
+ if (!mlir::isa<mlir::arith::ConstantOp>(definingOp)) {
+ // Unable to remove alloca arg
+ newOperands.push_back(a);
+ continue;
+ }
+
+ LLVM_DEBUG(llvm::dbgs() << " found define " << *definingOp << "\n");
+
+ std::string globalName =
+ "_global_const_." + std::to_string(uniqueLitId++);
+ assert(!builder.getNamedGlobal(globalName) &&
+ "We should have a unique name here");
+
+ if (std::find_if(allocas.begin(), allocas.end(), [alloca](auto x) {
+ return x.first == alloca;
+ }) == allocas.end()) {
+ allocas.push_back(std::make_pair(alloca, store));
+ }
+
+ auto loc = callOp.getLoc();
+ fir::GlobalOp global = builder.createGlobalConstant(
+ loc, varTy, globalName,
+ [&](fir::FirOpBuilder &builder) {
+ mlir::Operation *cln = definingOp->clone();
+ builder.insert(cln);
+ mlir::Value val =
+ builder.createConvert(loc, varTy, cln->getResult(0));
+ builder.create<fir::HasValueOp>(loc, val);
+ },
+ builder.createInternalLinkage());
+ mlir::Value addr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
+ global.getSymbol());
+ newOperands.push_back(addr);
+ needUpdate = true;
+ }
+
+ if (needUpdate) {
+ auto loc = callOp.getLoc();
+ llvm::SmallVector<mlir::Type> newResultTypes;
+ newResultTypes.append(callOp.getResultTypes().begin(),
+ callOp.getResultTypes().end());
+ fir::CallOp newOp = builder.create<fir::CallOp>(
+ loc, newResultTypes,
+ callOp.getCallee().has_value() ? callOp.getCallee().value()
+ : mlir::SymbolRefAttr{},
+ newOperands);
+ // Copy all the attributes from the old to new op.
+ newOp->setAttrs(callOp->getAttrs());
+ rewriter.replaceOp(callOp, newOp);
+
+ for (auto a : allocas) {
+ if (a.first->hasOneUse()) {
+ // If the alloca is only used for a store and the call operand, the
+ // store is no longer required.
+ rewriter.eraseOp(a.second);
+ rewriter.eraseOp(a.first);
+ }
+ }
+ LLVM_DEBUG(llvm::dbgs() << "global constant for " << callOp << " as "
+ << newOp << '\n');
+ return mlir::success();
+ }
+
+ // Failure here just means "we couldn't do the conversion", which is
+ // perfectly acceptable to the upper layers of this function.
+ return mlir::failure();
+ }
+};
+
+// this pass attempts to convert immediate scalar literals in function calls
+// to global constants to allow transformations such as Dead Argument
+// Elimination
+class ConstantArgumentGlobalisationOpt
+ : public fir::impl::ConstantArgumentGlobalisationOptBase<
+ ConstantArgumentGlobalisationOpt> {
+public:
+ ConstantArgumentGlobalisationOpt() = default;
+
+ void runOnOperation() override {
+ mlir::ModuleOp mod = getOperation();
+ mlir::DominanceInfo *di = &getAnalysis<mlir::DominanceInfo>();
+ auto *context = &getContext();
+ mlir::RewritePatternSet patterns(context);
+ mlir::GreedyRewriteConfig config;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
+ config.strictMode = mlir::GreedyRewriteStrictness::ExistingOps;
+
+ patterns.insert<CallOpRewriter>(context, *di);
+ if (mlir::failed(mlir::applyPatternsAndFoldGreedily(
+ mod, std::move(patterns), config))) {
+ mlir::emitError(mod.getLoc(),
+ "error in constant globalisation optimization\n");
+ signalPassFailure();
+ }
+ }
+};
+} // namespace
diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
index a233e7fbdcd1..1af5a68e8529 100644
--- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
+++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
@@ -132,10 +132,14 @@ public:
auto comparison = rewriter.create<mlir::arith::CmpIOp>(
loc, arith::CmpIPredicate::sgt, itersLeft, zero);
- rewriter.create<mlir::cf::CondBranchOp>(
+ auto cond = rewriter.create<mlir::cf::CondBranchOp>(
loc, comparison, firstBlock, llvm::ArrayRef<mlir::Value>(), endBlock,
llvm::ArrayRef<mlir::Value>());
+ // Copy loop annotations from the do loop to the loop entry condition.
+ if (auto ann = loop.getLoopAnnotation())
+ cond->setAttr("loop_annotation", *ann);
+
// The result of the loop operation is the values of the condition block
// arguments except the induction variable on the last iteration.
auto args = loop.getFinalValue()
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index a174f2c2bc4b..71cfee6d735a 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -13,15 +13,59 @@
#define DEBUG_TYPE "flang-debug-type-generator"
#include "DebugTypeGenerator.h"
+#include "flang/Optimizer/CodeGen/DescriptorModel.h"
+#include "flang/Optimizer/CodeGen/TypeConverter.h"
+#include "flang/Optimizer/Support/DataLayout.h"
+#include "mlir/Pass/Pass.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Debug.h"
namespace fir {
+/// Calculate offset of any field in the descriptor.
+template <int DescriptorField>
+std::uint64_t getComponentOffset(const mlir::DataLayout &dl,
+ mlir::MLIRContext *context,
+ mlir::Type llvmFieldType) {
+ static_assert(DescriptorField > 0 && DescriptorField < 10);
+ mlir::Type previousFieldType =
+ getDescFieldTypeModel<DescriptorField - 1>()(context);
+ std::uint64_t previousOffset =
+ getComponentOffset<DescriptorField - 1>(dl, context, previousFieldType);
+ std::uint64_t offset = previousOffset + dl.getTypeSize(previousFieldType);
+ std::uint64_t fieldAlignment = dl.getTypeABIAlignment(llvmFieldType);
+ return llvm::alignTo(offset, fieldAlignment);
+}
+template <>
+std::uint64_t getComponentOffset<0>(const mlir::DataLayout &dl,
+ mlir::MLIRContext *context,
+ mlir::Type llvmFieldType) {
+ return 0;
+}
+
DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
: module(m), kindMapping(getKindMapping(m)) {
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
+
+ std::optional<mlir::DataLayout> dl =
+ fir::support::getOrSetDataLayout(module, /*allowDefaultLayout=*/true);
+ if (!dl) {
+ mlir::emitError(module.getLoc(), "Missing data layout attribute in module");
+ return;
+ }
+
+ mlir::MLIRContext *context = module.getContext();
+
+ // The debug information requires the offset of certain fields in the
+ // descriptors like lower_bound and extent for each dimension.
+ mlir::Type llvmDimsType = getDescFieldTypeModel<kDimsPosInBox>()(context);
+ mlir::Type llvmPtrType = getDescFieldTypeModel<kAddrPosInBox>()(context);
+ mlir::Type llvmLenType = getDescFieldTypeModel<kElemLenPosInBox>()(context);
+ dimsOffset = getComponentOffset<kDimsPosInBox>(*dl, context, llvmDimsType);
+ dimsSize = dl->getTypeSize(llvmDimsType);
+ ptrSize = dl->getTypeSize(llvmPtrType);
+ lenOffset = getComponentOffset<kElemLenPosInBox>(*dl, context, llvmLenType);
}
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
@@ -33,14 +77,85 @@ static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
}
static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
- return genBasicType(context, mlir::StringAttr::get(context, "integer"), 32,
- llvm::dwarf::DW_ATE_signed);
+ return genBasicType(context, mlir::StringAttr::get(context, "integer"),
+ /*bitSize=*/32, llvm::dwarf::DW_ATE_signed);
+}
+
+mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
+ fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
+ bool genAssociated) {
+
+ mlir::MLIRContext *context = module.getContext();
+ // FIXME: Assumed rank arrays not supported yet
+ if (seqTy.hasUnknownShape())
+ return genPlaceholderType(context);
+
+ llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
+ auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
+ ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
+ };
+
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_deref, {});
+
+ // dataLocation = *base_addr
+ mlir::LLVM::DIExpressionAttr dataLocation =
+ mlir::LLVM::DIExpressionAttr::get(context, ops);
+ addOp(llvm::dwarf::DW_OP_lit0, {});
+ addOp(llvm::dwarf::DW_OP_ne, {});
+
+ // allocated = associated = (*base_addr != 0)
+ mlir::LLVM::DIExpressionAttr valid =
+ mlir::LLVM::DIExpressionAttr::get(context, ops);
+ mlir::LLVM::DIExpressionAttr allocated = genAllocated ? valid : nullptr;
+ mlir::LLVM::DIExpressionAttr associated = genAssociated ? valid : nullptr;
+ ops.clear();
+
+ llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
+ mlir::LLVM::DITypeAttr elemTy =
+ convertType(seqTy.getEleTy(), fileAttr, scope, loc);
+ unsigned offset = dimsOffset;
+ const unsigned indexSize = dimsSize / 3;
+ for ([[maybe_unused]] auto _ : seqTy.getShape()) {
+ // For each dimension, find the offset of count and lower bound in the
+ // descriptor and generate the dwarf expression to extract it.
+ // FIXME: If `indexSize` happens to be bigger than address size on the
+ // system then we may have to change 'DW_OP_deref' here.
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_plus_uconst,
+ {offset + (indexSize * kDimExtentPos)});
+ addOp(llvm::dwarf::DW_OP_deref, {});
+ // count[i] = *(base_addr + offset + (indexSize * kDimExtentPos))
+ // where 'offset' is dimsOffset + (i * dimsSize)
+ mlir::LLVM::DIExpressionAttr countAttr =
+ mlir::LLVM::DIExpressionAttr::get(context, ops);
+ ops.clear();
+
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_plus_uconst,
+ {offset + (indexSize * kDimLowerBoundPos)});
+ addOp(llvm::dwarf::DW_OP_deref, {});
+ // lower_bound[i] = *(base_addr + offset + (indexSize * kDimLowerBoundPos))
+ mlir::LLVM::DIExpressionAttr lowerAttr =
+ mlir::LLVM::DIExpressionAttr::get(context, ops);
+ ops.clear();
+
+ offset += dimsSize;
+ mlir::LLVM::DISubrangeAttr subrangeTy = mlir::LLVM::DISubrangeAttr::get(
+ context, nullptr, lowerAttr, countAttr, nullptr);
+ elements.push_back(subrangeTy);
+ }
+ return mlir::LLVM::DICompositeTypeAttr::get(
+ context, llvm::dwarf::DW_TAG_array_type, /*recursive_id=*/{},
+ /*name=*/nullptr, /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
+ mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0, elements,
+ dataLocation, /*rank=*/nullptr, allocated, associated);
}
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
-
mlir::MLIRContext *context = module.getContext();
// FIXME: Only fixed sizes arrays handled at the moment.
if (seqTy.hasDynamicExtents())
@@ -70,12 +185,83 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
// have been set to some valid default values.
return mlir::LLVM::DICompositeTypeAttr::get(
- context, llvm::dwarf::DW_TAG_array_type, /*recursive id*/ {},
- /* name */ nullptr, /* file */ nullptr, /* line */ 0, /* scope */ nullptr,
- elemTy, mlir::LLVM::DIFlags::Zero, /* sizeInBits */ 0,
- /*alignInBits*/ 0, elements, /* dataLocation */ nullptr,
- /* rank */ nullptr, /* allocated */ nullptr,
- /* associated */ nullptr);
+ context, llvm::dwarf::DW_TAG_array_type, /*recursive_id=*/{},
+ /*name=*/nullptr, /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, elemTy,
+ mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0, elements,
+ /*dataLocation=*/nullptr, /*rank=*/nullptr, /*allocated=*/nullptr,
+ /*associated=*/nullptr);
+}
+
+mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
+ fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool hasDescriptor) {
+ mlir::MLIRContext *context = module.getContext();
+
+ // DWARF 5 says the following about the character encoding in 5.1.1.2.
+ // "DW_ATE_ASCII and DW_ATE_UCS specify encodings for the Fortran 2003
+ // string kinds ASCII (ISO/IEC 646:1991) and ISO_10646 (UCS-4 in ISO/IEC
+ // 10646:2000)."
+ unsigned encoding = llvm::dwarf::DW_ATE_ASCII;
+ if (charTy.getFKind() != 1)
+ encoding = llvm::dwarf::DW_ATE_UCS;
+
+ uint64_t sizeInBits = 0;
+ mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
+ mlir::LLVM::DIExpressionAttr locExpr = nullptr;
+
+ if (hasDescriptor) {
+ llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
+ auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
+ ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
+ };
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_plus_uconst, {lenOffset});
+ lenExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+ ops.clear();
+
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_deref, {});
+ locExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+ } else if (charTy.hasConstantLen()) {
+ sizeInBits =
+ charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());
+ } else {
+ return genPlaceholderType(context);
+ }
+
+ // FIXME: Currently the DIStringType in llvm does not have the option to set
+ // type of the underlying character. This restricts out ability to represent
+ // string with non-default characters. Please see issue #95440 for more
+ // details.
+ return mlir::LLVM::DIStringTypeAttr::get(
+ context, llvm::dwarf::DW_TAG_string_type,
+ mlir::StringAttr::get(context, ""), sizeInBits, /*alignInBits=*/0,
+ /*stringLength=*/nullptr, lenExpr, locExpr, encoding);
+}
+
+mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
+ mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
+ bool genAssociated) {
+ mlir::MLIRContext *context = module.getContext();
+
+ // Arrays and character need different treatment because DWARF have special
+ // constructs for them to get the location from the descriptor. Rest of
+ // types are handled like pointer to underlying type.
+ if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
+ return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, genAllocated,
+ genAssociated);
+ if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
+ return convertCharacterType(charTy, fileAttr, scope, loc,
+ /*hasDescriptor=*/true);
+
+ mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
+
+ return mlir::LLVM::DIDerivedTypeAttr::get(
+ context, llvm::dwarf::DW_TAG_pointer_type,
+ mlir::StringAttr::get(context, ""), elTyAttr, ptrSize,
+ /*alignInBits=*/0, /*offset=*/0,
+ /*optional<address space>=*/std::nullopt, /*extra data=*/nullptr);
}
mlir::LLVM::DITypeAttr
@@ -112,6 +298,23 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
return convertSequenceType(seqTy, fileAttr, scope, loc);
+ } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
+ return convertCharacterType(charTy, fileAttr, scope, loc,
+ /*hasDescriptor=*/false);
+ } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
+ auto elTy = boxTy.getElementType();
+ if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
+ return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, false,
+ false);
+ if (auto heapTy = mlir::dyn_cast_or_null<fir::HeapType>(elTy))
+ return convertPointerLikeType(heapTy.getElementType(), fileAttr, scope,
+ loc, /*genAllocated=*/true,
+ /*genAssociated=*/false);
+ if (auto ptrTy = mlir::dyn_cast_or_null<fir::PointerType>(elTy))
+ return convertPointerLikeType(ptrTy.getElementType(), fileAttr, scope,
+ loc, /*genAllocated=*/false,
+ /*genAssociated=*/true);
+ return genPlaceholderType(context);
} else {
// FIXME: These types are currently unhandled. We are generating a
// placeholder type to allow us to test supported bits.
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index 963c919d6682..ec881e8be7ca 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -35,8 +35,33 @@ private:
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
mlir::Location loc);
+
+ /// The 'genAllocated' is true when we want to generate 'allocated' field
+ /// in the DICompositeType. It is needed for the allocatable arrays.
+ /// Similarly, 'genAssociated' is used with 'pointer' type to generate
+ /// 'associated' field.
+ mlir::LLVM::DITypeAttr
+ convertBoxedSequenceType(fir::SequenceType seqTy,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
+ bool genAllocated, bool genAssociated);
+ mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope,
+ mlir::Location loc,
+ bool hasDescriptor);
+
+ mlir::LLVM::DITypeAttr
+ convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
+ bool genAllocated, bool genAssociated);
+
mlir::ModuleOp module;
KindMapping kindMapping;
+ std::uint64_t dimsSize;
+ std::uint64_t dimsOffset;
+ std::uint64_t ptrSize;
+ std::uint64_t lenOffset;
};
} // namespace fir
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
index f54080f21b96..69c41595974e 100644
--- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -15,7 +15,6 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
namespace fir {
-#define GEN_PASS_DECL_FUNCTIONATTR
#define GEN_PASS_DEF_FUNCTIONATTR
#include "flang/Optimizer/Transforms/Passes.h.inc"
} // namespace fir
@@ -76,22 +75,3 @@ void FunctionAttrPass::runOnOperation() {
LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
}
-
-std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass(
- fir::FunctionAttrTypes &functionAttr, bool noInfsFPMath, bool noNaNsFPMath,
- bool approxFuncFPMath, bool noSignedZerosFPMath, bool unsafeFPMath) {
- FunctionAttrOptions opts;
- // Frame pointer
- opts.framePointerKind = functionAttr.framePointerKind;
- opts.noInfsFPMath = noInfsFPMath;
- opts.noNaNsFPMath = noNaNsFPMath;
- opts.approxFuncFPMath = approxFuncFPMath;
- opts.noSignedZerosFPMath = noSignedZerosFPMath;
- opts.unsafeFPMath = unsafeFPMath;
-
- return std::make_unique<FunctionAttrPass>(opts);
-}
-
-std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass() {
- return std::make_unique<FunctionAttrPass>();
-}
diff --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp
index 16bbb1c35646..7157b55b47c9 100644
--- a/flang/lib/Optimizer/Transforms/StackArrays.cpp
+++ b/flang/lib/Optimizer/Transforms/StackArrays.cpp
@@ -767,7 +767,7 @@ void StackArraysPass::runOnFunc(mlir::Operation *func) {
mlir::RewritePatternSet patterns(&context);
mlir::GreedyRewriteConfig config;
// prevent the pattern driver form merging blocks
- config.enableRegionSimplification = false;
+ config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
patterns.insert<AllocMemConversion>(&context, *candidateOps);
if (mlir::failed(mlir::applyOpPatternsAndFold(opsToConvert,
diff --git a/flang/lib/Optimizer/Transforms/StackReclaim.cpp b/flang/lib/Optimizer/Transforms/StackReclaim.cpp
new file mode 100644
index 000000000000..e5e0e4eab829
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/StackReclaim.cpp
@@ -0,0 +1,52 @@
+//===- StackReclaim.cpp -- Insert stacksave/stackrestore in region --------===//
+//
+// 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 "flang/Common/Fortran.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Matchers.h"
+#include "mlir/Pass/Pass.h"
+
+namespace fir {
+#define GEN_PASS_DEF_STACKRECLAIM
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+using namespace mlir;
+
+namespace {
+
+class StackReclaimPass : public fir::impl::StackReclaimBase<StackReclaimPass> {
+public:
+ using StackReclaimBase<StackReclaimPass>::StackReclaimBase;
+
+ void runOnOperation() override;
+};
+} // namespace
+
+void StackReclaimPass::runOnOperation() {
+ auto *op = getOperation();
+ auto *context = &getContext();
+ mlir::OpBuilder builder(context);
+ mlir::Type voidPtr = mlir::LLVM::LLVMPointerType::get(context);
+
+ op->walk([&](fir::DoLoopOp loopOp) {
+ mlir::Location loc = loopOp.getLoc();
+
+ if (!loopOp.getRegion().getOps<fir::AllocaOp>().empty()) {
+ builder.setInsertionPointToStart(&loopOp.getRegion().front());
+ auto stackSaveOp = builder.create<LLVM::StackSaveOp>(loc, voidPtr);
+
+ auto *terminator = loopOp.getRegion().back().getTerminator();
+ builder.setInsertionPoint(terminator);
+ builder.create<LLVM::StackRestoreOp>(loc, stackSaveOp);
+ }
+ });
+}
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index ff01974b549a..746d04ad649d 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -735,7 +735,8 @@ TYPE_PARSER(construct<AccessSpec>("PUBLIC" >> pure(AccessSpec::Kind::Public)) ||
// BIND ( C [, NAME = scalar-default-char-constant-expr] )
// R1528 proc-language-binding-spec -> language-binding-spec
TYPE_PARSER(construct<LanguageBindingSpec>(
- "BIND ( C" >> maybe(", NAME =" >> scalarDefaultCharConstantExpr) / ")"))
+ "BIND ( C" >> maybe(", NAME =" >> scalarDefaultCharConstantExpr),
+ (", CDEFINED" >> pure(true) || pure(false)) / ")"))
// R809 coarray-spec -> deferred-coshape-spec-list | explicit-coshape-spec
// N.B. Bracketed here rather than around references, for consistency with
@@ -1276,10 +1277,13 @@ constexpr auto loopCount{
constexpr auto assumeAligned{"ASSUME_ALIGNED" >>
optionalList(construct<CompilerDirective::AssumeAligned>(
indirect(designator), ":"_tok >> digitString64))};
+constexpr auto vectorAlways{
+ "VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()};
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
sourced((construct<CompilerDirective>(ignore_tkr) ||
construct<CompilerDirective>(loopCount) ||
construct<CompilerDirective>(assumeAligned) ||
+ construct<CompilerDirective>(vectorAlways) ||
construct<CompilerDirective>(
many(construct<CompilerDirective::NameValue>(
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
diff --git a/flang/lib/Parser/expr-parsers.cpp b/flang/lib/Parser/expr-parsers.cpp
index a47aae166b57..77a13de7fd02 100644
--- a/flang/lib/Parser/expr-parsers.cpp
+++ b/flang/lib/Parser/expr-parsers.cpp
@@ -70,7 +70,8 @@ TYPE_PARSER(construct<AcImpliedDoControl>(
constexpr auto primary{instrumented("primary"_en_US,
first(construct<Expr>(indirect(Parser<CharLiteralConstantSubstring>{})),
construct<Expr>(literalConstant),
- construct<Expr>(construct<Expr::Parentheses>(parenthesized(expr))),
+ construct<Expr>(construct<Expr::Parentheses>("(" >>
+ expr / !","_tok / recovery(")"_tok, SkipPastNested<'(', ')'>{}))),
construct<Expr>(indirect(functionReference) / !"("_tok / !"%"_tok),
construct<Expr>(designator / !"("_tok / !"%"_tok),
construct<Expr>(indirect(Parser<SubstringInquiry>{})), // %LEN or %KIND
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index e67dbcca30e7..0ea48ce29ca2 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -378,6 +378,7 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
"DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_distribute),
"DO SIMD" >> pure(llvm::omp::Directive::OMPD_do_simd),
"DO" >> pure(llvm::omp::Directive::OMPD_do),
+ "LOOP" >> pure(llvm::omp::Directive::OMPD_loop),
"MASKED TASKLOOP SIMD" >>
pure(llvm::omp::Directive::OMPD_masked_taskloop_simd),
"MASKED TASKLOOP" >> pure(llvm::omp::Directive::OMPD_masked_taskloop),
@@ -388,9 +389,12 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
"PARALLEL MASKED TASKLOOP" >>
pure(llvm::omp::Directive::OMPD_parallel_masked_taskloop),
"SIMD" >> pure(llvm::omp::Directive::OMPD_simd),
+ "TARGET LOOP" >> pure(llvm::omp::Directive::OMPD_target_loop),
"TARGET PARALLEL DO SIMD" >>
pure(llvm::omp::Directive::OMPD_target_parallel_do_simd),
"TARGET PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_target_parallel_do),
+ "TARGET PARALLEL LOOP" >>
+ pure(llvm::omp::Directive::OMPD_target_parallel_loop),
"TARGET SIMD" >> pure(llvm::omp::Directive::OMPD_target_simd),
"TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
pure(llvm::omp::Directive::
@@ -401,6 +405,7 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
pure(llvm::omp::Directive::OMPD_target_teams_distribute_simd),
"TARGET TEAMS DISTRIBUTE" >>
pure(llvm::omp::Directive::OMPD_target_teams_distribute),
+ "TARGET TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_target_teams_loop),
"TASKLOOP SIMD" >> pure(llvm::omp::Directive::OMPD_taskloop_simd),
"TASKLOOP" >> pure(llvm::omp::Directive::OMPD_taskloop),
"TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index f9b9c3d2c6e5..42aa829e0ed5 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -105,13 +105,15 @@ void Prescanner::Statement() {
NextLine();
return;
case LineClassification::Kind::ConditionalCompilationDirective:
- case LineClassification::Kind::DefinitionDirective:
- case LineClassification::Kind::PreprocessorDirective:
+ case LineClassification::Kind::IncludeDirective:
preprocessor_.Directive(TokenizePreprocessorDirective(), *this);
+ afterPreprocessingDirective_ = true;
+ skipLeadingAmpersand_ |= !inFixedForm_;
return;
- case LineClassification::Kind::IncludeDirective:
+ case LineClassification::Kind::PreprocessorDirective:
+ case LineClassification::Kind::DefinitionDirective:
preprocessor_.Directive(TokenizePreprocessorDirective(), *this);
- afterIncludeDirective_ = true;
+ // Don't set afterPreprocessingDirective_
return;
case LineClassification::Kind::CompilerDirective: {
directiveSentinel_ = line.sentinel;
@@ -171,15 +173,37 @@ void Prescanner::Statement() {
NextChar();
}
LabelField(tokens);
- } else if (skipLeadingAmpersand_) {
- skipLeadingAmpersand_ = false;
- const char *p{SkipWhiteSpace(at_)};
- if (p < limit_ && *p == '&') {
- column_ += ++p - at_;
- at_ = p;
- }
} else {
- SkipSpaces();
+ if (skipLeadingAmpersand_) {
+ skipLeadingAmpersand_ = false;
+ const char *p{SkipWhiteSpace(at_)};
+ if (p < limit_ && *p == '&') {
+ column_ += ++p - at_;
+ at_ = p;
+ }
+ } else {
+ SkipSpaces();
+ }
+ // Check for a leading identifier that might be a keyword macro
+ // that will expand to anything indicating a non-source line, like
+ // a comment marker or directive sentinel. If so, disable line
+ // continuation, so that NextToken() won't consume anything from
+ // following lines.
+ if (IsLegalIdentifierStart(*at_) && NextToken(tokens) &&
+ tokens.SizeInTokens() > 0) {
+ if (CharBlock id{tokens.TokenAt(0)}; preprocessor_.IsNameDefined(id) &&
+ !preprocessor_.IsFunctionLikeDefinition(id)) {
+ if (auto replaced{preprocessor_.MacroReplacement(tokens, *this)}) {
+ auto newLineClass{ClassifyLine(*replaced, GetCurrentProvenance())};
+ disableSourceContinuation_ =
+ newLineClass.kind != LineClassification::Kind::Source;
+ if (newLineClass.kind ==
+ LineClassification::Kind::CompilerDirective) {
+ directiveSentinel_ = newLineClass.sentinel;
+ }
+ }
+ }
+ }
}
break;
}
@@ -197,17 +221,13 @@ void Prescanner::Statement() {
Provenance newlineProvenance{GetCurrentProvenance()};
if (std::optional<TokenSequence> preprocessed{
preprocessor_.MacroReplacement(tokens, *this)}) {
- // Reprocess the preprocessed line. Append a newline temporarily.
- preprocessed->PutNextTokenChar('\n', newlineProvenance);
- preprocessed->CloseToken();
- const char *ppd{preprocessed->ToCharBlock().begin()};
- LineClassification ppl{ClassifyLine(ppd)};
- preprocessed->pop_back(); // remove the newline
+ // Reprocess the preprocessed line.
+ LineClassification ppl{ClassifyLine(*preprocessed, newlineProvenance)};
switch (ppl.kind) {
case LineClassification::Kind::Comment:
break;
case LineClassification::Kind::IncludeLine:
- FortranInclude(ppd + ppl.payloadOffset);
+ FortranInclude(preprocessed->TokenAt(0).begin() + ppl.payloadOffset);
break;
case LineClassification::Kind::ConditionalCompilationDirective:
case LineClassification::Kind::IncludeDirective:
@@ -270,21 +290,28 @@ void Prescanner::Statement() {
void Prescanner::CheckAndEmitLine(
TokenSequence &tokens, Provenance newlineProvenance) {
- tokens.CheckBadFortranCharacters(messages_, *this);
+ tokens.CheckBadFortranCharacters(
+ messages_, *this, disableSourceContinuation_);
// Parenthesis nesting check does not apply while any #include is
- // active, nor on the lines before and after a top-level #include.
+ // active, nor on the lines before and after a top-level #include,
+ // nor before or after conditional source.
// Applications play shenanigans with line continuation before and
- // after #include'd subprogram argument lists.
+ // after #include'd subprogram argument lists and conditional source.
if (!isNestedInIncludeDirective_ && !omitNewline_ &&
- !afterIncludeDirective_) {
- tokens.CheckBadParentheses(messages_);
+ !afterPreprocessingDirective_ && tokens.BadlyNestedParentheses() &&
+ !preprocessor_.InConditional()) {
+ if (nextLine_ < limit_ && IsPreprocessorDirectiveLine(nextLine_)) {
+ // don't complain
+ } else {
+ tokens.CheckBadParentheses(messages_);
+ }
}
tokens.Emit(cooked_);
if (omitNewline_) {
omitNewline_ = false;
} else {
cooked_.Put('\n', newlineProvenance);
- afterIncludeDirective_ = false;
+ afterPreprocessingDirective_ = false;
}
}
@@ -331,7 +358,17 @@ void Prescanner::LabelField(TokenSequence &token) {
++column_;
}
if (badColumn && !preprocessor_.IsNameDefined(token.CurrentOpenToken())) {
- if (features_.ShouldWarn(common::UsageWarning::Scanning)) {
+ if ((prescannerNesting_ > 0 && *badColumn == 6 &&
+ cooked_.BufferedBytes() == firstCookedCharacterOffset_) ||
+ afterPreprocessingDirective_) {
+ // This is the first source line in #include'd text or conditional
+ // code under #if, or the first source line after such.
+ // If it turns out that the preprocessed text begins with a
+ // fixed form continuation line, the newline at the end
+ // of the latest source line beforehand will be deleted in
+ // CookedSource::Marshal().
+ cooked_.MarkPossibleFixedFormContinuation();
+ } else if (features_.ShouldWarn(common::UsageWarning::Scanning)) {
Say(GetProvenance(start + *badColumn - 1),
*badColumn == 6
? "Statement should not begin with a continuation line"_warn_en_US
@@ -568,7 +605,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
char previous{at_ <= start_ ? ' ' : at_[-1]};
NextChar();
SkipSpaces();
- if (*at_ == '\n') {
+ if (*at_ == '\n' && !omitNewline_) {
// Discard white space at the end of a line.
} else if (!inPreprocessorDirective_ &&
(previous == '(' || *at_ == '(' || *at_ == ')')) {
@@ -1038,6 +1075,17 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) {
return true;
} else if (inPreprocessorDirective_) {
return false;
+ } else if (afterAmpersand &&
+ (lineClass.kind ==
+ LineClassification::Kind::ConditionalCompilationDirective ||
+ lineClass.kind == LineClassification::Kind::DefinitionDirective ||
+ lineClass.kind == LineClassification::Kind::PreprocessorDirective ||
+ lineClass.kind == LineClassification::Kind::IncludeDirective ||
+ lineClass.kind == LineClassification::Kind::IncludeLine)) {
+ SkipToEndOfLine();
+ omitNewline_ = true;
+ skipLeadingAmpersand_ = true;
+ return false;
} else if (lineClass.kind ==
LineClassification::Kind::ConditionalCompilationDirective ||
lineClass.kind == LineClassification::Kind::PreprocessorDirective) {
@@ -1049,13 +1097,6 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) {
// continued line).
preprocessor_.Directive(TokenizePreprocessorDirective(), *this);
return true;
- } else if (afterAmpersand &&
- (lineClass.kind == LineClassification::Kind::IncludeDirective ||
- lineClass.kind == LineClassification::Kind::IncludeLine)) {
- SkipToEndOfLine();
- omitNewline_ = true;
- skipLeadingAmpersand_ = true;
- return false;
} else {
return false;
}
@@ -1243,7 +1284,9 @@ bool Prescanner::IsImplicitContinuation() const {
}
bool Prescanner::Continuation(bool mightNeedFixedFormSpace) {
- if (*at_ == '\n' || *at_ == '&') {
+ if (disableSourceContinuation_) {
+ return false;
+ } else if (*at_ == '\n' || *at_ == '&') {
if (inFixedForm_) {
return FixedFormContinuation(mightNeedFixedFormSpace);
} else {
@@ -1255,8 +1298,9 @@ bool Prescanner::Continuation(bool mightNeedFixedFormSpace) {
BeginSourceLine(nextLine_);
NextLine();
return true;
+ } else {
+ return false;
}
- return false;
}
std::optional<Prescanner::LineClassification>
@@ -1418,6 +1462,17 @@ Prescanner::LineClassification Prescanner::ClassifyLine(
return {LineClassification::Kind::Source};
}
+Prescanner::LineClassification Prescanner::ClassifyLine(
+ TokenSequence &tokens, Provenance newlineProvenance) const {
+ // Append a newline temporarily.
+ tokens.PutNextTokenChar('\n', newlineProvenance);
+ tokens.CloseToken();
+ const char *ppd{tokens.ToCharBlock().begin()};
+ LineClassification classification{ClassifyLine(ppd)};
+ tokens.pop_back(); // remove the newline
+ return classification;
+}
+
void Prescanner::SourceFormChange(std::string &&dir) {
if (dir == "!dir$ free") {
inFixedForm_ = false;
@@ -1445,7 +1500,7 @@ bool Prescanner::CompilerDirectiveContinuation(
return true;
}
CHECK(origSentinel != nullptr);
- directiveSentinel_ = origSentinel; // so IsDirective() is true
+ directiveSentinel_ = origSentinel; // so InCompilerDirective() is true
const char *nextContinuation{
followingLine.kind == LineClassification::Kind::CompilerDirective
? FreeFormContinuationLine(true)
@@ -1457,7 +1512,6 @@ bool Prescanner::CompilerDirectiveContinuation(
auto origNextLine{nextLine_};
BeginSourceLine(nextLine_);
NextLine();
- TokenSequence followingTokens;
if (nextContinuation) {
// What follows is !DIR$ & xxx; skip over the & so that it
// doesn't cause a spurious continuation.
@@ -1467,6 +1521,7 @@ bool Prescanner::CompilerDirectiveContinuation(
// but might become a directive continuation afterwards.
SkipSpaces();
}
+ TokenSequence followingTokens;
while (NextToken(followingTokens)) {
}
if (auto followingPrepro{
@@ -1475,25 +1530,31 @@ bool Prescanner::CompilerDirectiveContinuation(
}
followingTokens.RemoveRedundantBlanks();
std::size_t startAt{0};
- std::size_t keep{followingTokens.SizeInTokens()};
+ std::size_t following{followingTokens.SizeInTokens()};
bool ok{false};
if (nextContinuation) {
ok = true;
} else {
- if (keep >= 3 && followingTokens.TokenAt(0) == "!" &&
- followingTokens.TokenAt(2) == "&") {
+ startAt = 2;
+ if (startAt < following && followingTokens.TokenAt(0) == "!") {
CharBlock sentinel{followingTokens.TokenAt(1)};
if (!sentinel.empty() &&
std::memcmp(sentinel.begin(), origSentinel, sentinel.size()) == 0) {
- startAt = 3;
- keep -= 3;
ok = true;
+ while (
+ startAt < following && followingTokens.TokenAt(startAt).IsBlank()) {
+ ++startAt;
+ }
+ if (startAt < following && followingTokens.TokenAt(startAt) == "&") {
+ ++startAt;
+ }
}
}
}
if (ok) {
tokens.pop_back(); // delete original '&'
- tokens.Put(followingTokens, startAt, keep);
+ tokens.Put(followingTokens, startAt, following - startAt);
+ tokens.RemoveRedundantBlanks();
} else {
nextLine_ = origNextLine;
}
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 491b1fe0a751..421ba97d324c 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -94,6 +94,7 @@ private:
LineClassification(Kind k, std::size_t po = 0, const char *s = nullptr)
: kind{k}, payloadOffset{po}, sentinel{s} {}
LineClassification(LineClassification &&) = default;
+ LineClassification &operator=(LineClassification &&) = default;
Kind kind;
std::size_t payloadOffset; // byte offset of content
const char *sentinel; // if it's a compiler directive
@@ -117,6 +118,7 @@ private:
parenthesisNesting_ = 0;
continuationLines_ = 0;
isPossibleMacroCall_ = false;
+ disableSourceContinuation_ = false;
}
Provenance GetProvenance(const char *sourceChar) const {
@@ -192,6 +194,8 @@ private:
std::optional<LineClassification> IsFreeFormCompilerDirectiveLine(
const char *) const;
LineClassification ClassifyLine(const char *) const;
+ LineClassification ClassifyLine(
+ TokenSequence &, Provenance newlineProvenance) const;
void SourceFormChange(std::string &&);
bool CompilerDirectiveContinuation(TokenSequence &, const char *sentinel);
bool SourceLineContinuation(TokenSequence &);
@@ -210,7 +214,8 @@ private:
int prescannerNesting_{0};
int continuationLines_{0};
bool isPossibleMacroCall_{false};
- bool afterIncludeDirective_{false};
+ bool afterPreprocessingDirective_{false};
+ bool disableSourceContinuation_{false};
Provenance startProvenance_;
const char *start_{nullptr}; // beginning of current source file content
@@ -242,6 +247,8 @@ private:
bool omitNewline_{false};
bool skipLeadingAmpersand_{false};
+ const std::size_t firstCookedCharacterOffset_{cooked_.BufferedBytes()};
+
const Provenance spaceProvenance_{
allSources_.CompilerInsertionProvenance(' ')};
const Provenance backslashProvenance_{
diff --git a/flang/lib/Parser/program-parsers.cpp b/flang/lib/Parser/program-parsers.cpp
index 6f25ba482722..b51b60157f39 100644
--- a/flang/lib/Parser/program-parsers.cpp
+++ b/flang/lib/Parser/program-parsers.cpp
@@ -86,10 +86,15 @@ TYPE_CONTEXT_PARSER("specification part"_en_US,
// are in contexts that impose constraints on the kinds of statements that
// are allowed, and so we have a variant production for declaration-construct
// that implements those constraints.
-constexpr auto execPartLookAhead{first(actionStmt >> ok, openaccConstruct >> ok,
- openmpConstruct >> ok, "ASSOCIATE ("_tok, "BLOCK"_tok, "SELECT"_tok,
- "CHANGE TEAM"_sptok, "CRITICAL"_tok, "DO"_tok, "IF ("_tok, "WHERE ("_tok,
- "FORALL ("_tok, "!$CUF"_tok)};
+constexpr auto actionStmtLookAhead{first(actionStmt >> ok,
+ // Also accept apparent action statements with errors if they might be
+ // first in the execution part
+ "ALLOCATE ("_tok, "CALL" >> name >> "("_tok, "GO TO"_tok, "OPEN ("_tok,
+ "PRINT"_tok / space / !"("_tok, "READ ("_tok, "WRITE ("_tok)};
+constexpr auto execPartLookAhead{first(actionStmtLookAhead >> ok,
+ openaccConstruct >> ok, openmpConstruct >> ok, "ASSOCIATE ("_tok,
+ "BLOCK"_tok, "SELECT"_tok, "CHANGE TEAM"_sptok, "CRITICAL"_tok, "DO"_tok,
+ "IF ("_tok, "WHERE ("_tok, "FORALL ("_tok, "!$CUF"_tok)};
constexpr auto declErrorRecovery{
stmtErrorRecoveryStart >> !execPartLookAhead >> skipStmtErrorRecovery};
constexpr auto misplacedSpecificationStmt{Parser<UseStmt>{} >>
@@ -446,10 +451,13 @@ TYPE_PARSER(extension<LanguageFeature::CUDA>(
"<<<" >> construct<CallStmt::Chevrons>(scalarExpr, "," >> scalarExpr,
maybe("," >> scalarIntExpr), maybe("," >> scalarIntExpr)) /
">>>"))
-TYPE_PARSER(construct<CallStmt>(
- sourced(construct<CallStmt>("CALL" >> Parser<ProcedureDesignator>{},
- maybe(Parser<CallStmt::Chevrons>{}),
- defaulted(parenthesized(optionalList(actualArgSpec)))))))
+constexpr auto actualArgSpecList{optionalList(actualArgSpec)};
+TYPE_CONTEXT_PARSER("CALL statement"_en_US,
+ construct<CallStmt>(
+ sourced(construct<CallStmt>("CALL" >> Parser<ProcedureDesignator>{},
+ maybe(Parser<CallStmt::Chevrons>{}) / space,
+ "(" >> actualArgSpecList / ")" ||
+ lookAhead(endOfStmt) >> defaulted(actualArgSpecList)))))
// R1522 procedure-designator ->
// procedure-name | proc-component-ref | data-ref % binding-name
diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp
index 55ef67fd6288..6e2e7326e216 100644
--- a/flang/lib/Parser/provenance.cpp
+++ b/flang/lib/Parser/provenance.cpp
@@ -513,6 +513,16 @@ void CookedSource::Marshal(AllCookedSources &allCookedSources) {
"(after end of source)"));
data_ = buffer_.Marshal();
buffer_.clear();
+ for (std::size_t ffStart : possibleFixedFormContinuations_) {
+ if (ffStart > 0 && ffStart + 1 < data_.size() &&
+ data_[ffStart - 1] == '\n' && data_[ffStart] == ' ') {
+ // This fixed form include line is the first source line in an
+ // #include file (or after an empty one). Connect it with the previous
+ // source line by deleting its terminal newline.
+ data_[ffStart - 1] = ' ';
+ }
+ }
+ possibleFixedFormContinuations_.clear();
allCookedSources.Register(*this);
}
diff --git a/flang/lib/Parser/token-parsers.h b/flang/lib/Parser/token-parsers.h
index 2495017d1964..fe6bc1f69f57 100644
--- a/flang/lib/Parser/token-parsers.h
+++ b/flang/lib/Parser/token-parsers.h
@@ -560,6 +560,8 @@ template <char goal> struct SkipPast {
while (std::optional<const char *> p{state.GetNextChar()}) {
if (**p == goal) {
return {Success{}};
+ } else if (**p == '\n') {
+ break;
}
}
return std::nullopt;
@@ -574,8 +576,32 @@ template <char goal> struct SkipTo {
while (std::optional<const char *> p{state.PeekAtNextChar()}) {
if (**p == goal) {
return {Success{}};
+ } else if (**p == '\n') {
+ break;
+ } else {
+ state.UncheckedAdvance();
+ }
+ }
+ return std::nullopt;
+ }
+};
+
+template <char left, char right> struct SkipPastNested {
+ using resultType = Success;
+ constexpr SkipPastNested() {}
+ constexpr SkipPastNested(const SkipPastNested &) {}
+ static std::optional<Success> Parse(ParseState &state) {
+ int nesting{1};
+ while (std::optional<const char *> p{state.GetNextChar()}) {
+ if (**p == right) {
+ if (!--nesting) {
+ return {Success{}};
+ }
+ } else if (**p == left) {
+ ++nesting;
+ } else if (**p == '\n') {
+ break;
}
- state.UncheckedAdvance();
}
return std::nullopt;
}
diff --git a/flang/lib/Parser/token-sequence.cpp b/flang/lib/Parser/token-sequence.cpp
index d0254ecd5aae..133e60ba4f00 100644
--- a/flang/lib/Parser/token-sequence.cpp
+++ b/flang/lib/Parser/token-sequence.cpp
@@ -347,7 +347,8 @@ ProvenanceRange TokenSequence::GetProvenanceRange() const {
}
const TokenSequence &TokenSequence::CheckBadFortranCharacters(
- Messages &messages, const Prescanner &prescanner) const {
+ Messages &messages, const Prescanner &prescanner,
+ bool allowAmpersand) const {
std::size_t tokens{SizeInTokens()};
for (std::size_t j{0}; j < tokens; ++j) {
CharBlock token{TokenAt(j)};
@@ -362,6 +363,8 @@ const TokenSequence &TokenSequence::CheckBadFortranCharacters(
++j;
continue;
}
+ } else if (ch == '&' && allowAmpersand) {
+ continue;
}
if (ch < ' ' || ch >= '\x7f') {
messages.Say(GetTokenProvenanceRange(j),
@@ -375,9 +378,7 @@ const TokenSequence &TokenSequence::CheckBadFortranCharacters(
return *this;
}
-const TokenSequence &TokenSequence::CheckBadParentheses(
- Messages &messages) const {
- // First, a quick pass with no allocation for the common case
+bool TokenSequence::BadlyNestedParentheses() const {
int nesting{0};
std::size_t tokens{SizeInTokens()};
for (std::size_t j{0}; j < tokens; ++j) {
@@ -391,8 +392,14 @@ const TokenSequence &TokenSequence::CheckBadParentheses(
}
}
}
- if (nesting != 0) {
+ return nesting != 0;
+}
+
+const TokenSequence &TokenSequence::CheckBadParentheses(
+ Messages &messages) const {
+ if (BadlyNestedParentheses()) {
// There's an error; diagnose it
+ std::size_t tokens{SizeInTokens()};
std::vector<std::size_t> stack;
for (std::size_t j{0}; j < tokens; ++j) {
CharBlock token{TokenAt(j)};
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index b98aae8e8f7a..2511a5dda9d0 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -524,7 +524,13 @@ public:
Word("NULL()");
}
void Unparse(const LanguageBindingSpec &x) { // R808 & R1528
- Word("BIND(C"), Walk(", NAME=", x.v), Put(')');
+ Word("BIND(C");
+ Walk(
+ ", NAME=", std::get<std::optional<ScalarDefaultCharConstantExpr>>(x.t));
+ if (std::get<bool>(x.t)) {
+ Word(", CDEFINED");
+ }
+ Put(')');
}
void Unparse(const CoarraySpec &x) { // R809
common::visit(common::visitors{
@@ -1828,6 +1834,9 @@ public:
Word("!DIR$ ASSUME_ALIGNED ");
Walk(" ", assumeAligned, ", ");
},
+ [&](const CompilerDirective::VectorAlways &valways) {
+ Word("!DIR$ VECTOR ALWAYS");
+ },
[&](const std::list<CompilerDirective::NameValue> &names) {
Walk("!DIR$ ", names, " ");
},
@@ -2198,6 +2207,9 @@ public:
case llvm::omp::Directive::OMPD_do_simd:
Word("DO SIMD ");
break;
+ case llvm::omp::Directive::OMPD_loop:
+ Word("LOOP ");
+ break;
case llvm::omp::Directive::OMPD_masked_taskloop_simd:
Word("MASKED TASKLOOP SIMD");
break;
@@ -2219,12 +2231,18 @@ public:
case llvm::omp::Directive::OMPD_simd:
Word("SIMD ");
break;
+ case llvm::omp::Directive::OMPD_target_loop:
+ Word("TARGET LOOP ");
+ break;
case llvm::omp::Directive::OMPD_target_parallel_do:
Word("TARGET PARALLEL DO ");
break;
case llvm::omp::Directive::OMPD_target_parallel_do_simd:
Word("TARGET PARALLEL DO SIMD ");
break;
+ case llvm::omp::Directive::OMPD_target_parallel_loop:
+ Word("TARGET PARALLEL LOOP ");
+ break;
case llvm::omp::Directive::OMPD_target_teams_distribute:
Word("TARGET TEAMS DISTRIBUTE ");
break;
@@ -2237,6 +2255,9 @@ public:
case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
Word("TARGET TEAMS DISTRIBUTE SIMD ");
break;
+ case llvm::omp::Directive::OMPD_target_teams_loop:
+ Word("TARGET TEAMS LOOP ");
+ break;
case llvm::omp::Directive::OMPD_target_simd:
Word("TARGET SIMD ");
break;
diff --git a/flang/lib/Semantics/CMakeLists.txt b/flang/lib/Semantics/CMakeLists.txt
index 809206565fc1..41406ecf50e0 100644
--- a/flang/lib/Semantics/CMakeLists.txt
+++ b/flang/lib/Semantics/CMakeLists.txt
@@ -2,6 +2,7 @@ add_flang_library(FortranSemantics
assignment.cpp
attr.cpp
canonicalize-acc.cpp
+ canonicalize-directives.cpp
canonicalize-do.cpp
canonicalize-omp.cpp
check-acc-structure.cpp
diff --git a/flang/lib/Semantics/canonicalize-directives.cpp b/flang/lib/Semantics/canonicalize-directives.cpp
new file mode 100644
index 000000000000..ae691ab612ba
--- /dev/null
+++ b/flang/lib/Semantics/canonicalize-directives.cpp
@@ -0,0 +1,124 @@
+//===-- lib/Semantics/canonicalize-directives.cpp -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "canonicalize-directives.h"
+#include "flang/Parser/parse-tree-visitor.h"
+
+namespace Fortran::semantics {
+
+using namespace parser::literals;
+
+// Check that directives are associated with the correct constructs.
+// Directives that need to be associated with other constructs in the execution
+// part are moved to the execution part so they can be checked there.
+class CanonicalizationOfDirectives {
+public:
+ CanonicalizationOfDirectives(parser::Messages &messages)
+ : messages_{messages} {}
+
+ template <typename T> bool Pre(T &) { return true; }
+ template <typename T> void Post(T &) {}
+
+ // Move directives that must appear in the Execution part out of the
+ // Specification part.
+ void Post(parser::SpecificationPart &spec);
+ bool Pre(parser::ExecutionPart &x);
+
+ // Ensure that directives associated with constructs appear accompanying the
+ // construct.
+ void Post(parser::Block &block);
+
+private:
+ // Ensure that loop directives appear immediately before a loop.
+ void CheckLoopDirective(parser::CompilerDirective &dir, parser::Block &block,
+ std::list<parser::ExecutionPartConstruct>::iterator it);
+
+ parser::Messages &messages_;
+
+ // Directives to be moved to the Execution part from the Specification part.
+ std::list<common::Indirection<parser::CompilerDirective>>
+ directivesToConvert_;
+};
+
+bool CanonicalizeDirectives(
+ parser::Messages &messages, parser::Program &program) {
+ CanonicalizationOfDirectives dirs{messages};
+ Walk(program, dirs);
+ return !messages.AnyFatalError();
+}
+
+static bool IsExecutionDirective(const parser::CompilerDirective &dir) {
+ return std::holds_alternative<parser::CompilerDirective::VectorAlways>(dir.u);
+}
+
+void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) {
+ auto &list{
+ std::get<std::list<common::Indirection<parser::CompilerDirective>>>(
+ spec.t)};
+ for (auto it{list.begin()}; it != list.end();) {
+ if (IsExecutionDirective(it->value())) {
+ directivesToConvert_.emplace_back(std::move(*it));
+ it = list.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+bool CanonicalizationOfDirectives::Pre(parser::ExecutionPart &x) {
+ auto origFirst{x.v.begin()};
+ for (auto &dir : directivesToConvert_) {
+ x.v.insert(origFirst,
+ parser::ExecutionPartConstruct{
+ parser::ExecutableConstruct{std::move(dir)}});
+ }
+
+ directivesToConvert_.clear();
+ return true;
+}
+
+template <typename T> T *GetConstructIf(parser::ExecutionPartConstruct &x) {
+ if (auto *y{std::get_if<parser::ExecutableConstruct>(&x.u)}) {
+ if (auto *z{std::get_if<common::Indirection<T>>(&y->u)}) {
+ return &z->value();
+ }
+ }
+ return nullptr;
+}
+
+void CanonicalizationOfDirectives::CheckLoopDirective(
+ parser::CompilerDirective &dir, parser::Block &block,
+ std::list<parser::ExecutionPartConstruct>::iterator it) {
+
+ // Skip over this and other compiler directives
+ while (GetConstructIf<parser::CompilerDirective>(*it)) {
+ ++it;
+ }
+
+ if (it == block.end() || !GetConstructIf<parser::DoConstruct>(*it)) {
+ std::string s{parser::ToUpperCaseLetters(dir.source.ToString())};
+ s.pop_back(); // Remove trailing newline from source string
+ messages_.Say(
+ dir.source, "A DO loop must follow the %s directive"_warn_en_US, s);
+ }
+}
+
+void CanonicalizationOfDirectives::Post(parser::Block &block) {
+ for (auto it{block.begin()}; it != block.end(); ++it) {
+ if (auto *dir{GetConstructIf<parser::CompilerDirective>(*it)}) {
+ std::visit(
+ common::visitors{[&](parser::CompilerDirective::VectorAlways &) {
+ CheckLoopDirective(*dir, block, it);
+ },
+ [&](auto &) {}},
+ dir->u);
+ }
+ }
+}
+
+} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/canonicalize-directives.h b/flang/lib/Semantics/canonicalize-directives.h
new file mode 100644
index 000000000000..89f8a0e3fce4
--- /dev/null
+++ b/flang/lib/Semantics/canonicalize-directives.h
@@ -0,0 +1,22 @@
+//===-- lib/Semantics/canonicalize-directives.h -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_
+#define FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_
+
+namespace Fortran::parser {
+struct Program;
+class Messages;
+} // namespace Fortran::parser
+
+namespace Fortran::semantics {
+bool CanonicalizeDirectives(
+ parser::Messages &messages, parser::Program &program);
+}
+
+#endif // FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 69b9fe17e6a8..25140a047374 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -403,9 +403,9 @@ void AccStructureChecker::CheckMultipleOccurrenceInDeclare(
if (GetContext().directive != llvm::acc::Directive::ACCD_declare)
return;
for (const auto &object : list.v) {
- std::visit(
- Fortran::common::visitors{
- [&](const Fortran::parser::Designator &designator) {
+ common::visit(
+ common::visitors{
+ [&](const parser::Designator &designator) {
if (const auto *name = getDesignatorNameIfDataRef(designator)) {
if (declareSymbols.contains(&name->symbol->GetUltimate())) {
if (declareSymbols[&name->symbol->GetUltimate()] == clause) {
@@ -435,7 +435,7 @@ void AccStructureChecker::CheckMultipleOccurrenceInDeclare(
declareSymbols.insert({&name->symbol->GetUltimate(), clause});
}
},
- [&](const Fortran::parser::Name &name) {
+ [&](const parser::Name &name) {
// TODO: check common block
}},
object.u);
@@ -674,9 +674,9 @@ void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {
const auto &objects{std::get<parser::AccObjectList>(list.t)};
for (const auto &object : objects.v) {
- std::visit(
- Fortran::common::visitors{
- [&](const Fortran::parser::Designator &designator) {
+ common::visit(
+ common::visitors{
+ [&](const parser::Designator &designator) {
if (const auto *name = getDesignatorNameIfDataRef(designator)) {
const auto *type{name->symbol->GetType()};
if (type->IsNumeric(TypeCategory::Integer) &&
diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp
index b4c566067057..a4fa72b03ca1 100644
--- a/flang/lib/Semantics/check-allocate.cpp
+++ b/flang/lib/Semantics/check-allocate.cpp
@@ -539,7 +539,7 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) {
// Shape related checks
if (ultimate_ && evaluate::IsAssumedRank(*ultimate_)) {
context.Say(name_.source,
- "An assumed-rank object may not appear in an ALLOCATE statement"_err_en_US);
+ "An assumed-rank dummy argument may not appear in an ALLOCATE statement"_err_en_US);
return false;
}
if (ultimate_ && IsAssumedSizeArray(*ultimate_) && context.AnyFatalError()) {
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 72576942e62c..8fe90eedc913 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -67,11 +67,9 @@ static void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
messages.Say(
"Coarray argument requires an explicit interface"_err_en_US);
}
- if (const auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
- if (details->IsAssumedRank()) {
- messages.Say(
- "Assumed rank argument requires an explicit interface"_err_en_US);
- }
+ if (evaluate::IsAssumedRank(symbol)) {
+ messages.Say(
+ "Assumed rank argument requires an explicit interface"_err_en_US);
}
if (symbol.attrs().test(Attr::ASYNCHRONOUS)) {
messages.Say(
@@ -143,8 +141,8 @@ static void CheckCharacterActual(evaluate::Expr<evaluate::SomeType> &actual,
bool canAssociate{CanAssociateWithStorageSequence(dummy)};
if (dummy.type.Rank() > 0 && canAssociate) {
// Character storage sequence association (F'2023 15.5.2.12p4)
- if (auto dummySize{evaluate::ToInt64(evaluate::Fold(foldingContext,
- evaluate::GetSize(evaluate::Shape{dummy.type.shape()})))}) {
+ if (auto dummySize{evaluate::ToInt64(evaluate::Fold(
+ foldingContext, evaluate::GetSize(dummy.type.shape())))}) {
auto dummyChars{*dummySize * *dummyLength};
if (actualType.Rank() == 0) {
evaluate::DesignatorFolder folder{
@@ -183,8 +181,7 @@ static void CheckCharacterActual(evaluate::Expr<evaluate::SomeType> &actual,
}
} else { // actual.type.Rank() > 0
if (auto actualSize{evaluate::ToInt64(evaluate::Fold(
- foldingContext,
- evaluate::GetSize(evaluate::Shape(actualType.shape()))))};
+ foldingContext, evaluate::GetSize(actualType.shape())))};
actualSize &&
*actualSize * *actualLength < *dummySize * *dummyLength &&
(extentErrors ||
@@ -251,7 +248,7 @@ static void ConvertIntegerActual(evaluate::Expr<evaluate::SomeType> &actual,
if (dummyType.type().category() == TypeCategory::Integer &&
actualType.type().category() == TypeCategory::Integer &&
dummyType.type().kind() != actualType.type().kind() &&
- GetRank(dummyType.shape()) == 0 && GetRank(actualType.shape()) == 0 &&
+ dummyType.Rank() == 0 && actualType.Rank() == 0 &&
!evaluate::IsVariable(actual)) {
auto converted{
evaluate::ConvertToType(dummyType.type(), std::move(actual))};
@@ -387,10 +384,10 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
// if the actual argument is an array or array element designator,
// and the dummy is an array, but not assumed-shape or an INTENT(IN)
// pointer that's standing in for an assumed-shape dummy.
- } else {
+ } else if (dummy.type.shape() && actualType.shape()) {
// Let CheckConformance accept actual scalars; storage association
// cases are checked here below.
- CheckConformance(messages, dummy.type.shape(), actualType.shape(),
+ CheckConformance(messages, *dummy.type.shape(), *actualType.shape(),
dummyIsAllocatableOrPointer
? evaluate::CheckConformanceFlags::None
: evaluate::CheckConformanceFlags::RightScalarExpandable,
@@ -579,8 +576,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
CanAssociateWithStorageSequence(dummy) &&
!dummy.attrs.test(
characteristics::DummyDataObject::Attr::DeducedFromActual)) {
- if (auto dummySize{evaluate::ToInt64(evaluate::Fold(foldingContext,
- evaluate::GetSize(evaluate::Shape{dummy.type.shape()})))}) {
+ if (auto dummySize{evaluate::ToInt64(evaluate::Fold(
+ foldingContext, evaluate::GetSize(dummy.type.shape())))}) {
if (actualRank == 0 && !actualIsAssumedRank) {
if (evaluate::IsArrayElement(actual)) {
// Actual argument is a scalar array element
@@ -622,8 +619,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
}
} else { // actualRank > 0 || actualIsAssumedRank
- if (auto actualSize{evaluate::ToInt64(evaluate::Fold(foldingContext,
- evaluate::GetSize(evaluate::Shape(actualType.shape()))))};
+ if (auto actualSize{evaluate::ToInt64(evaluate::Fold(
+ foldingContext, evaluate::GetSize(actualType.shape())))};
actualSize && *actualSize < *dummySize &&
(extentErrors ||
context.ShouldWarn(common::UsageWarning::ShortArrayActual))) {
diff --git a/flang/lib/Semantics/check-coarray.cpp b/flang/lib/Semantics/check-coarray.cpp
index 106af7960fa9..6cf61a6b923d 100644
--- a/flang/lib/Semantics/check-coarray.cpp
+++ b/flang/lib/Semantics/check-coarray.cpp
@@ -93,7 +93,7 @@ static void CheckCoindexedStatOrErrmsg(SemanticsContext &context,
}
}
}};
- std::visit(CoindexedCheck, statOrErrmsg.u);
+ Fortran::common::visit(CoindexedCheck, statOrErrmsg.u);
}
static void CheckSyncStatList(
diff --git a/flang/lib/Semantics/check-cuda.cpp b/flang/lib/Semantics/check-cuda.cpp
index 8af50cac8ef5..5b3ea214d63e 100644
--- a/flang/lib/Semantics/check-cuda.cpp
+++ b/flang/lib/Semantics/check-cuda.cpp
@@ -548,8 +548,8 @@ void CUDAChecker::Enter(const parser::AssignmentStmt &x) {
return;
}
- int nbLhs{evaluate::GetNbOfCUDASymbols(assign->lhs)};
- int nbRhs{evaluate::GetNbOfCUDASymbols(assign->rhs)};
+ int nbLhs{evaluate::GetNbOfCUDADeviceSymbols(assign->lhs)};
+ int nbRhs{evaluate::GetNbOfCUDADeviceSymbols(assign->rhs)};
// device to host transfer with more than one device object on the rhs is not
// legal.
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 25de9d4af1ff..dae405027920 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -40,7 +40,9 @@ public:
SemanticsContext &context() { return context_; }
void Check() { Check(context_.globalScope()); }
void Check(const ParamValue &, bool canBeAssumed);
- void Check(const Bound &bound) { CheckSpecExpr(bound.GetExplicit()); }
+ void Check(const Bound &bound) {
+ CheckSpecExpr(bound.GetExplicit(), /*forElementalFunctionResult=*/false);
+ }
void Check(const ShapeSpec &spec) {
Check(spec.lbound());
Check(spec.ubound());
@@ -53,8 +55,10 @@ public:
const Procedure *Characterize(const Symbol &);
private:
- template <typename A> void CheckSpecExpr(const A &x) {
- evaluate::CheckSpecificationExpr(x, DEREF(scope_), foldingContext_);
+ template <typename A>
+ void CheckSpecExpr(const A &x, bool forElementalFunctionResult) {
+ evaluate::CheckSpecificationExpr(
+ x, DEREF(scope_), foldingContext_, forElementalFunctionResult);
}
void CheckValue(const Symbol &, const DerivedTypeSpec *);
void CheckVolatile(const Symbol &, const DerivedTypeSpec *);
@@ -138,8 +142,8 @@ private:
void CheckGlobalName(const Symbol &);
void CheckProcedureAssemblyName(const Symbol &symbol);
void CheckExplicitSave(const Symbol &);
- parser::Messages WhyNotInteroperableDerivedType(const Symbol &, bool isError);
- parser::Messages WhyNotInteroperableObject(const Symbol &, bool isError);
+ parser::Messages WhyNotInteroperableDerivedType(const Symbol &);
+ parser::Messages WhyNotInteroperableObject(const Symbol &);
parser::Messages WhyNotInteroperableFunctionResult(const Symbol &);
parser::Messages WhyNotInteroperableProcedure(const Symbol &, bool isError);
void CheckBindC(const Symbol &);
@@ -222,7 +226,7 @@ void CheckHelper::Check(const ParamValue &value, bool canBeAssumed) {
"An assumed (*) type parameter may be used only for a (non-statement function) dummy argument, associate name, character named constant, or external function result"_err_en_US);
}
} else {
- CheckSpecExpr(value.GetExplicit());
+ CheckSpecExpr(value.GetExplicit(), /*forElementalFunctionResult=*/false);
}
}
@@ -248,8 +252,7 @@ void CheckHelper::Check(const Symbol &symbol) {
&symbol == &symbol.GetUltimate()) {
if (context_.ShouldWarn(common::LanguageFeature::LongNames)) {
WarnIfNotInModuleFile(symbol.name(),
- "%s has length %d, which is greater than the maximum name length "
- "%d"_port_en_US,
+ "%s has length %d, which is greater than the maximum name length %d"_port_en_US,
symbol.name(), symbol.name().size(), common::maxNameLen);
}
}
@@ -350,7 +353,10 @@ void CheckHelper::Check(const Symbol &symbol) {
messages_.Say(
"A pure subprogram may not have a variable with the VOLATILE attribute"_err_en_US);
}
- if (IsProcedure(symbol) && !IsPureProcedure(symbol) && IsDummy(symbol)) {
+ if (innermostSymbol_ && innermostSymbol_->name() == "__builtin_c_funloc") {
+ // The intrinsic procedure C_FUNLOC() gets a pass on this check.
+ } else if (IsProcedure(symbol) && !IsPureProcedure(symbol) &&
+ IsDummy(symbol)) {
messages_.Say(
"A dummy procedure of a pure subprogram must be pure"_err_en_US);
}
@@ -378,24 +384,31 @@ void CheckHelper::Check(const Symbol &symbol) {
} else {
Check(*type, canHaveAssumedParameter);
}
- if (InPure() && InFunction() && IsFunctionResult(symbol)) {
- if (type->IsPolymorphic() && IsAllocatable(symbol)) { // C1585
- messages_.Say(
- "Result of pure function may not be both polymorphic and ALLOCATABLE"_err_en_US);
- }
- if (derived) {
- // These cases would be caught be the general validation of local
- // variables in a pure context, but these messages are more specific.
- if (HasImpureFinal(symbol)) { // C1584
+ if (InFunction() && IsFunctionResult(symbol)) {
+ if (InPure()) {
+ if (type->IsPolymorphic() && IsAllocatable(symbol)) { // C1585
messages_.Say(
- "Result of pure function may not have an impure FINAL subroutine"_err_en_US);
+ "Result of pure function may not be both polymorphic and ALLOCATABLE"_err_en_US);
}
- if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
- SayWithDeclaration(*bad,
- "Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'"_err_en_US,
- bad.BuildResultDesignatorName());
+ if (derived) {
+ // These cases would be caught be the general validation of local
+ // variables in a pure context, but these messages are more specific.
+ if (HasImpureFinal(symbol)) { // C1584
+ messages_.Say(
+ "Result of pure function may not have an impure FINAL subroutine"_err_en_US);
+ }
+ if (auto bad{FindPolymorphicAllocatableUltimateComponent(*derived)}) {
+ SayWithDeclaration(*bad,
+ "Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'"_err_en_US,
+ bad.BuildResultDesignatorName());
+ }
}
}
+ if (InElemental() && isChar) { // F'2023 C15121
+ CheckSpecExpr(type->characterTypeSpec().length().GetExplicit(),
+ /*forElementalFunctionResult=*/true);
+ // TODO: check PDT LEN parameters
+ }
}
}
if (IsAssumedLengthCharacter(symbol) && IsFunction(symbol)) { // C723
@@ -452,12 +465,12 @@ void CheckHelper::Check(const Symbol &symbol) {
symbol.name());
}
}
- if (IsProcedure(symbol) && !symbol.HasExplicitInterface()) {
+ if (IsProcedure(symbol)) {
if (IsAllocatable(symbol)) {
messages_.Say(
- "Procedure '%s' may not be ALLOCATABLE without an explicit interface"_err_en_US,
- symbol.name());
- } else if (symbol.Rank() > 0) {
+ "Procedure '%s' may not be ALLOCATABLE"_err_en_US, symbol.name());
+ }
+ if (!symbol.HasExplicitInterface() && symbol.Rank() > 0) {
messages_.Say(
"Procedure '%s' may not be an array without an explicit interface"_err_en_US,
symbol.name());
@@ -731,14 +744,13 @@ void CheckHelper::CheckObjectEntity(
}
} else if (!IsIntentInOut(symbol)) { // C1586
messages_.Say(
- "non-POINTER dummy argument of pure %s must have INTENT() or VALUE attribute"_warn_en_US,
+ "non-POINTER dummy argument of pure %s must have INTENT() or VALUE attribute"_err_en_US,
what);
ok = false;
}
- if (ok && InFunction()) {
+ if (ok && InFunction() && !InModuleFile() && !InElemental()) {
if (context_.IsEnabled(common::LanguageFeature::RelaxedPureDummy)) {
- if (context_.ShouldWarn(common::LanguageFeature::RelaxedPureDummy) &&
- !InModuleFile() && !InElemental()) {
+ if (context_.ShouldWarn(common::LanguageFeature::RelaxedPureDummy)) {
messages_.Say(
"non-POINTER dummy argument of pure function should be INTENT(IN) or VALUE"_warn_en_US);
}
@@ -1315,6 +1327,13 @@ private:
bool CheckSameAttrs(const Symbol &, const Symbol &, ATTRS, ATTRS);
bool ShapesAreCompatible(const DummyDataObject &, const DummyDataObject &);
evaluate::Shape FoldShape(const evaluate::Shape &);
+ std::optional<evaluate::Shape> FoldShape(
+ const std::optional<evaluate::Shape> &shape) {
+ if (shape) {
+ return FoldShape(*shape);
+ }
+ return std::nullopt;
+ }
std::string AsFortran(DummyDataObject::Attr attr) {
return parser::ToUpperCaseLetters(DummyDataObject::EnumToString(attr));
}
@@ -1887,11 +1906,34 @@ void CheckHelper::CheckSpecifics(
helper.Check(generic.owner());
}
+static bool CUDAHostDeviceDiffer(
+ const Procedure &proc, const DummyDataObject &arg) {
+ auto procCUDA{
+ proc.cudaSubprogramAttrs.value_or(common::CUDASubprogramAttrs::Host)};
+ bool procIsHostOnly{procCUDA == common::CUDASubprogramAttrs::Host};
+ bool procIsDeviceOnly{
+ !procIsHostOnly && procCUDA != common::CUDASubprogramAttrs::HostDevice};
+ const auto &argCUDA{arg.cudaDataAttr};
+ bool argIsHostOnly{!argCUDA || *argCUDA == common::CUDADataAttr::Pinned};
+ bool argIsDeviceOnly{(!argCUDA && procIsDeviceOnly) ||
+ (argCUDA &&
+ (*argCUDA != common::CUDADataAttr::Managed &&
+ *argCUDA != common::CUDADataAttr::Pinned &&
+ *argCUDA != common::CUDADataAttr::Unified))};
+ return (procIsHostOnly && argIsDeviceOnly) ||
+ (procIsDeviceOnly && argIsHostOnly);
+}
+
static bool ConflictsWithIntrinsicAssignment(const Procedure &proc) {
- auto lhs{std::get<DummyDataObject>(proc.dummyArguments[0].u).type};
- auto rhs{std::get<DummyDataObject>(proc.dummyArguments[1].u).type};
- return Tristate::No ==
- IsDefinedAssignment(lhs.type(), lhs.Rank(), rhs.type(), rhs.Rank());
+ const auto &lhsData{std::get<DummyDataObject>(proc.dummyArguments[0].u)};
+ const auto &lhsTnS{lhsData.type};
+ const auto &rhsData{std::get<DummyDataObject>(proc.dummyArguments[1].u)};
+ const auto &rhsTnS{rhsData.type};
+ return !CUDAHostDeviceDiffer(proc, lhsData) &&
+ !CUDAHostDeviceDiffer(proc, rhsData) &&
+ Tristate::No ==
+ IsDefinedAssignment(
+ lhsTnS.type(), lhsTnS.Rank(), rhsTnS.type(), rhsTnS.Rank());
}
static bool ConflictsWithIntrinsicOperator(
@@ -1899,8 +1941,12 @@ static bool ConflictsWithIntrinsicOperator(
if (!kind.IsIntrinsicOperator()) {
return false;
}
- auto arg0{std::get<DummyDataObject>(proc.dummyArguments[0].u).type};
- auto type0{arg0.type()};
+ const auto &arg0Data{std::get<DummyDataObject>(proc.dummyArguments[0].u)};
+ if (CUDAHostDeviceDiffer(proc, arg0Data)) {
+ return false;
+ }
+ const auto &arg0TnS{arg0Data.type};
+ auto type0{arg0TnS.type()};
if (proc.dummyArguments.size() == 1) { // unary
return common::visit(
common::visitors{
@@ -1910,10 +1956,14 @@ static bool ConflictsWithIntrinsicOperator(
},
kind.u);
} else { // binary
- int rank0{arg0.Rank()};
- auto arg1{std::get<DummyDataObject>(proc.dummyArguments[1].u).type};
- auto type1{arg1.type()};
- int rank1{arg1.Rank()};
+ int rank0{arg0TnS.Rank()};
+ const auto &arg1Data{std::get<DummyDataObject>(proc.dummyArguments[1].u)};
+ if (CUDAHostDeviceDiffer(proc, arg1Data)) {
+ return false;
+ }
+ const auto &arg1TnS{arg1Data.type};
+ auto type1{arg1TnS.type()};
+ int rank1{arg1TnS.Rank()};
return common::visit(
common::visitors{
[&](common::NumericOperator) {
@@ -2087,8 +2137,8 @@ bool CheckHelper::CheckDefinedAssignment(
if (!(ok0 && ok1)) {
return false; // error was reported
} else if (ConflictsWithIntrinsicAssignment(proc)) {
- msg = "Defined assignment subroutine '%s' conflicts with"
- " intrinsic assignment"_err_en_US;
+ msg =
+ "Defined assignment subroutine '%s' conflicts with intrinsic assignment"_err_en_US;
} else {
return true; // OK
}
@@ -2861,13 +2911,12 @@ void CheckHelper::CheckProcedureAssemblyName(const Symbol &symbol) {
}
parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
- const Symbol &symbol, bool isError) {
+ const Symbol &symbol) {
parser::Messages msgs;
if (examinedByWhyNotInteroperable_.find(symbol) !=
examinedByWhyNotInteroperable_.end()) {
return msgs;
}
- isError |= symbol.attrs().test(Attr::BIND_C);
examinedByWhyNotInteroperable_.insert(symbol);
if (const auto *derived{symbol.detailsIf<DerivedTypeDetails>()}) {
if (derived->sequence()) { // C1801
@@ -2878,14 +2927,13 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
"An interoperable derived type cannot have a type parameter"_err_en_US);
} else if (const auto *parent{
symbol.scope()->GetDerivedTypeParent()}) { // C1803
- if (isError) {
+ if (symbol.attrs().test(Attr::BIND_C)) {
msgs.Say(symbol.name(),
"A derived type with the BIND attribute cannot be an extended derived type"_err_en_US);
} else {
bool interoperableParent{true};
if (parent->symbol()) {
- auto bad{WhyNotInteroperableDerivedType(
- *parent->symbol(), /*isError=*/false)};
+ auto bad{WhyNotInteroperableDerivedType(*parent->symbol())};
if (bad.AnyFatalError()) {
auto &msg{msgs.Say(symbol.name(),
"The parent of an interoperable type is not interoperable"_err_en_US)};
@@ -2915,8 +2963,7 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
"An interoperable derived type cannot have a pointer or allocatable component"_err_en_US);
} else if (const auto *type{component.GetType()}) {
if (const auto *derived{type->AsDerived()}) {
- auto bad{
- WhyNotInteroperableDerivedType(derived->typeSymbol(), isError)};
+ auto bad{WhyNotInteroperableDerivedType(derived->typeSymbol())};
if (bad.AnyFatalError()) {
auto &msg{msgs.Say(component.name(),
"Component '%s' of an interoperable derived type must have an interoperable type but does not"_err_en_US,
@@ -2968,28 +3015,19 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
}
}
}
- if (isError) {
- for (auto &m : msgs.messages()) {
- if (!m.IsFatal()) {
- m.set_severity(parser::Severity::Error);
- }
- }
- }
if (msgs.AnyFatalError()) {
examinedByWhyNotInteroperable_.erase(symbol);
}
return msgs;
}
-parser::Messages CheckHelper::WhyNotInteroperableObject(
- const Symbol &symbol, bool isError) {
+parser::Messages CheckHelper::WhyNotInteroperableObject(const Symbol &symbol) {
parser::Messages msgs;
if (examinedByWhyNotInteroperable_.find(symbol) !=
examinedByWhyNotInteroperable_.end()) {
return msgs;
}
bool isExplicitBindC{symbol.attrs().test(Attr::BIND_C)};
- isError |= isExplicitBindC;
examinedByWhyNotInteroperable_.insert(symbol);
CHECK(symbol.has<ObjectEntityDetails>());
if (isExplicitBindC && !symbol.owner().IsModule()) {
@@ -3018,14 +3056,14 @@ parser::Messages CheckHelper::WhyNotInteroperableObject(
}
if (const auto *type{symbol.GetType()}) {
const auto *derived{type->AsDerived()};
- if (derived) {
- if (derived->typeSymbol().attrs().test(Attr::BIND_C)) {
- } else if (isError) {
+ if (derived && !derived->typeSymbol().attrs().test(Attr::BIND_C)) {
+ if (!context_.IsEnabled(
+ common::LanguageFeature::NonBindCInteroperability)) {
msgs.Say(symbol.name(),
- "The derived type of a BIND(C) object must also be BIND(C)"_err_en_US)
+ "The derived type of an interoperable object must be BIND(C)"_err_en_US)
.Attach(derived->typeSymbol().name(), "Non-BIND(C) type"_en_US);
- } else if (auto bad{WhyNotInteroperableDerivedType(
- derived->typeSymbol(), /*isError=*/false)};
+ } else if (auto bad{
+ WhyNotInteroperableDerivedType(derived->typeSymbol())};
bad.AnyFatalError()) {
bad.AttachTo(
msgs.Say(symbol.name(),
@@ -3155,7 +3193,7 @@ parser::Messages CheckHelper::WhyNotInteroperableProcedure(
"A dummy procedure of an interoperable procedure should be BIND(C)"_warn_en_US);
}
} else if (dummy->has<ObjectEntityDetails>()) {
- dummyMsgs = WhyNotInteroperableObject(*dummy, /*isError=*/false);
+ dummyMsgs = WhyNotInteroperableObject(*dummy);
} else {
CheckBindC(*dummy);
}
@@ -3225,13 +3263,12 @@ void CheckHelper::CheckBindC(const Symbol &symbol) {
}
}
if (symbol.has<ObjectEntityDetails>()) {
- whyNot = WhyNotInteroperableObject(symbol, /*isError=*/isExplicitBindC);
+ whyNot = WhyNotInteroperableObject(symbol);
} else if (symbol.has<ProcEntityDetails>() ||
symbol.has<SubprogramDetails>()) {
whyNot = WhyNotInteroperableProcedure(symbol, /*isError=*/isExplicitBindC);
} else if (symbol.has<DerivedTypeDetails>()) {
- whyNot =
- WhyNotInteroperableDerivedType(symbol, /*isError=*/isExplicitBindC);
+ whyNot = WhyNotInteroperableDerivedType(symbol);
}
if (!whyNot.empty()) {
bool anyFatal{whyNot.AnyFatalError()};
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 54ce45157537..e5baddf59940 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2378,6 +2378,87 @@ bool OmpStructureChecker::CheckIntrinsicOperator(
return false;
}
+static bool IsReductionAllowedForType(
+ const parser::OmpClause::Reduction &x, const DeclTypeSpec &type) {
+ const auto &definedOp{std::get<parser::OmpReductionOperator>(x.v.t)};
+ // TODO: user defined reduction operators. Just allow everything for now.
+ bool ok{true};
+
+ auto IsLogical{[](const DeclTypeSpec &type) -> bool {
+ return type.category() == DeclTypeSpec::Logical;
+ }};
+ auto IsCharacter{[](const DeclTypeSpec &type) -> bool {
+ return type.category() == DeclTypeSpec::Character;
+ }};
+
+ common::visit(
+ common::visitors{
+ [&](const parser::DefinedOperator &dOpr) {
+ if (const auto *intrinsicOp{
+ std::get_if<parser::DefinedOperator::IntrinsicOperator>(
+ &dOpr.u)}) {
+ // OMP5.2: The type [...] of a list item that appears in a
+ // reduction clause must be valid for the combiner expression
+ // See F2023: Table 10.2
+ // .LT., .LE., .GT., .GE. are handled as procedure designators
+ // below.
+ switch (*intrinsicOp) {
+ case parser::DefinedOperator::IntrinsicOperator::Multiply:
+ [[fallthrough]];
+ case parser::DefinedOperator::IntrinsicOperator::Add:
+ [[fallthrough]];
+ case parser::DefinedOperator::IntrinsicOperator::Subtract:
+ ok = type.IsNumeric(TypeCategory::Integer) ||
+ type.IsNumeric(TypeCategory::Real) ||
+ type.IsNumeric(TypeCategory::Complex);
+ break;
+
+ case parser::DefinedOperator::IntrinsicOperator::AND:
+ [[fallthrough]];
+ case parser::DefinedOperator::IntrinsicOperator::OR:
+ [[fallthrough]];
+ case parser::DefinedOperator::IntrinsicOperator::EQV:
+ [[fallthrough]];
+ case parser::DefinedOperator::IntrinsicOperator::NEQV:
+ ok = IsLogical(type);
+ break;
+
+ // Reduction identifier is not in OMP5.2 Table 5.2
+ default:
+ DIE("This should have been caught in CheckIntrinsicOperator");
+ ok = false;
+ break;
+ }
+ }
+ },
+ [&](const parser::ProcedureDesignator &procD) {
+ const parser::Name *name{std::get_if<parser::Name>(&procD.u)};
+ if (name && name->symbol) {
+ const SourceName &realName{name->symbol->GetUltimate().name()};
+ // OMP5.2: The type [...] of a list item that appears in a
+ // reduction clause must be valid for the combiner expression
+ if (realName == "iand" || realName == "ior" ||
+ realName == "ieor") {
+ // IAND: arguments must be integers: F2023 16.9.100
+ // IEOR: arguments must be integers: F2023 16.9.106
+ // IOR: arguments must be integers: F2023 16.9.111
+ ok = type.IsNumeric(TypeCategory::Integer);
+ } else if (realName == "max" || realName == "min") {
+ // MAX: arguments must be integer, real, or character:
+ // F2023 16.9.135
+ // MIN: arguments must be integer, real, or character:
+ // F2023 16.9.141
+ ok = type.IsNumeric(TypeCategory::Integer) ||
+ type.IsNumeric(TypeCategory::Real) || IsCharacter(type);
+ }
+ }
+ },
+ },
+ definedOp.u);
+
+ return ok;
+}
+
void OmpStructureChecker::CheckReductionTypeList(
const parser::OmpClause::Reduction &x) {
const auto &ompObjectList{std::get<parser::OmpObjectList>(x.v.t)};
@@ -2397,6 +2478,10 @@ void OmpStructureChecker::CheckReductionTypeList(
context_.Say(source,
"A procedure pointer '%s' must not appear in a REDUCTION clause."_err_en_US,
symbol->name());
+ } else if (!IsReductionAllowedForType(x, DEREF(symbol->GetType()))) {
+ context_.Say(source,
+ "The type of '%s' is incompatible with the reduction operator."_err_en_US,
+ symbol->name());
}
}
}
@@ -2696,7 +2781,7 @@ void OmpStructureChecker::CheckIsLoopIvPartOfClause(
}
}
}
-// Following clauses have a seperate node in parse-tree.h.
+// Following clauses have a separate node in parse-tree.h.
// Atomic-clause
CHECK_SIMPLE_PARSER_CLAUSE(OmpAtomicRead, OMPC_read)
CHECK_SIMPLE_PARSER_CLAUSE(OmpAtomicWrite, OMPC_write)
@@ -2802,18 +2887,18 @@ void OmpStructureChecker::CheckAllowedMapTypes(
const parser::OmpMapType::Type &type,
const std::list<parser::OmpMapType::Type> &allowedMapTypeList) {
if (!llvm::is_contained(allowedMapTypeList, type)) {
- std::string commaSeperatedMapTypes;
+ std::string commaSeparatedMapTypes;
llvm::interleave(
allowedMapTypeList.begin(), allowedMapTypeList.end(),
[&](const parser::OmpMapType::Type &mapType) {
- commaSeperatedMapTypes.append(parser::ToUpperCaseLetters(
+ commaSeparatedMapTypes.append(parser::ToUpperCaseLetters(
parser::OmpMapType::EnumToString(mapType)));
},
- [&] { commaSeperatedMapTypes.append(", "); });
+ [&] { commaSeparatedMapTypes.append(", "); });
context_.Say(GetContext().clauseSource,
"Only the %s map types are permitted "
"for MAP clauses on the %s directive"_err_en_US,
- commaSeperatedMapTypes, ContextDirectiveAsFortran());
+ commaSeparatedMapTypes, ContextDirectiveAsFortran());
}
}
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index ae7e6d4cc360..d80b3b65f0a9 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -153,6 +153,7 @@ public:
bool CheckConformance();
bool CheckAssignmentConformance();
bool CheckForNullPointer(const char *where = "as an operand here");
+ bool CheckForAssumedRank(const char *where = "as an operand here");
// Find and return a user-defined operator or report an error.
// The provided message is used if there is no such operator.
@@ -172,7 +173,8 @@ public:
void Dump(llvm::raw_ostream &);
private:
- MaybeExpr TryDefinedOp(std::vector<const char *>, parser::MessageFixedText);
+ MaybeExpr TryDefinedOp(
+ const std::vector<const char *> &, parser::MessageFixedText);
MaybeExpr TryBoundOp(const Symbol &, int passIndex);
std::optional<ActualArgument> AnalyzeExpr(const parser::Expr &);
std::optional<ActualArgument> AnalyzeVariable(const parser::Variable &);
@@ -3199,6 +3201,7 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) {
if (!procRef) {
analyzer.CheckForNullPointer(
"in a non-pointer intrinsic assignment statement");
+ analyzer.CheckForAssumedRank("in an assignment statement");
const Expr<SomeType> &lhs{analyzer.GetExpr(0)};
if (auto dyType{lhs.GetType()};
dyType && dyType->IsPolymorphic()) { // 10.2.1.2p1(1)
@@ -3393,6 +3396,7 @@ static MaybeExpr NumericUnaryHelper(ExpressionAnalyzer &context,
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicNumeric(opr)) {
analyzer.CheckForNullPointer();
+ analyzer.CheckForAssumedRank();
if (opr == NumericOperator::Add) {
return analyzer.MoveExpr(0);
} else {
@@ -3427,6 +3431,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::NOT &x) {
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicLogical()) {
analyzer.CheckForNullPointer();
+ analyzer.CheckForAssumedRank();
return AsGenericExpr(
LogicalNegation(std::get<Expr<SomeLogical>>(analyzer.MoveExpr(0).u)));
} else {
@@ -3475,6 +3480,7 @@ MaybeExpr NumericBinaryHelper(ExpressionAnalyzer &context, NumericOperator opr,
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicNumeric(opr)) {
analyzer.CheckForNullPointer();
+ analyzer.CheckForAssumedRank();
analyzer.CheckConformance();
return NumericOperation<OPR>(context.GetContextualMessages(),
analyzer.MoveExpr(0), analyzer.MoveExpr(1),
@@ -3524,6 +3530,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Concat &x) {
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicConcat()) {
analyzer.CheckForNullPointer();
+ analyzer.CheckForAssumedRank();
return common::visit(
[&](auto &&x, auto &&y) -> MaybeExpr {
using T = ResultType<decltype(x)>;
@@ -3571,6 +3578,7 @@ MaybeExpr RelationHelper(ExpressionAnalyzer &context, RelationalOperator opr,
if (leftType && rightType &&
analyzer.IsIntrinsicRelational(opr, *leftType, *rightType)) {
analyzer.CheckForNullPointer("as a relational operand");
+ analyzer.CheckForAssumedRank("as a relational operand");
return AsMaybeExpr(Relate(context.GetContextualMessages(), opr,
analyzer.MoveExpr(0), analyzer.MoveExpr(1)));
} else {
@@ -3616,6 +3624,7 @@ MaybeExpr LogicalBinaryHelper(ExpressionAnalyzer &context, LogicalOperator opr,
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicLogical()) {
analyzer.CheckForNullPointer("as a logical operand");
+ analyzer.CheckForAssumedRank("as a logical operand");
return AsGenericExpr(BinaryLogicalOperation(opr,
std::get<Expr<SomeLogical>>(analyzer.MoveExpr(0).u),
std::get<Expr<SomeLogical>>(analyzer.MoveExpr(1).u)));
@@ -4329,6 +4338,18 @@ bool ArgumentAnalyzer::CheckForNullPointer(const char *where) {
return true;
}
+bool ArgumentAnalyzer::CheckForAssumedRank(const char *where) {
+ for (const std::optional<ActualArgument> &arg : actuals_) {
+ if (arg && IsAssumedRank(arg->UnwrapExpr())) {
+ context_.Say(source_,
+ "An assumed-rank dummy argument is not allowed %s"_err_en_US, where);
+ fatalErrors_ = true;
+ return false;
+ }
+ }
+ return true;
+}
+
MaybeExpr ArgumentAnalyzer::TryDefinedOp(
const char *opr, parser::MessageFixedText error, bool isUserOp) {
if (AnyUntypedOrMissingOperand()) {
@@ -4403,14 +4424,14 @@ MaybeExpr ArgumentAnalyzer::TryDefinedOp(
context_.Say(
"Operands of %s are not conformable; have rank %d and rank %d"_err_en_US,
ToUpperCase(opr), actuals_[0]->Rank(), actuals_[1]->Rank());
- } else if (CheckForNullPointer()) {
+ } else if (CheckForNullPointer() && CheckForAssumedRank()) {
context_.Say(error, ToUpperCase(opr), TypeAsFortran(0), TypeAsFortran(1));
}
return result;
}
MaybeExpr ArgumentAnalyzer::TryDefinedOp(
- std::vector<const char *> oprs, parser::MessageFixedText error) {
+ const std::vector<const char *> &oprs, parser::MessageFixedText error) {
if (oprs.size() == 1) {
return TryDefinedOp(oprs[0], error);
}
diff --git a/flang/lib/Semantics/pointer-assignment.cpp b/flang/lib/Semantics/pointer-assignment.cpp
index 077072060e9b..6c634c641319 100644
--- a/flang/lib/Semantics/pointer-assignment.cpp
+++ b/flang/lib/Semantics/pointer-assignment.cpp
@@ -148,6 +148,9 @@ bool PointerAssignmentChecker::CheckLeftHandSide(const SomeExpr &lhs) {
msg->Attach(std::move(*whyNot));
}
return false;
+ } else if (evaluate::IsAssumedRank(lhs)) {
+ Say("The left-hand side of a pointer assignment must not be an assumed-rank dummy argument"_err_en_US);
+ return false;
} else {
return true;
}
@@ -333,8 +336,8 @@ bool PointerAssignmentChecker::Check(const evaluate::Designator<T> &d) {
} else if (!isBoundsRemapping_ &&
!lhsType_->attrs().test(TypeAndShape::Attr::AssumedRank)) {
- int lhsRank{evaluate::GetRank(lhsType_->shape())};
- int rhsRank{evaluate::GetRank(rhsType->shape())};
+ int lhsRank{lhsType_->Rank()};
+ int rhsRank{rhsType->Rank()};
if (lhsRank != rhsRank) {
msg = MessageFormattedText{
"Pointer has rank %d but target has rank %d"_err_en_US, lhsRank,
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index dbc531372c3f..0bf63a00bdf9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1602,6 +1602,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
case llvm::omp::Directive::OMPD_distribute_simd:
case llvm::omp::Directive::OMPD_do:
case llvm::omp::Directive::OMPD_do_simd:
+ case llvm::omp::Directive::OMPD_loop:
case llvm::omp::Directive::OMPD_masked_taskloop_simd:
case llvm::omp::Directive::OMPD_masked_taskloop:
case llvm::omp::Directive::OMPD_parallel_do:
@@ -1609,12 +1610,15 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
case llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd:
case llvm::omp::Directive::OMPD_parallel_masked_taskloop:
case llvm::omp::Directive::OMPD_simd:
+ case llvm::omp::Directive::OMPD_target_loop:
case llvm::omp::Directive::OMPD_target_parallel_do:
case llvm::omp::Directive::OMPD_target_parallel_do_simd:
+ case llvm::omp::Directive::OMPD_target_parallel_loop:
case llvm::omp::Directive::OMPD_target_teams_distribute:
case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
+ case llvm::omp::Directive::OMPD_target_teams_loop:
case llvm::omp::Directive::OMPD_target_simd:
case llvm::omp::Directive::OMPD_taskloop:
case llvm::omp::Directive::OMPD_taskloop_simd:
@@ -1629,6 +1633,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
default:
break;
}
+ if (beginDir.v == llvm::omp::Directive::OMPD_target_loop)
+ if (context_.ShouldWarn(common::UsageWarning::OpenMPUsage)) {
+ context_.Say(beginDir.source,
+ "Usage of directive %s is non-confirming to OpenMP standard"_warn_en_US,
+ llvm::omp::getOpenMPDirectiveName(beginDir.v).str());
+ }
ClearDataSharingAttributeObjects();
SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList));
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 7397c3a51b61..88822974e013 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -315,6 +315,7 @@ private:
bool IsConflictingAttr(Attr);
MaybeExpr bindName_; // from BIND(C, NAME="...")
+ bool isCDefined_{false}; // BIND(C, NAME="...", CDEFINED) extension
std::optional<SourceName> passName_; // from PASS(...)
};
@@ -660,8 +661,8 @@ public:
void MakeExternal(Symbol &);
// C815 duplicated attribute checking; returns false on error
- bool CheckDuplicatedAttr(SourceName, const Symbol &, Attr);
- bool CheckDuplicatedAttrs(SourceName, const Symbol &, Attrs);
+ bool CheckDuplicatedAttr(SourceName, Symbol &, Attr);
+ bool CheckDuplicatedAttrs(SourceName, Symbol &, Attrs);
void SetExplicitAttr(Symbol &symbol, Attr attr) const {
symbol.attrs().set(attr);
@@ -1086,6 +1087,58 @@ protected:
void NoteScalarSpecificationArgument(const Symbol &symbol) {
mustBeScalar_.emplace(symbol);
}
+ // Declare an object or procedure entity.
+ // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
+ template <typename T>
+ Symbol &DeclareEntity(const parser::Name &name, Attrs attrs) {
+ Symbol &symbol{MakeSymbol(name, attrs)};
+ if (context().HasError(symbol) || symbol.has<T>()) {
+ return symbol; // OK or error already reported
+ } else if (symbol.has<UnknownDetails>()) {
+ symbol.set_details(T{});
+ return symbol;
+ } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
+ symbol.set_details(T{std::move(*details)});
+ return symbol;
+ } else if (std::is_same_v<EntityDetails, T> &&
+ (symbol.has<ObjectEntityDetails>() ||
+ symbol.has<ProcEntityDetails>())) {
+ return symbol; // OK
+ } else if (auto *details{symbol.detailsIf<UseDetails>()}) {
+ Say(name.source,
+ "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US,
+ name.source, GetUsedModule(*details).name());
+ } else if (auto *details{symbol.detailsIf<SubprogramNameDetails>()}) {
+ if (details->kind() == SubprogramKind::Module) {
+ Say2(name,
+ "Declaration of '%s' conflicts with its use as module procedure"_err_en_US,
+ symbol, "Module procedure definition"_en_US);
+ } else if (details->kind() == SubprogramKind::Internal) {
+ Say2(name,
+ "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US,
+ symbol, "Internal procedure definition"_en_US);
+ } else {
+ DIE("unexpected kind");
+ }
+ } else if (std::is_same_v<ObjectEntityDetails, T> &&
+ symbol.has<ProcEntityDetails>()) {
+ SayWithDecl(
+ name, symbol, "'%s' is already declared as a procedure"_err_en_US);
+ } else if (std::is_same_v<ProcEntityDetails, T> &&
+ symbol.has<ObjectEntityDetails>()) {
+ if (FindCommonBlockContaining(symbol)) {
+ SayWithDecl(name, symbol,
+ "'%s' may not be a procedure as it is in a COMMON block"_err_en_US);
+ } else {
+ SayWithDecl(
+ name, symbol, "'%s' is already declared as an object"_err_en_US);
+ }
+ } else if (!CheckPossibleBadForwardRef(symbol)) {
+ SayAlreadyDeclared(name, symbol);
+ }
+ context().SetError(symbol);
+ return symbol;
+ }
private:
// The attribute corresponding to the statement containing an ObjectDecl
@@ -1150,59 +1203,6 @@ private:
bool PassesLocalityChecks(
const parser::Name &name, Symbol &symbol, Symbol::Flag flag);
bool CheckForHostAssociatedImplicit(const parser::Name &);
-
- // Declare an object or procedure entity.
- // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
- template <typename T>
- Symbol &DeclareEntity(const parser::Name &name, Attrs attrs) {
- Symbol &symbol{MakeSymbol(name, attrs)};
- if (context().HasError(symbol) || symbol.has<T>()) {
- return symbol; // OK or error already reported
- } else if (symbol.has<UnknownDetails>()) {
- symbol.set_details(T{});
- return symbol;
- } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
- symbol.set_details(T{std::move(*details)});
- return symbol;
- } else if (std::is_same_v<EntityDetails, T> &&
- (symbol.has<ObjectEntityDetails>() ||
- symbol.has<ProcEntityDetails>())) {
- return symbol; // OK
- } else if (auto *details{symbol.detailsIf<UseDetails>()}) {
- Say(name.source,
- "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US,
- name.source, GetUsedModule(*details).name());
- } else if (auto *details{symbol.detailsIf<SubprogramNameDetails>()}) {
- if (details->kind() == SubprogramKind::Module) {
- Say2(name,
- "Declaration of '%s' conflicts with its use as module procedure"_err_en_US,
- symbol, "Module procedure definition"_en_US);
- } else if (details->kind() == SubprogramKind::Internal) {
- Say2(name,
- "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US,
- symbol, "Internal procedure definition"_en_US);
- } else {
- DIE("unexpected kind");
- }
- } else if (std::is_same_v<ObjectEntityDetails, T> &&
- symbol.has<ProcEntityDetails>()) {
- SayWithDecl(
- name, symbol, "'%s' is already declared as a procedure"_err_en_US);
- } else if (std::is_same_v<ProcEntityDetails, T> &&
- symbol.has<ObjectEntityDetails>()) {
- if (FindCommonBlockContaining(symbol)) {
- SayWithDecl(name, symbol,
- "'%s' may not be a procedure as it is in a COMMON block"_err_en_US);
- } else {
- SayWithDecl(
- name, symbol, "'%s' is already declared as an object"_err_en_US);
- }
- } else if (!CheckPossibleBadForwardRef(symbol)) {
- SayAlreadyDeclared(name, symbol);
- }
- context().SetError(symbol);
- return symbol;
- }
bool HasCycle(const Symbol &, const Symbol *interface);
bool MustBeScalar(const Symbol &symbol) const {
return mustBeScalar_.find(symbol) != mustBeScalar_.end();
@@ -1623,6 +1623,7 @@ private:
void PreSpecificationConstruct(const parser::SpecificationConstruct &);
void CreateCommonBlockSymbols(const parser::CommonStmt &);
+ void CreateObjectSymbols(const std::list<parser::ObjectDecl> &, Attr);
void CreateGeneric(const parser::GenericSpec &);
void FinishSpecificationPart(const std::list<parser::DeclarationConstruct> &);
void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt &);
@@ -1762,6 +1763,7 @@ Attrs AttrsVisitor::EndAttrs() {
cudaDataAttr_.reset();
passName_ = std::nullopt;
bindName_.reset();
+ isCDefined_ = false;
return result;
}
@@ -1783,6 +1785,7 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) {
!symbol.attrs().test(Attr::BIND_C)) {
return;
}
+ symbol.SetIsCDefined(isCDefined_);
std::optional<std::string> label{
evaluate::GetScalarConstantValue<evaluate::Ascii>(bindName_)};
// 18.9.2(2): discard leading and trailing blanks
@@ -1820,9 +1823,12 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) {
void AttrsVisitor::Post(const parser::LanguageBindingSpec &x) {
if (CheckAndSet(Attr::BIND_C)) {
- if (x.v) {
- bindName_ = EvaluateExpr(*x.v);
+ if (const auto &name{
+ std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
+ x.t)}) {
+ bindName_ = EvaluateExpr(*name);
}
+ isCDefined_ = std::get<bool>(x.t);
}
}
bool AttrsVisitor::Pre(const parser::IntentSpec &x) {
@@ -2800,12 +2806,13 @@ void ScopeHandler::MakeExternal(Symbol &symbol) {
}
bool ScopeHandler::CheckDuplicatedAttr(
- SourceName name, const Symbol &symbol, Attr attr) {
+ SourceName name, Symbol &symbol, Attr attr) {
if (attr == Attr::SAVE) {
// checked elsewhere
} else if (symbol.attrs().test(attr)) { // C815
if (symbol.implicitAttrs().test(attr)) {
// Implied attribute is now confirmed explicitly
+ symbol.implicitAttrs().reset(attr);
} else {
Say(name, "%s attribute was already specified on '%s'"_err_en_US,
EnumToString(attr), name);
@@ -2816,7 +2823,7 @@ bool ScopeHandler::CheckDuplicatedAttr(
}
bool ScopeHandler::CheckDuplicatedAttrs(
- SourceName name, const Symbol &symbol, Attrs attrs) {
+ SourceName name, Symbol &symbol, Attrs attrs) {
bool ok{true};
attrs.IterateOverMembers(
[&](Attr x) { ok &= CheckDuplicatedAttr(name, symbol, x); });
@@ -4056,7 +4063,9 @@ void SubprogramVisitor::CreateEntry(
Attrs attrs;
const auto &suffix{std::get<std::optional<parser::Suffix>>(stmt.t)};
bool hasGlobalBindingName{outer.IsGlobal() && suffix && suffix->binding &&
- suffix->binding->v.has_value()};
+ std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
+ suffix->binding->t)
+ .has_value()};
if (!hasGlobalBindingName) {
if (Symbol * extant{FindSymbol(outer, entryName)}) {
if (!HandlePreviousCalls(entryName, *extant, subpFlag)) {
@@ -4440,7 +4449,10 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
bool hasModulePrefix) {
Symbol *symbol{GetSpecificFromGeneric(name)};
if (!symbol) {
- if (bindingSpec && currScope().IsGlobal() && bindingSpec->v) {
+ if (bindingSpec && currScope().IsGlobal() &&
+ std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
+ bindingSpec->t)
+ .has_value()) {
// Create this new top-level subprogram with a binding label
// in a new global scope, so that its symbol's name won't clash
// with another symbol that has a distinct binding label.
@@ -5021,6 +5033,10 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity(
charInfo_.length.reset();
if (symbol.attrs().test(Attr::EXTERNAL)) {
ConvertToProcEntity(symbol);
+ } else if (symbol.attrs().HasAny(Attrs{Attr::ALLOCATABLE,
+ Attr::ASYNCHRONOUS, Attr::CONTIGUOUS, Attr::PARAMETER,
+ Attr::SAVE, Attr::TARGET, Attr::VALUE, Attr::VOLATILE})) {
+ ConvertToObjectEntity(symbol);
}
if (attrs.test(Attr::BIND_C)) {
SetBindNameOn(symbol);
@@ -5670,7 +5686,9 @@ bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt &x) {
const auto &procAttrSpec{std::get<std::list<parser::ProcAttrSpec>>(x.t)};
for (const parser::ProcAttrSpec &procAttr : procAttrSpec) {
if (auto *bindC{std::get_if<parser::LanguageBindingSpec>(&procAttr.u)}) {
- if (bindC->v.has_value()) {
+ if (std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
+ bindC->t)
+ .has_value()) {
if (std::get<std::list<parser::ProcDecl>>(x.t).size() > 1) {
Say(context().location().value(),
"A procedure declaration statement with a binding name may not declare multiple procedures"_err_en_US);
@@ -8538,11 +8556,19 @@ void ResolveNamesVisitor::PreSpecificationConstruct(
}
},
[&](const parser::Statement<parser::OtherSpecificationStmt> &y) {
- if (const auto *commonStmt{parser::Unwrap<parser::CommonStmt>(y)}) {
- CreateCommonBlockSymbols(*commonStmt);
- }
+ common::visit(
+ common::visitors{
+ [&](const common::Indirection<parser::CommonStmt> &z) {
+ CreateCommonBlockSymbols(z.value());
+ },
+ [&](const common::Indirection<parser::TargetStmt> &z) {
+ CreateObjectSymbols(z.value().v, Attr::TARGET);
+ },
+ [](const auto &) {},
+ },
+ y.statement.u);
},
- [&](const auto &) {},
+ [](const auto &) {},
},
spec.u);
}
@@ -8562,6 +8588,15 @@ void ResolveNamesVisitor::CreateCommonBlockSymbols(
}
}
+void ResolveNamesVisitor::CreateObjectSymbols(
+ const std::list<parser::ObjectDecl> &decls, Attr attr) {
+ for (const parser::ObjectDecl &decl : decls) {
+ SetImplicitAttr(DeclareEntity<ObjectEntityDetails>(
+ std::get<parser::ObjectName>(decl.t), Attrs{}),
+ attr);
+ }
+}
+
void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
auto info{GenericSpecInfo{x}};
SourceName symbolName{info.symbolName()};
@@ -8886,6 +8921,9 @@ void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) {
}
void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
+ if (std::holds_alternative<parser::CompilerDirective::VectorAlways>(x.u)) {
+ return;
+ }
if (const auto *tkr{
std::get_if<std::list<parser::CompilerDirective::IgnoreTKR>>(&x.u)}) {
if (currScope().IsTopLevel() ||
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index 15ea34c66dba..8939dc4499ec 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -748,7 +748,7 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
symbol, foldingContext)};
CHECK(typeAndShape.has_value());
auto dyType{typeAndShape->type()};
- const auto &shape{typeAndShape->shape()};
+ int rank{typeAndShape->Rank()};
AddValue(values, componentSchema_, "name"s,
SaveNameAsPointerTarget(scope, symbol.name().ToString()));
AddValue(values, componentSchema_, "category"s,
@@ -830,7 +830,6 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
SomeExpr{evaluate::NullPointer{}});
}
// Shape information
- int rank{evaluate::GetRank(shape)};
AddValue(values, componentSchema_, "rank"s, IntExpr<1>(rank));
if (rank > 0 && !IsAllocatable(symbol) && !IsPointer(symbol)) {
std::vector<evaluate::StructureConstructor> bounds;
@@ -1143,7 +1142,7 @@ void RuntimeTableBuilder::DescribeSpecialProc(
isArgDescriptorSet |= 1;
} else {
which = scalarFinalEnum_;
- if (int rank{evaluate::GetRank(typeAndShape.shape())}; rank > 0) {
+ if (int rank{typeAndShape.Rank()}; rank > 0) {
which = IntExpr<1>(ToInt64(which).value() + rank);
if (dummyData.IsPassedByDescriptor(proc->IsBindC())) {
argThatMightBeDescriptor = 1;
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index a860040f7378..89128e4a5049 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -56,7 +56,7 @@ Scope &Scope::MakeScope(Kind kind, Symbol *symbol) {
template <typename T>
static std::vector<common::Reference<T>> GetSortedSymbols(
- std::map<SourceName, MutableSymbolRef> symbols) {
+ const std::map<SourceName, MutableSymbolRef> &symbols) {
std::vector<common::Reference<T>> result;
result.reserve(symbols.size());
for (auto &pair : symbols) {
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index d51cc62d804e..1bb0679b7511 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -9,6 +9,7 @@
#include "flang/Semantics/semantics.h"
#include "assignment.h"
#include "canonicalize-acc.h"
+#include "canonicalize-directives.h"
#include "canonicalize-do.h"
#include "canonicalize-omp.h"
#include "check-acc-structure.h"
@@ -599,6 +600,7 @@ bool Semantics::Perform() {
CanonicalizeAcc(context_.messages(), program_) &&
CanonicalizeOmp(context_.messages(), program_) &&
CanonicalizeCUDA(program_) &&
+ CanonicalizeDirectives(context_.messages(), program_) &&
PerformStatementSemantics(context_, program_) &&
ModFileWriter{context_}.WriteAll();
}
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 3eb120fd962f..023ab7b64e4f 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -375,6 +375,18 @@ void Symbol::SetIsExplicitBindName(bool yes) {
details_);
}
+void Symbol::SetIsCDefined(bool yes) {
+ common::visit(
+ [&](auto &x) {
+ if constexpr (HasBindName<decltype(&x)>) {
+ x.set_isCDefined(yes);
+ } else {
+ DIE("CDEFINED not allowed on this kind of symbol");
+ }
+ },
+ details_);
+}
+
bool Symbol::IsFuncResult() const {
return common::visit(
common::visitors{[](const EntityDetails &x) { return x.isFuncResult(); },
@@ -422,6 +434,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const EntityDetails &x) {
os << " type: " << *x.type();
}
DumpOptional(os, "bindName", x.bindName());
+ DumpBool(os, "CDEFINED", x.isCDefined());
return os;
}
diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90
index 4746ca20a13a..44b0f17339cd 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang/module/__fortran_builtins.f90
@@ -6,6 +6,8 @@
!
!===------------------------------------------------------------------------===!
+include '../include/flang/Runtime/magic-numbers.h'
+
! These naming shenanigans prevent names from Fortran intrinsic modules
! from being usable on INTRINSIC statements, and force the program
! to USE the standard intrinsic modules in order to access the
@@ -49,6 +51,42 @@ module __fortran_builtins
integer(kind=int64), private :: __count
end type
+ type, public :: __builtin_ieee_flag_type
+ integer(kind=1), private :: flag = 0
+ end type
+
+ type(__builtin_ieee_flag_type), parameter, public :: &
+ __builtin_ieee_invalid = &
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INVALID), &
+ __builtin_ieee_overflow = &
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_OVERFLOW), &
+ __builtin_ieee_divide_by_zero = &
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO), &
+ __builtin_ieee_underflow = &
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_UNDERFLOW), &
+ __builtin_ieee_inexact = &
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INEXACT), &
+ __builtin_ieee_denorm = & ! extension
+ __builtin_ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DENORM)
+
+ type, public :: __builtin_ieee_round_type
+ integer(kind=1), private :: mode = 0
+ end type
+
+ type(__builtin_ieee_round_type), parameter, public :: &
+ __builtin_ieee_to_zero = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_TO_ZERO), &
+ __builtin_ieee_nearest = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_NEAREST), &
+ __builtin_ieee_up = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_UP), &
+ __builtin_ieee_down = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_DOWN), &
+ __builtin_ieee_away = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_AWAY), &
+ __builtin_ieee_other = &
+ __builtin_ieee_round_type(_FORTRAN_RUNTIME_IEEE_OTHER)
+
type, public :: __builtin_team_type
integer(kind=int64), private :: __id
end type
@@ -74,8 +112,10 @@ module __fortran_builtins
intrinsic :: __builtin_ieee_selected_real_kind
intrinsic :: __builtin_ieee_support_datatype, &
__builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
+ __builtin_ieee_support_flag, __builtin_ieee_support_halting, &
__builtin_ieee_support_inf, __builtin_ieee_support_io, &
- __builtin_ieee_support_nan, __builtin_ieee_support_sqrt, &
+ __builtin_ieee_support_nan, __builtin_ieee_support_rounding, &
+ __builtin_ieee_support_sqrt, &
__builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
__builtin_ieee_support_underflow_control
public :: __builtin_fma
@@ -87,8 +127,10 @@ module __fortran_builtins
public :: __builtin_ieee_selected_real_kind
public :: __builtin_ieee_support_datatype, &
__builtin_ieee_support_denormal, __builtin_ieee_support_divide, &
+ __builtin_ieee_support_flag, __builtin_ieee_support_halting, &
__builtin_ieee_support_inf, __builtin_ieee_support_io, &
- __builtin_ieee_support_nan, __builtin_ieee_support_sqrt, &
+ __builtin_ieee_support_nan, __builtin_ieee_support_rounding, &
+ __builtin_ieee_support_sqrt, &
__builtin_ieee_support_standard, __builtin_ieee_support_subnormal, &
__builtin_ieee_support_underflow_control
@@ -140,7 +182,10 @@ module __fortran_builtins
__builtin_c_ptr_ne = x%__address /= y%__address
end function
- function __builtin_c_funloc(x)
+ ! Semantics has some special-case code that allows c_funloc()
+ ! to appear in a specification expression and exempts it
+ ! from the requirement that "x" be a pure dummy procedure.
+ pure function __builtin_c_funloc(x)
type(__builtin_c_funptr) :: __builtin_c_funloc
external :: x
__builtin_c_funloc = __builtin_c_funptr(loc(x))
diff --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang/module/__fortran_ieee_exceptions.f90
index afcd18355319..810a2b0e400f 100644
--- a/flang/module/__fortran_ieee_exceptions.f90
+++ b/flang/module/__fortran_ieee_exceptions.f90
@@ -14,25 +14,22 @@
include '../include/flang/Runtime/magic-numbers.h'
module __fortran_ieee_exceptions
+ use __fortran_builtins, only: &
+ ieee_flag_type => __builtin_ieee_flag_type, &
+ ieee_support_flag => __builtin_ieee_support_flag, &
+ ieee_support_halting => __builtin_ieee_support_halting, &
+ ieee_invalid => __builtin_ieee_invalid, &
+ ieee_overflow => __builtin_ieee_overflow, &
+ ieee_divide_by_zero => __builtin_ieee_divide_by_zero, &
+ ieee_underflow => __builtin_ieee_underflow, &
+ ieee_inexact => __builtin_ieee_inexact, &
+ ieee_denorm => __builtin_ieee_denorm
implicit none
-
- ! Set PRIVATE by default to explicitly only export what is meant
- ! to be exported by this MODULE.
private
- type, public :: ieee_flag_type ! Fortran 2018, 17.2 & 17.3
- private
- integer(kind=1) :: flag = 0
- end type ieee_flag_type
-
- type(ieee_flag_type), parameter, public :: &
- ieee_invalid = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INVALID), &
- ieee_overflow = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_OVERFLOW), &
- ieee_divide_by_zero = &
- ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO), &
- ieee_underflow = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_UNDERFLOW), &
- ieee_inexact = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_INEXACT), &
- ieee_denorm = ieee_flag_type(_FORTRAN_RUNTIME_IEEE_DENORM) ! extension
+ public :: ieee_flag_type, ieee_support_flag, ieee_support_halting
+ public :: ieee_invalid, ieee_overflow, ieee_divide_by_zero, ieee_underflow, &
+ ieee_inexact, ieee_denorm
type(ieee_flag_type), parameter, public :: &
ieee_usual(*) = [ ieee_overflow, ieee_divide_by_zero, ieee_invalid ], &
@@ -139,28 +136,4 @@ module __fortran_ieee_exceptions
end interface
public :: ieee_set_status
-#define IEEE_SUPPORT_FLAG_R(XKIND) \
- pure logical function ieee_support_flag_a##XKIND(flag, x); \
- import ieee_flag_type; \
- type(ieee_flag_type), intent(in) :: flag; \
- real(XKIND), intent(in) :: x(..); \
- end function ieee_support_flag_a##XKIND;
- interface ieee_support_flag
- pure logical function ieee_support_flag_0(flag)
- import ieee_flag_type
- type(ieee_flag_type), intent(in) :: flag
- end function ieee_support_flag_0
- SPECIFICS_R(IEEE_SUPPORT_FLAG_R)
- end interface ieee_support_flag
- public :: ieee_support_flag
-#undef IEEE_SUPPORT_FLAG_R
-
- interface ieee_support_halting
- pure logical function ieee_support_halting_0(flag)
- import ieee_flag_type
- type(ieee_flag_type), intent(in) :: flag
- end function ieee_support_halting_0
- end interface
- public :: ieee_support_halting
-
end module __fortran_ieee_exceptions
diff --git a/flang/module/ieee_arithmetic.f90 b/flang/module/ieee_arithmetic.f90
index 1da5610f13df..7c7721d78c1e 100644
--- a/flang/module/ieee_arithmetic.f90
+++ b/flang/module/ieee_arithmetic.f90
@@ -18,13 +18,18 @@ module ieee_arithmetic
use __fortran_ieee_exceptions
use __fortran_builtins, only: &
+ ieee_away => __builtin_ieee_away, &
+ ieee_down => __builtin_ieee_down, &
ieee_fma => __builtin_fma, &
ieee_is_nan => __builtin_ieee_is_nan, &
ieee_is_negative => __builtin_ieee_is_negative, &
ieee_is_normal => __builtin_ieee_is_normal, &
+ ieee_nearest => __builtin_ieee_nearest, &
ieee_next_after => __builtin_ieee_next_after, &
ieee_next_down => __builtin_ieee_next_down, &
ieee_next_up => __builtin_ieee_next_up, &
+ ieee_other => __builtin_ieee_other, &
+ ieee_round_type => __builtin_ieee_round_type, &
ieee_scalb => scale, &
ieee_selected_real_kind => __builtin_ieee_selected_real_kind, &
ieee_support_datatype => __builtin_ieee_support_datatype, &
@@ -33,10 +38,14 @@ module ieee_arithmetic
ieee_support_inf => __builtin_ieee_support_inf, &
ieee_support_io => __builtin_ieee_support_io, &
ieee_support_nan => __builtin_ieee_support_nan, &
+ ieee_support_rounding => __builtin_ieee_support_rounding, &
ieee_support_sqrt => __builtin_ieee_support_sqrt, &
ieee_support_standard => __builtin_ieee_support_standard, &
ieee_support_subnormal => __builtin_ieee_support_subnormal, &
- ieee_support_underflow_control => __builtin_ieee_support_underflow_control
+ ieee_support_underflow_control => __builtin_ieee_support_underflow_control, &
+ ieee_to_zero => __builtin_ieee_to_zero, &
+ ieee_up => __builtin_ieee_up
+
implicit none
@@ -45,13 +54,18 @@ module ieee_arithmetic
private
! Explicitly export the symbols from __fortran_builtins
+ public :: ieee_away
+ public :: ieee_down
public :: ieee_fma
public :: ieee_is_nan
public :: ieee_is_negative
public :: ieee_is_normal
+ public :: ieee_nearest
+ public :: ieee_other
public :: ieee_next_after
public :: ieee_next_down
public :: ieee_next_up
+ public :: ieee_round_type
public :: ieee_scalb
public :: ieee_selected_real_kind
public :: ieee_support_datatype
@@ -60,10 +74,13 @@ module ieee_arithmetic
public :: ieee_support_inf
public :: ieee_support_io
public :: ieee_support_nan
+ public :: ieee_support_rounding
public :: ieee_support_sqrt
public :: ieee_support_standard
public :: ieee_support_subnormal
public :: ieee_support_underflow_control
+ public :: ieee_to_zero
+ public :: ieee_up
! Explicitly export the symbols from __fortran_ieee_exceptions
public :: ieee_flag_type
@@ -114,19 +131,6 @@ module ieee_arithmetic
ieee_negative_denormal = ieee_negative_subnormal, &
ieee_positive_denormal = ieee_positive_subnormal
- type, public :: ieee_round_type
- private
- integer(kind=1) :: mode = 0
- end type ieee_round_type
-
- type(ieee_round_type), parameter, public :: &
- ieee_to_zero = ieee_round_type(_FORTRAN_RUNTIME_IEEE_TO_ZERO), &
- ieee_nearest = ieee_round_type(_FORTRAN_RUNTIME_IEEE_NEAREST), &
- ieee_up = ieee_round_type(_FORTRAN_RUNTIME_IEEE_UP), &
- ieee_down = ieee_round_type(_FORTRAN_RUNTIME_IEEE_DOWN), &
- ieee_away = ieee_round_type(_FORTRAN_RUNTIME_IEEE_AWAY), &
- ieee_other = ieee_round_type(_FORTRAN_RUNTIME_IEEE_OTHER)
-
interface operator(==)
elemental logical function ieee_class_eq(x, y)
import ieee_class_type
@@ -586,22 +590,6 @@ module ieee_arithmetic
public :: ieee_signbit
#undef IEEE_SIGNBIT_R
-#define IEEE_SUPPORT_ROUNDING_R(XKIND) \
- pure logical function ieee_support_rounding_a##XKIND(round_value, x); \
- import ieee_round_type; \
- type(ieee_round_type), intent(in) :: round_value; \
- real(XKIND), intent(in) :: x(..); \
- end function ieee_support_rounding_a##XKIND;
- interface ieee_support_rounding
- pure logical function ieee_support_rounding_0(round_value)
- import ieee_round_type
- type(ieee_round_type), intent(in) :: round_value
- end function ieee_support_rounding_0
- SPECIFICS_R(IEEE_SUPPORT_ROUNDING_R)
- end interface ieee_support_rounding
- public :: ieee_support_rounding
-#undef IEEE_SUPPORT_ROUNDING_R
-
#define IEEE_UNORDERED_RR(XKIND, YKIND) \
elemental logical function ieee_unordered_a##XKIND##_a##YKIND(x, y); \
real(XKIND), intent(in) :: x; \
diff --git a/flang/runtime/ISO_Fortran_binding.cpp b/flang/runtime/ISO_Fortran_binding.cpp
index 99ba3aa56fee..fe22026f31f5 100644
--- a/flang/runtime/ISO_Fortran_binding.cpp
+++ b/flang/runtime/ISO_Fortran_binding.cpp
@@ -13,6 +13,7 @@
#include "terminator.h"
#include "flang/ISO_Fortran_binding_wrapper.h"
#include "flang/Runtime/descriptor.h"
+#include "flang/Runtime/pointer.h"
#include "flang/Runtime/type-code.h"
#include <cstdlib>
@@ -75,7 +76,7 @@ RT_API_ATTRS int CFI_allocate(CFI_cdesc_t *descriptor,
dim->sm = byteSize;
byteSize *= extent;
}
- void *p{byteSize ? std::malloc(byteSize) : std::malloc(1)};
+ void *p{runtime::AllocateValidatedPointerPayload(byteSize)};
if (!p && byteSize) {
return CFI_ERROR_MEM_ALLOCATION;
}
@@ -91,8 +92,11 @@ RT_API_ATTRS int CFI_deallocate(CFI_cdesc_t *descriptor) {
if (descriptor->version != CFI_VERSION) {
return CFI_INVALID_DESCRIPTOR;
}
- if (descriptor->attribute != CFI_attribute_allocatable &&
- descriptor->attribute != CFI_attribute_pointer) {
+ if (descriptor->attribute == CFI_attribute_pointer) {
+ if (!runtime::ValidatePointerPayload(*descriptor)) {
+ return CFI_INVALID_DESCRIPTOR;
+ }
+ } else if (descriptor->attribute != CFI_attribute_allocatable) {
// Non-interoperable object
return CFI_INVALID_DESCRIPTOR;
}
diff --git a/flang/runtime/assign.cpp b/flang/runtime/assign.cpp
index 25d2ba4501c1..c3c9b0ba10ab 100644
--- a/flang/runtime/assign.cpp
+++ b/flang/runtime/assign.cpp
@@ -594,26 +594,24 @@ void RTDEF(AssignTemporary)(Descriptor &to, const Descriptor &from,
Assign(to, from, terminator, PolymorphicLHS);
}
-void RTDEF(CopyOutAssign)(Descriptor &to, const Descriptor &from,
- bool skipToInit, const char *sourceFile, int sourceLine) {
+void RTDEF(CopyInAssign)(Descriptor &temp, const Descriptor &var,
+ const char *sourceFile, int sourceLine) {
+ Terminator terminator{sourceFile, sourceLine};
+ temp = var;
+ temp.set_base_addr(nullptr);
+ temp.raw().attribute = CFI_attribute_allocatable;
+ RTNAME(AssignTemporary)(temp, var, sourceFile, sourceLine);
+}
+
+void RTDEF(CopyOutAssign)(
+ Descriptor *var, Descriptor &temp, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
- // Initialize the "to" if it is of derived type that needs initialization.
- if (!skipToInit) {
- if (const DescriptorAddendum * addendum{to.Addendum()}) {
- if (const auto *derived{addendum->derivedType()}) {
- if (!derived->noInitializationNeeded()) {
- if (ReturnError(terminator, Initialize(to, *derived, terminator)) !=
- StatOk) {
- return;
- }
- }
- }
- }
- }
// Copyout from the temporary must not cause any finalizations
- // for LHS.
- Assign(to, from, terminator, NoAssignFlags);
+ // for LHS. The variable must be properly initialized already.
+ if (var)
+ Assign(*var, temp, terminator, NoAssignFlags);
+ temp.Destroy(/*finalize=*/false, /*destroyPointers=*/false, &terminator);
}
void RTDEF(AssignExplicitLengthCharacter)(Descriptor &to,
diff --git a/flang/runtime/complex-reduction.c b/flang/runtime/complex-reduction.c
index 7654de8080a1..37ce3fa41001 100644
--- a/flang/runtime/complex-reduction.c
+++ b/flang/runtime/complex-reduction.c
@@ -157,23 +157,39 @@ ADAPT_REDUCTION(DotProductComplex16, CFloat128ComplexType, CppComplexFloat128,
#endif
/* REDUCE() */
-#define RARGS REDUCE_ARGS(float_Complex_t)
-ADAPT_REDUCTION(ReduceComplex4, float_Complex_t, CppComplexFloat, CMPLXF, RARGS,
- REDUCE_ARG_NAMES)
+#define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op)
+ADAPT_REDUCTION(ReduceComplex4Ref, float_Complex_t, CppComplexFloat, CMPLXF,
+ RARGS, REDUCE_ARG_NAMES)
+#undef RARGS
+#define RARGS REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op)
+ADAPT_REDUCTION(ReduceComplex4Value, float_Complex_t, CppComplexFloat, CMPLXF,
+ RARGS, REDUCE_ARG_NAMES)
+#undef RARGS
+#define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_ref_op)
+ADAPT_REDUCTION(ReduceComplex8Ref, double_Complex_t, CppComplexDouble, CMPLX,
+ RARGS, REDUCE_ARG_NAMES)
#undef RARGS
-#define RARGS REDUCE_ARGS(double_Complex_t)
-ADAPT_REDUCTION(ReduceComplex8, double_Complex_t, CppComplexDouble, CMPLX,
+#define RARGS REDUCE_ARGS(double_Complex_t, double_Complex_t_value_op)
+ADAPT_REDUCTION(ReduceComplex8Value, double_Complex_t, CppComplexDouble, CMPLX,
RARGS, REDUCE_ARG_NAMES)
#undef RARGS
#if LDBL_MANT_DIG == 64
-#define RARGS REDUCE_ARGS(long_double_Complex_t)
-ADAPT_REDUCTION(ReduceComplex10, long_double_Complex_t, CppComplexLongDouble,
+#define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_ref_op)
+ADAPT_REDUCTION(ReduceComplex10Ref, long_double_Complex_t, CppComplexLongDouble,
CMPLXL, RARGS, REDUCE_ARG_NAMES)
#undef RARGS
+#define RARGS REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_value_op)
+ADAPT_REDUCTION(ReduceComplex10Value, long_double_Complex_t,
+ CppComplexLongDouble, CMPLXL, RARGS, REDUCE_ARG_NAMES)
+#undef RARGS
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-#define RARGS REDUCE_ARGS(CFloat128ComplexType)
-ADAPT_REDUCTION(ReduceComplex16, CFloat128ComplexType, CppComplexFloat128,
+#define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_ref_op)
+ADAPT_REDUCTION(ReduceComplex16Ref, CFloat128ComplexType, CppComplexFloat128,
+ CMPLXF128, RARGS, REDUCE_ARG_NAMES)
+#undef RARGS
+#define RARGS REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op)
+ADAPT_REDUCTION(ReduceComplex16Value, CFloat128ComplexType, CppComplexFloat128,
CMPLXF128, RARGS, REDUCE_ARG_NAMES)
#undef RARGS
#endif
diff --git a/flang/runtime/complex-reduction.h b/flang/runtime/complex-reduction.h
index 98b20d1e592b..b0f19622fdb1 100644
--- a/flang/runtime/complex-reduction.h
+++ b/flang/runtime/complex-reduction.h
@@ -69,49 +69,91 @@ long_double_Complex_t RTNAME(DotProductComplex10)(DOT_PRODUCT_ARGS);
CFloat128ComplexType RTNAME(DotProductComplex16)(DOT_PRODUCT_ARGS);
#endif
-#define REDUCE_ARGS(T) \
- T##_op operation, const struct CppDescriptor *x, \
- const struct CppDescriptor *y, const char *source, int line, \
- int dim /*=0*/, const struct CppDescriptor *mask /*=NULL*/, \
- const T *identity /*=NULL*/, _Bool ordered /*=true*/
+#define REDUCE_ARGS(T, OP) \
+ OP operation, const struct CppDescriptor *x, const struct CppDescriptor *y, \
+ const char *source, int line, int dim /*=0*/, \
+ const struct CppDescriptor *mask /*=NULL*/, const T *identity /*=NULL*/, \
+ _Bool ordered /*=true*/
#define REDUCE_ARG_NAMES \
operation, x, y, source, line, dim, mask, identity, ordered
-typedef float_Complex_t (*float_Complex_t_op)(
+typedef float_Complex_t (*float_Complex_t_ref_op)(
const float_Complex_t *, const float_Complex_t *);
-typedef double_Complex_t (*double_Complex_t_op)(
+typedef float_Complex_t (*float_Complex_t_value_op)(
+ float_Complex_t, float_Complex_t);
+typedef double_Complex_t (*double_Complex_t_ref_op)(
const double_Complex_t *, const double_Complex_t *);
-typedef long_double_Complex_t (*long_double_Complex_t_op)(
+typedef double_Complex_t (*double_Complex_t_value_op)(
+ double_Complex_t, double_Complex_t);
+typedef long_double_Complex_t (*long_double_Complex_t_ref_op)(
const long_double_Complex_t *, const long_double_Complex_t *);
-
-float_Complex_t RTNAME(ReduceComplex2)(REDUCE_ARGS(float_Complex_t));
-float_Complex_t RTNAME(ReduceComplex3)(REDUCE_ARGS(float_Complex_t));
-float_Complex_t RTNAME(ReduceComplex4)(REDUCE_ARGS(float_Complex_t));
-double_Complex_t RTNAME(ReduceComplex8)(REDUCE_ARGS(double_Complex_t));
-long_double_Complex_t RTNAME(ReduceComplex10)(
- REDUCE_ARGS(long_double_Complex_t));
+typedef long_double_Complex_t (*long_double_Complex_t_value_op)(
+ long_double_Complex_t, long_double_Complex_t);
+
+float_Complex_t RTNAME(ReduceComplex2Ref)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op));
+float_Complex_t RTNAME(ReduceComplex2Value)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op));
+float_Complex_t RTNAME(ReduceComplex3Ref)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op));
+float_Complex_t RTNAME(ReduceComplex3Value)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op));
+float_Complex_t RTNAME(ReduceComplex4Ref)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_ref_op));
+float_Complex_t RTNAME(ReduceComplex4Value)(
+ REDUCE_ARGS(float_Complex_t, float_Complex_t_value_op));
+double_Complex_t RTNAME(ReduceComplex8Ref)(
+ REDUCE_ARGS(double_Complex_t, double_Complex_t_ref_op));
+double_Complex_t RTNAME(ReduceComplex8Value)(
+ REDUCE_ARGS(double_Complex_t, double_Complex_t_value_op));
+long_double_Complex_t RTNAME(ReduceComplex10Ref)(
+ REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_ref_op));
+long_double_Complex_t RTNAME(ReduceComplex10Value)(
+ REDUCE_ARGS(long_double_Complex_t, long_double_Complex_t_value_op));
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-typedef CFloat128ComplexType (*CFloat128ComplexType_op)(
+typedef CFloat128ComplexType (*CFloat128ComplexType_ref_op)(
const CFloat128ComplexType *, const CFloat128ComplexType *);
-CFloat128ComplexType RTNAME(ReduceComplex16)(REDUCE_ARGS(CFloat128ComplexType));
+typedef CFloat128ComplexType (*CFloat128ComplexType_value_op)(
+ CFloat128ComplexType, CFloat128ComplexType);
+CFloat128ComplexType RTNAME(ReduceComplex16Ref)(
+ REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_ref_op));
+CFloat128ComplexType RTNAME(ReduceComplex16Value)(
+ REDUCE_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op));
#endif
-#define REDUCE_DIM_ARGS(T) \
- struct CppDescriptor *result, T##_op operation, \
- const struct CppDescriptor *x, const struct CppDescriptor *y, \
- const char *source, int line, int dim, \
+#define REDUCE_DIM_ARGS(T, OP) \
+ struct CppDescriptor *result, OP operation, const struct CppDescriptor *x, \
+ const struct CppDescriptor *y, const char *source, int line, int dim, \
const struct CppDescriptor *mask /*=NULL*/, const T *identity /*=NULL*/, \
_Bool ordered /*=true*/
#define REDUCE_DIM_ARG_NAMES \
result, operation, x, y, source, line, dim, mask, identity, ordered
-void RTNAME(ReduceComplex2Dim)(REDUCE_DIM_ARGS(float_Complex_t));
-void RTNAME(ReduceComplex3Dim)(REDUCE_DIM_ARGS(float_Complex_t));
-void RTNAME(ReduceComplex4Dim)(REDUCE_DIM_ARGS(float_Complex_t));
-void RTNAME(ReduceComplex8Dim)(REDUCE_DIM_ARGS(double_Complex_t));
-void RTNAME(ReduceComplex10Dim)(REDUCE_DIM_ARGS(long_double_Complex_t));
+void RTNAME(ReduceComplex2DimRef)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_ref_op));
+void RTNAME(ReduceComplex2DimValue)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_value_op));
+void RTNAME(ReduceComplex3DimRef)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_ref_op));
+void RTNAME(ReduceComplex3DimValue)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_value_op));
+void RTNAME(ReduceComplex4DimRef)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_ref_op));
+void RTNAME(ReduceComplex4DimValue)(
+ REDUCE_DIM_ARGS(float_Complex_t, float_Complex_t_value_op));
+void RTNAME(ReduceComplex8DimRef)(
+ REDUCE_DIM_ARGS(double_Complex_t, double_Complex_t_ref_op));
+void RTNAME(ReduceComplex8DimValue)(
+ REDUCE_DIM_ARGS(double_Complex_t, double_Complex_t_value_op));
+void RTNAME(ReduceComplex10DimRef)(
+ REDUCE_DIM_ARGS(long_double_Complex_t, long_double_Complex_t_ref_op));
+void RTNAME(ReduceComplex10DimValue)(
+ REDUCE_DIM_ARGS(long_double_Complex_t, long_double_Complex_t_value_op));
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-void RTNAME(ReduceComplex16Dim)(REDUCE_DIM_ARGS(CFloat128ComplexType));
+void RTNAME(ReduceComplex16DimRef)(
+ REDUCE_DIM_ARGS(CFloat128ComplexType, CFloat128ComplexType_ref_op));
+void RTNAME(ReduceComplex16DimValue)(
+ REDUCE_DIM_ARGS(CFloat128ComplexType, CFloat128ComplexType_value_op));
#endif
#endif // FORTRAN_RUNTIME_COMPLEX_REDUCTION_H_
diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp
index d8b51f1be0c5..9b04cb4f8d0d 100644
--- a/flang/runtime/descriptor.cpp
+++ b/flang/runtime/descriptor.cpp
@@ -199,7 +199,16 @@ RT_API_ATTRS int Descriptor::Destroy(
}
}
-RT_API_ATTRS int Descriptor::Deallocate() { return ISO::CFI_deallocate(&raw_); }
+RT_API_ATTRS int Descriptor::Deallocate() {
+ ISO::CFI_cdesc_t &descriptor{raw()};
+ if (!descriptor.base_addr) {
+ return CFI_ERROR_BASE_ADDR_NULL;
+ } else {
+ std::free(descriptor.base_addr);
+ descriptor.base_addr = nullptr;
+ return CFI_SUCCESS;
+ }
+}
RT_API_ATTRS bool Descriptor::DecrementSubscripts(
SubscriptValue *subscript, const int *permutation) const {
diff --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp
index 0f5bc5059e21..c7f8f386d81f 100644
--- a/flang/runtime/execute.cpp
+++ b/flang/runtime/execute.cpp
@@ -13,8 +13,10 @@
#include "tools.h"
#include "flang/Runtime/descriptor.h"
#include <cstdlib>
+#include <errno.h>
#include <future>
#include <limits>
+
#ifdef _WIN32
#include "flang/Common/windows-include.h"
#else
@@ -32,13 +34,16 @@ namespace Fortran::runtime {
// and the processor does not support asynchronous execution. Otherwise it is
// assigned the value 0
enum CMD_STAT {
- ASYNC_NO_SUPPORT_ERR = -2,
- NO_SUPPORT_ERR = -1,
- CMD_EXECUTED = 0,
- FORK_ERR = 1,
- EXECL_ERR = 2,
- INVALID_CL_ERR = 3,
- SIGNAL_ERR = 4
+ ASYNC_NO_SUPPORT_ERR = -2, // system returns -1 with ENOENT
+ NO_SUPPORT_ERR = -1, // Linux setsid() returns -1
+ CMD_EXECUTED = 0, // command executed with no error
+ FORK_ERR = 1, // Linux fork() returns < 0
+ EXECL_ERR = 2, // system returns -1 with other errno
+ COMMAND_EXECUTION_ERR = 3, // exit code 1
+ COMMAND_CANNOT_EXECUTE_ERR = 4, // Linux exit code 126
+ COMMAND_NOT_FOUND_ERR = 5, // Linux exit code 127
+ INVALID_CL_ERR = 6, // cover all other non-zero exit code
+ SIGNAL_ERR = 7
};
// Override CopyCharsToDescriptor in tools.h, pass string directly
@@ -62,24 +67,86 @@ void CheckAndStoreIntToDescriptor(
// If a condition occurs that would assign a nonzero value to CMDSTAT but
// the CMDSTAT variable is not present, error termination is initiated.
-int TerminationCheck(int status, const Descriptor *cmdstat,
+std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
const Descriptor *cmdmsg, Terminator &terminator) {
+ // On both Windows and Linux, errno is set when system returns -1.
if (status == -1) {
- if (!cmdstat) {
- terminator.Crash("Execution error with system status code: %d", status);
+ // On Windows, ENOENT means the command interpreter can't be found.
+ // On Linux, system calls execl with filepath "/bin/sh", ENOENT means the
+ // file pathname does not exist.
+ if (errno == ENOENT) {
+ if (!cmdstat) {
+ terminator.Crash("Command line execution is not supported, system "
+ "returns -1 with errno ENOENT.");
+ } else {
+ StoreIntToDescriptor(cmdstat, NO_SUPPORT_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(cmdmsg,
+ "Command line execution is not supported, system returns -1 with "
+ "errno ENOENT.");
+ }
} else {
- StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "Execution error");
+ char err_buffer[30];
+ char msg[]{"Execution error with system status code: -1, errno: "};
+#ifdef _WIN32
+ if (strerror_s(err_buffer, sizeof(err_buffer), errno) != 0)
+#else
+ if (strerror_r(errno, err_buffer, sizeof(err_buffer)) != 0)
+#endif
+ terminator.Crash("errno to char msg failed.");
+ char *newMsg{static_cast<char *>(AllocateMemoryOrCrash(
+ terminator, std::strlen(msg) + std::strlen(err_buffer) + 1))};
+ std::strcat(newMsg, err_buffer);
+
+ if (!cmdstat) {
+ terminator.Crash(newMsg);
+ } else {
+ StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(cmdmsg, newMsg);
+ }
+ FreeMemory(newMsg);
}
}
+
#ifdef _WIN32
// On WIN32 API std::system returns exit status directly
- int exitStatusVal{status};
- if (exitStatusVal == 1) {
+ std::int64_t exitStatusVal{status};
+ if (exitStatusVal != 0) {
+ if (!cmdstat) {
+ terminator.Crash(
+ "Invalid command quit with exit status code: %d", exitStatusVal);
+ } else {
+ StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(cmdmsg, "Invalid command line");
+ }
+ }
#else
- int exitStatusVal{WEXITSTATUS(status)};
- if (exitStatusVal == 127 || exitStatusVal == 126) {
-#endif
+ std::int64_t exitStatusVal{WEXITSTATUS(status)};
+ if (exitStatusVal == 1) {
+ if (!cmdstat) {
+ terminator.Crash("Command line execution failed with exit code: 1.");
+ } else {
+ StoreIntToDescriptor(cmdstat, COMMAND_EXECUTION_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(
+ cmdmsg, "Command line execution failed with exit code: 1.");
+ }
+ } else if (exitStatusVal == 126) {
+ if (!cmdstat) {
+ terminator.Crash("Command cannot be executed with exit code: 126.");
+ } else {
+ StoreIntToDescriptor(cmdstat, COMMAND_CANNOT_EXECUTE_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(
+ cmdmsg, "Command cannot be executed with exit code: 126.");
+ }
+ } else if (exitStatusVal == 127) {
+ if (!cmdstat) {
+ terminator.Crash("Command not found with exit code: 127.");
+ } else {
+ StoreIntToDescriptor(cmdstat, COMMAND_NOT_FOUND_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(
+ cmdmsg, "Command not found with exit code: 127.");
+ }
+ // capture all other nonzero exit code
+ } else if (exitStatusVal != 0) {
if (!cmdstat) {
terminator.Crash(
"Invalid command quit with exit status code: %d", exitStatusVal);
@@ -88,23 +155,26 @@ int TerminationCheck(int status, const Descriptor *cmdstat,
CheckAndCopyCharsToDescriptor(cmdmsg, "Invalid command line");
}
}
+#endif
+
#if defined(WIFSIGNALED) && defined(WTERMSIG)
if (WIFSIGNALED(status)) {
if (!cmdstat) {
- terminator.Crash("killed by signal: %d", WTERMSIG(status));
+ terminator.Crash("Killed by signal: %d", WTERMSIG(status));
} else {
StoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "killed by signal");
+ CheckAndCopyCharsToDescriptor(cmdmsg, "Killed by signal");
}
}
#endif
+
#if defined(WIFSTOPPED) && defined(WSTOPSIG)
if (WIFSTOPPED(status)) {
if (!cmdstat) {
- terminator.Crash("stopped by signal: %d", WSTOPSIG(status));
+ terminator.Crash("Stopped by signal: %d", WSTOPSIG(status));
} else {
StoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "stopped by signal");
+ CheckAndCopyCharsToDescriptor(cmdmsg, "Stopped by signal");
}
}
#endif
@@ -134,8 +204,9 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
if (wait) {
// either wait is not specified or wait is true: synchronous mode
- int status{std::system(newCmd)};
- int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)};
+ std::int64_t status{std::system(newCmd)};
+ std::int64_t exitStatusVal{
+ TerminationCheck(status, cmdstat, cmdmsg, terminator)};
// If sync, assigned processor-dependent exit status. Otherwise unchanged
CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator);
} else {
@@ -173,7 +244,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
terminator.Crash(
"CreateProcess failed with error code: %lu.", GetLastError());
} else {
- StoreIntToDescriptor(cmdstat, (uint32_t)GetLastError(), terminator);
+ StoreIntToDescriptor(cmdstat, ASYNC_NO_SUPPORT_ERR, terminator);
CheckAndCopyCharsToDescriptor(cmdmsg, "CreateProcess failed.");
}
}
@@ -201,7 +272,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
}
exit(EXIT_FAILURE);
}
- int status{std::system(newCmd)};
+ std::int64_t status{std::system(newCmd)};
TerminationCheck(status, cmdstat, cmdmsg, terminator);
exit(status);
}
diff --git a/flang/runtime/external-unit.cpp b/flang/runtime/external-unit.cpp
index 328c994a180b..8009151a8a37 100644
--- a/flang/runtime/external-unit.cpp
+++ b/flang/runtime/external-unit.cpp
@@ -65,10 +65,17 @@ ExternalFileUnit *ExternalFileUnit::LookUpOrCreateAnonymous(int unit,
bool exists{false};
ExternalFileUnit *result{GetUnitMap().LookUpOrCreate(unit, handler, exists)};
if (result && !exists) {
- result->OpenAnonymousUnit(
- dir == Direction::Input ? OpenStatus::Unknown : OpenStatus::Replace,
- Action::ReadWrite, Position::Rewind, Convert::Unknown, handler);
- result->isUnformatted = isUnformatted;
+ if (!result->OpenAnonymousUnit(
+ dir == Direction::Input ? OpenStatus::Unknown : OpenStatus::Replace,
+ Action::ReadWrite, Position::Rewind, Convert::Unknown, handler)) {
+ // fort.N isn't a writable file
+ if (ExternalFileUnit * closed{LookUpForClose(result->unitNumber())}) {
+ closed->DestroyClosed();
+ }
+ result = nullptr;
+ } else {
+ result->isUnformatted = isUnformatted;
+ }
}
return result;
}
@@ -183,7 +190,7 @@ bool ExternalFileUnit::OpenUnit(Fortran::common::optional<OpenStatus> status,
return impliedClose;
}
-void ExternalFileUnit::OpenAnonymousUnit(
+bool ExternalFileUnit::OpenAnonymousUnit(
Fortran::common::optional<OpenStatus> status,
Fortran::common::optional<Action> action, Position position,
Convert convert, IoErrorHandler &handler) {
@@ -193,6 +200,7 @@ void ExternalFileUnit::OpenAnonymousUnit(
std::snprintf(path.get(), pathMaxLen, "fort.%d", unitNumber_);
OpenUnit(status, action, position, std::move(path), std::strlen(path.get()),
convert, handler);
+ return IsConnected();
}
void ExternalFileUnit::CloseUnit(CloseStatus status, IoErrorHandler &handler) {
diff --git a/flang/runtime/inquiry.cpp b/flang/runtime/inquiry.cpp
index ea114174de7f..9fbcaa96fa3c 100644
--- a/flang/runtime/inquiry.cpp
+++ b/flang/runtime/inquiry.cpp
@@ -39,28 +39,14 @@ std::int64_t RTDEF(LboundDim)(
return static_cast<std::int64_t>(dimension.LowerBound());
}
-void RTDEF(Ubound)(Descriptor &result, const Descriptor &array, int kind,
+void RTDEF(Ubound)(void *result, const Descriptor &array, int kind,
const char *sourceFile, int line) {
- SubscriptValue extent[1]{array.rank()};
- result.Establish(TypeCategory::Integer, kind, nullptr, 1, extent,
- CFI_attribute_allocatable);
- // The array returned by UBOUND has a lower bound of 1 and an extent equal to
- // the rank of its input array.
- result.GetDimension(0).SetBounds(1, array.rank());
Terminator terminator{sourceFile, line};
- if (int stat{result.Allocate()}) {
- terminator.Crash(
- "UBOUND: could not allocate memory for result; STAT=%d", stat);
- }
- auto storeIntegerAt = [&](std::size_t atIndex, std::int64_t value) {
- Fortran::runtime::ApplyIntegerKind<StoreIntegerAt, void>(
- kind, terminator, result, atIndex, value);
- };
-
- INTERNAL_CHECK(result.rank() == 1);
+ INTERNAL_CHECK(array.rank() <= common::maxRank);
for (SubscriptValue i{0}; i < array.rank(); ++i) {
const Dimension &dimension{array.GetDimension(i)};
- storeIntegerAt(i, dimension.UpperBound());
+ Fortran::runtime::ApplyIntegerKind<RawStoreIntegerAt, void>(
+ kind, terminator, result, i, dimension.UpperBound());
}
}
@@ -85,8 +71,9 @@ std::int64_t RTDEF(SizeDim)(
return static_cast<std::int64_t>(dimension.Extent());
}
-void RTDEF(Shape)(void *result, const Descriptor &array, int kind) {
- Terminator terminator{__FILE__, __LINE__};
+void RTDEF(Shape)(void *result, const Descriptor &array, int kind,
+ const char *sourceFile, int line) {
+ Terminator terminator{sourceFile, line};
INTERNAL_CHECK(array.rank() <= common::maxRank);
for (SubscriptValue i{0}; i < array.rank(); ++i) {
const Dimension &dimension{array.GetDimension(i)};
@@ -95,5 +82,16 @@ void RTDEF(Shape)(void *result, const Descriptor &array, int kind) {
}
}
+void RTDEF(Lbound)(void *result, const Descriptor &array, int kind,
+ const char *sourceFile, int line) {
+ Terminator terminator{sourceFile, line};
+ INTERNAL_CHECK(array.rank() <= common::maxRank);
+ for (SubscriptValue i{0}; i < array.rank(); ++i) {
+ const Dimension &dimension{array.GetDimension(i)};
+ Fortran::runtime::ApplyIntegerKind<RawStoreIntegerAt, void>(
+ kind, terminator, result, i, dimension.LowerBound());
+ }
+}
+
} // extern "C"
} // namespace Fortran::runtime
diff --git a/flang/runtime/numeric-templates.h b/flang/runtime/numeric-templates.h
index 4936e7738a66..1b5395df9451 100644
--- a/flang/runtime/numeric-templates.h
+++ b/flang/runtime/numeric-templates.h
@@ -354,6 +354,110 @@ template <int PREC, typename T> inline RT_API_ATTRS T Spacing(T x) {
}
}
+// ERFC_SCALED (16.9.71)
+template <typename T> inline RT_API_ATTRS T ErfcScaled(T arg) {
+ // Coefficients for approximation to erfc in the first interval.
+ static const T a[5] = {3.16112374387056560e00, 1.13864154151050156e02,
+ 3.77485237685302021e02, 3.20937758913846947e03, 1.85777706184603153e-1};
+ static const T b[4] = {2.36012909523441209e01, 2.44024637934444173e02,
+ 1.28261652607737228e03, 2.84423683343917062e03};
+
+ // Coefficients for approximation to erfc in the second interval.
+ static const T c[9] = {5.64188496988670089e-1, 8.88314979438837594e00,
+ 6.61191906371416295e01, 2.98635138197400131e02, 8.81952221241769090e02,
+ 1.71204761263407058e03, 2.05107837782607147e03, 1.23033935479799725e03,
+ 2.15311535474403846e-8};
+ static const T d[8] = {1.57449261107098347e01, 1.17693950891312499e02,
+ 5.37181101862009858e02, 1.62138957456669019e03, 3.29079923573345963e03,
+ 4.36261909014324716e03, 3.43936767414372164e03, 1.23033935480374942e03};
+
+ // Coefficients for approximation to erfc in the third interval.
+ static const T p[6] = {3.05326634961232344e-1, 3.60344899949804439e-1,
+ 1.25781726111229246e-1, 1.60837851487422766e-2, 6.58749161529837803e-4,
+ 1.63153871373020978e-2};
+ static const T q[5] = {2.56852019228982242e00, 1.87295284992346047e00,
+ 5.27905102951428412e-1, 6.05183413124413191e-2, 2.33520497626869185e-3};
+
+ constexpr T sqrtpi{1.7724538509078120380404576221783883301349L};
+ constexpr T rsqrtpi{0.5641895835477562869480794515607725858440L};
+ constexpr T epsilonby2{std::numeric_limits<T>::epsilon() * 0.5};
+ constexpr T xneg{-26.628e0};
+ constexpr T xhuge{6.71e7};
+ constexpr T thresh{0.46875e0};
+ constexpr T zero{0.0};
+ constexpr T one{1.0};
+ constexpr T four{4.0};
+ constexpr T sixteen{16.0};
+ constexpr T xmax{1.0 / (sqrtpi * std::numeric_limits<T>::min())};
+ static_assert(xmax > xhuge, "xmax must be greater than xhuge");
+
+ T ysq;
+ T xnum;
+ T xden;
+ T del;
+ T result;
+
+ auto x{arg};
+ auto y{std::fabs(x)};
+
+ if (y <= thresh) {
+ // evaluate erf for |x| <= 0.46875
+ ysq = zero;
+ if (y > epsilonby2) {
+ ysq = y * y;
+ }
+ xnum = a[4] * ysq;
+ xden = ysq;
+ for (int i{0}; i < 3; i++) {
+ xnum = (xnum + a[i]) * ysq;
+ xden = (xden + b[i]) * ysq;
+ }
+ result = x * (xnum + a[3]) / (xden + b[3]);
+ result = one - result;
+ result = std::exp(ysq) * result;
+ return result;
+ } else if (y <= four) {
+ // evaluate erfc for 0.46875 < |x| <= 4.0
+ xnum = c[8] * y;
+ xden = y;
+ for (int i{0}; i < 7; ++i) {
+ xnum = (xnum + c[i]) * y;
+ xden = (xden + d[i]) * y;
+ }
+ result = (xnum + c[7]) / (xden + d[7]);
+ } else {
+ // evaluate erfc for |x| > 4.0
+ result = zero;
+ if (y >= xhuge) {
+ if (y < xmax) {
+ result = rsqrtpi / y;
+ }
+ } else {
+ ysq = one / (y * y);
+ xnum = p[5] * ysq;
+ xden = ysq;
+ for (int i{0}; i < 4; ++i) {
+ xnum = (xnum + p[i]) * ysq;
+ xden = (xden + q[i]) * ysq;
+ }
+ result = ysq * (xnum + p[4]) / (xden + q[4]);
+ result = (rsqrtpi - result) / y;
+ }
+ }
+ // fix up for negative argument, erf, etc.
+ if (x < zero) {
+ if (x < xneg) {
+ result = std::numeric_limits<T>::max();
+ } else {
+ ysq = trunc(x * sixteen) / sixteen;
+ del = (x - ysq) * (x + ysq);
+ y = std::exp((ysq * ysq)) * std::exp((del));
+ result = (y + y) - result;
+ }
+ }
+ return result;
+}
+
} // namespace Fortran::runtime
#endif // FORTRAN_RUNTIME_NUMERIC_TEMPLATES_H_
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index 2225473c4690..7c40beb31083 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -316,6 +316,27 @@ CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling16_16)(
#endif
#endif
+CppTypeFor<TypeCategory::Real, 4> RTDEF(ErfcScaled4)(
+ CppTypeFor<TypeCategory::Real, 4> x) {
+ return ErfcScaled(x);
+}
+CppTypeFor<TypeCategory::Real, 8> RTDEF(ErfcScaled8)(
+ CppTypeFor<TypeCategory::Real, 8> x) {
+ return ErfcScaled(x);
+}
+#if LDBL_MANT_DIG == 64
+CppTypeFor<TypeCategory::Real, 10> RTDEF(ErfcScaled10)(
+ CppTypeFor<TypeCategory::Real, 10> x) {
+ return ErfcScaled(x);
+}
+#endif
+#if LDBL_MANT_DIG == 113
+CppTypeFor<TypeCategory::Real, 16> RTDEF(ErfcScaled16)(
+ CppTypeFor<TypeCategory::Real, 16> x) {
+ return ErfcScaled(x);
+}
+#endif
+
CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent4_4)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
diff --git a/flang/runtime/pointer.cpp b/flang/runtime/pointer.cpp
index 08a1223764f3..aeed879f1a2e 100644
--- a/flang/runtime/pointer.cpp
+++ b/flang/runtime/pointer.cpp
@@ -124,6 +124,23 @@ void RTDEF(PointerAssociateRemapping)(Descriptor &pointer,
}
}
+RT_API_ATTRS void *AllocateValidatedPointerPayload(std::size_t byteSize) {
+ // Add space for a footer to validate during deallocation.
+ constexpr std::size_t align{sizeof(std::uintptr_t)};
+ byteSize = ((byteSize / align) + 1) * align;
+ std::size_t total{byteSize + sizeof(std::uintptr_t)};
+ void *p{std::malloc(total)};
+ if (p) {
+ // Fill the footer word with the XOR of the ones' complement of
+ // the base address, which is a value that would be highly unlikely
+ // to appear accidentally at the right spot.
+ std::uintptr_t *footer{
+ reinterpret_cast<std::uintptr_t *>(static_cast<char *>(p) + byteSize)};
+ *footer = ~reinterpret_cast<std::uintptr_t>(p);
+ }
+ return p;
+}
+
int RTDEF(PointerAllocate)(Descriptor &pointer, bool hasStat,
const Descriptor *errMsg, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
@@ -137,22 +154,12 @@ int RTDEF(PointerAllocate)(Descriptor &pointer, bool hasStat,
elementBytes = pointer.raw().elem_len = 0;
}
std::size_t byteSize{pointer.Elements() * elementBytes};
- // Add space for a footer to validate during DEALLOCATE.
- constexpr std::size_t align{sizeof(std::uintptr_t)};
- byteSize = ((byteSize + align - 1) / align) * align;
- std::size_t total{byteSize + sizeof(std::uintptr_t)};
- void *p{std::malloc(total)};
+ void *p{AllocateValidatedPointerPayload(byteSize)};
if (!p) {
return ReturnError(terminator, CFI_ERROR_MEM_ALLOCATION, errMsg, hasStat);
}
pointer.set_base_addr(p);
pointer.SetByteStrides();
- // Fill the footer word with the XOR of the ones' complement of
- // the base address, which is a value that would be highly unlikely
- // to appear accidentally at the right spot.
- std::uintptr_t *footer{
- reinterpret_cast<std::uintptr_t *>(static_cast<char *>(p) + byteSize)};
- *footer = ~reinterpret_cast<std::uintptr_t>(p);
int stat{StatOk};
if (const DescriptorAddendum * addendum{pointer.Addendum()}) {
if (const auto *derived{addendum->derivedType()}) {
@@ -176,6 +183,27 @@ int RTDEF(PointerAllocateSource)(Descriptor &pointer, const Descriptor &source,
return stat;
}
+static RT_API_ATTRS std::size_t GetByteSize(
+ const ISO::CFI_cdesc_t &descriptor) {
+ std::size_t rank{descriptor.rank};
+ const ISO::CFI_dim_t *dim{descriptor.dim};
+ std::size_t byteSize{descriptor.elem_len};
+ for (std::size_t j{0}; j < rank; ++j) {
+ byteSize *= dim[j].extent;
+ }
+ return byteSize;
+}
+
+bool RT_API_ATTRS ValidatePointerPayload(const ISO::CFI_cdesc_t &desc) {
+ std::size_t byteSize{GetByteSize(desc)};
+ constexpr std::size_t align{sizeof(std::uintptr_t)};
+ byteSize = ((byteSize / align) + 1) * align;
+ const void *p{desc.base_addr};
+ const std::uintptr_t *footer{reinterpret_cast<const std::uintptr_t *>(
+ static_cast<const char *>(p) + byteSize)};
+ return *footer == ~reinterpret_cast<std::uintptr_t>(p);
+}
+
int RTDEF(PointerDeallocate)(Descriptor &pointer, bool hasStat,
const Descriptor *errMsg, const char *sourceFile, int sourceLine) {
Terminator terminator{sourceFile, sourceLine};
@@ -185,20 +213,9 @@ int RTDEF(PointerDeallocate)(Descriptor &pointer, bool hasStat,
if (!pointer.IsAllocated()) {
return ReturnError(terminator, StatBaseNull, errMsg, hasStat);
}
- if (executionEnvironment.checkPointerDeallocation) {
- // Validate the footer. This should fail if the pointer doesn't
- // span the entire object, or the object was not allocated as a
- // pointer.
- std::size_t byteSize{pointer.Elements() * pointer.ElementBytes()};
- constexpr std::size_t align{sizeof(std::uintptr_t)};
- byteSize = ((byteSize + align - 1) / align) * align;
- void *p{pointer.raw().base_addr};
- std::uintptr_t *footer{
- reinterpret_cast<std::uintptr_t *>(static_cast<char *>(p) + byteSize)};
- if (*footer != ~reinterpret_cast<std::uintptr_t>(p)) {
- return ReturnError(
- terminator, StatBadPointerDeallocation, errMsg, hasStat);
- }
+ if (executionEnvironment.checkPointerDeallocation &&
+ !ValidatePointerPayload(pointer.raw())) {
+ return ReturnError(terminator, StatBadPointerDeallocation, errMsg, hasStat);
}
return ReturnError(terminator,
pointer.Destroy(/*finalize=*/true, /*destroyPointers=*/true, &terminator),
diff --git a/flang/runtime/pseudo-unit.cpp b/flang/runtime/pseudo-unit.cpp
index 70e70eec6a77..526afd11d916 100644
--- a/flang/runtime/pseudo-unit.cpp
+++ b/flang/runtime/pseudo-unit.cpp
@@ -65,7 +65,7 @@ bool ExternalFileUnit::OpenUnit(Fortran::common::optional<OpenStatus> status,
handler.Crash("%s: unsupported", RT_PRETTY_FUNCTION);
}
-void ExternalFileUnit::OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
+bool ExternalFileUnit::OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
Fortran::common::optional<Action>, Position, Convert convert,
IoErrorHandler &handler) {
handler.Crash("%s: unsupported", RT_PRETTY_FUNCTION);
diff --git a/flang/runtime/reduce.cpp b/flang/runtime/reduce.cpp
index f8a5221a1ebf..2f4bb6ea159c 100644
--- a/flang/runtime/reduce.cpp
+++ b/flang/runtime/reduce.cpp
@@ -16,11 +16,12 @@
namespace Fortran::runtime {
-template <typename T> class ReduceAccumulator {
+template <typename T, bool isByValue> class ReduceAccumulator {
public:
- RT_API_ATTRS ReduceAccumulator(const Descriptor &array,
- ReductionOperation<T> operation, const T *identity,
- Terminator &terminator)
+ using Operation = std::conditional_t<isByValue, ValueReductionOperation<T>,
+ ReferenceReductionOperation<T>>;
+ RT_API_ATTRS ReduceAccumulator(const Descriptor &array, Operation operation,
+ const T *identity, Terminator &terminator)
: array_{array}, operation_{operation}, identity_{identity},
terminator_{terminator} {}
RT_API_ATTRS void Reinitialize() { result_.reset(); }
@@ -28,7 +29,11 @@ public:
RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) {
const auto *operand{array_.Element<A>(at)};
if (result_) {
- result_ = operation_(&*result_, operand);
+ if constexpr (isByValue) {
+ result_ = operation_(*result_, *operand);
+ } else {
+ result_ = operation_(&*result_, operand);
+ }
} else {
result_ = *operand;
}
@@ -48,7 +53,7 @@ public:
private:
const Descriptor &array_;
common::optional<T> result_;
- ReductionOperation<T> operation_;
+ Operation operation_;
const T *identity_{nullptr};
Terminator &terminator_;
};
@@ -104,104 +109,213 @@ private:
extern "C" {
RT_EXT_API_GROUP_BEGIN
-std::int8_t RTDEF(ReduceInteger1)(const Descriptor &array,
- ReductionOperation<std::int8_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int8_t *identity,
+std::int8_t RTDEF(ReduceInteger1Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Integer, 1>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::int8_t, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+std::int8_t RTDEF(ReduceInteger1Value)(const Descriptor &array,
+ ValueReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Integer, 1>(array, source, line, dim,
mask,
- ReduceAccumulator<std::int8_t>{array, operation, identity, terminator},
+ ReduceAccumulator<std::int8_t, true>{
+ array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceInteger1Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int8_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int8_t *identity,
+void RTDEF(ReduceInteger1DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::int8_t, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Integer, 1>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceInteger1DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::int8_t>;
+ using Accumulator = ReduceAccumulator<std::int8_t, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Integer, 1>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-std::int16_t RTDEF(ReduceInteger2)(const Descriptor &array,
- ReductionOperation<std::int16_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int16_t *identity,
+std::int16_t RTDEF(ReduceInteger2Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Integer, 2>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::int16_t, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+std::int16_t RTDEF(ReduceInteger2Value)(const Descriptor &array,
+ ValueReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Integer, 2>(array, source, line, dim,
mask,
- ReduceAccumulator<std::int16_t>{array, operation, identity, terminator},
+ ReduceAccumulator<std::int16_t, true>{
+ array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceInteger2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int16_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int16_t *identity,
+void RTDEF(ReduceInteger2DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::int16_t, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Integer, 2>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceInteger2DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::int16_t>;
+ using Accumulator = ReduceAccumulator<std::int16_t, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Integer, 2>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-std::int32_t RTDEF(ReduceInteger4)(const Descriptor &array,
- ReductionOperation<std::int32_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int32_t *identity,
+std::int32_t RTDEF(ReduceInteger4Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Integer, 4>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::int32_t, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+std::int32_t RTDEF(ReduceInteger4Value)(const Descriptor &array,
+ ValueReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Integer, 4>(array, source, line, dim,
mask,
- ReduceAccumulator<std::int32_t>{array, operation, identity, terminator},
+ ReduceAccumulator<std::int32_t, true>{
+ array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceInteger4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int32_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int32_t *identity,
+void RTDEF(ReduceInteger4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::int32_t, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Integer, 4>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceInteger4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::int32_t>;
+ using Accumulator = ReduceAccumulator<std::int32_t, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Integer, 4>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-std::int64_t RTDEF(ReduceInteger8)(const Descriptor &array,
- ReductionOperation<std::int64_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int64_t *identity,
+std::int64_t RTDEF(ReduceInteger8Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Integer, 8>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::int64_t, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+std::int64_t RTDEF(ReduceInteger8Value)(const Descriptor &array,
+ ValueReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Integer, 8>(array, source, line, dim,
mask,
- ReduceAccumulator<std::int64_t>{array, operation, identity, terminator},
+ ReduceAccumulator<std::int64_t, true>{
+ array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceInteger8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int64_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int64_t *identity,
+void RTDEF(ReduceInteger8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::int64_t, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Integer, 8>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceInteger8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::int64_t>;
+ using Accumulator = ReduceAccumulator<std::int64_t, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Integer, 8>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#ifdef __SIZEOF_INT128__
-common::int128_t RTDEF(ReduceInteger16)(const Descriptor &array,
- ReductionOperation<common::int128_t> operation, const char *source,
+common::int128_t RTDEF(ReduceInteger16Ref)(const Descriptor &array,
+ ReferenceReductionOperation<common::int128_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const common::int128_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Integer, 16>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<common::int128_t, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+common::int128_t RTDEF(ReduceInteger16Value)(const Descriptor &array,
+ ValueReductionOperation<common::int128_t> operation, const char *source,
int line, int dim, const Descriptor *mask, const common::int128_t *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Integer, 16>(array, source, line, dim,
mask,
- ReduceAccumulator<common::int128_t>{
+ ReduceAccumulator<common::int128_t, true>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceInteger16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<common::int128_t> operation, const char *source,
+void RTDEF(ReduceInteger16DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<common::int128_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const common::int128_t *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<common::int128_t, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Integer, 16>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceInteger16DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<common::int128_t> operation, const char *source,
int line, int dim, const Descriptor *mask, const common::int128_t *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<common::int128_t>;
+ using Accumulator = ReduceAccumulator<common::int128_t, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Integer, 16>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
@@ -209,231 +323,464 @@ void RTDEF(ReduceInteger16Dim)(Descriptor &result, const Descriptor &array,
#endif
// TODO: real/complex(2 & 3)
-float RTDEF(ReduceReal4)(const Descriptor &array,
- ReductionOperation<float> operation, const char *source, int line, int dim,
- const Descriptor *mask, const float *identity, bool ordered) {
+float RTDEF(ReduceReal4Ref)(const Descriptor &array,
+ ReferenceReductionOperation<float> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const float *identity, bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<float, false>{array, operation, identity, terminator},
+ "REDUCE");
+}
+float RTDEF(ReduceReal4Value)(const Descriptor &array,
+ ValueReductionOperation<float> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const float *identity, bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
- mask, ReduceAccumulator<float>{array, operation, identity, terminator},
+ mask,
+ ReduceAccumulator<float, true>{array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceReal4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<float> operation, const char *source, int line, int dim,
- const Descriptor *mask, const float *identity, bool ordered) {
+void RTDEF(ReduceReal4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<float> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const float *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<float, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceReal4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<float> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const float *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<float>;
+ using Accumulator = ReduceAccumulator<float, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-double RTDEF(ReduceReal8)(const Descriptor &array,
- ReductionOperation<double> operation, const char *source, int line, int dim,
- const Descriptor *mask, const double *identity, bool ordered) {
+double RTDEF(ReduceReal8Ref)(const Descriptor &array,
+ ReferenceReductionOperation<double> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const double *identity, bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
- mask, ReduceAccumulator<double>{array, operation, identity, terminator},
+ mask,
+ ReduceAccumulator<double, false>{array, operation, identity, terminator},
+ "REDUCE");
+}
+double RTDEF(ReduceReal8Value)(const Descriptor &array,
+ ValueReductionOperation<double> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const double *identity, bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<double, true>{array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceReal8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<double> operation, const char *source, int line, int dim,
- const Descriptor *mask, const double *identity, bool ordered) {
+void RTDEF(ReduceReal8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<double> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const double *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<double>;
+ using Accumulator = ReduceAccumulator<double, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceReal8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<double> operation, const char *source, int line,
+ int dim, const Descriptor *mask, const double *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<double, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#if LDBL_MANT_DIG == 64
-long double RTDEF(ReduceReal10)(const Descriptor &array,
- ReductionOperation<long double> operation, const char *source, int line,
- int dim, const Descriptor *mask, const long double *identity,
+long double RTDEF(ReduceReal10Ref)(const Descriptor &array,
+ ReferenceReductionOperation<long double> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const long double *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<long double, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+long double RTDEF(ReduceReal10Value)(const Descriptor &array,
+ ValueReductionOperation<long double> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const long double *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
mask,
- ReduceAccumulator<long double>{array, operation, identity, terminator},
+ ReduceAccumulator<long double, true>{
+ array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceReal10Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<long double> operation, const char *source, int line,
- int dim, const Descriptor *mask, const long double *identity,
+void RTDEF(ReduceReal10DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<long double> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const long double *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<long double, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceReal10DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<long double> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const long double *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<long double>;
+ using Accumulator = ReduceAccumulator<long double, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppFloat128Type RTDEF(ReduceReal16)(const Descriptor &array,
- ReductionOperation<CppFloat128Type> operation, const char *source, int line,
- int dim, const Descriptor *mask, const CppFloat128Type *identity,
+CppFloat128Type RTDEF(ReduceReal16Ref)(const Descriptor &array,
+ ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
bool ordered) {
Terminator terminator{source, line};
return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
mask,
- ReduceAccumulator<CppFloat128Type>{
+ ReduceAccumulator<CppFloat128Type, false>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(ReduceReal16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<CppFloat128Type> operation, const char *source, int line,
- int dim, const Descriptor *mask, const CppFloat128Type *identity,
+CppFloat128Type RTDEF(ReduceReal16Value)(const Descriptor &array,
+ ValueReductionOperation<CppFloat128Type> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<CppFloat128Type>;
+ return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<CppFloat128Type, true>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+void RTDEF(ReduceReal16DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<CppFloat128Type, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(ReduceReal16DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<CppFloat128Type> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
+ bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<CppFloat128Type, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#endif
-void RTDEF(CppReduceComplex4)(std::complex<float> &result,
- const Descriptor &array, ReductionOperation<std::complex<float>> operation,
+void RTDEF(CppReduceComplex4Ref)(std::complex<float> &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<float>> operation,
const char *source, int line, int dim, const Descriptor *mask,
const std::complex<float> *identity, bool ordered) {
Terminator terminator{source, line};
result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
mask,
- ReduceAccumulator<std::complex<float>>{
+ ReduceAccumulator<std::complex<float>, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+void RTDEF(CppReduceComplex4Value)(std::complex<float> &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<float>> operation, const char *source,
+ int line, int dim, const Descriptor *mask,
+ const std::complex<float> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::complex<float>, true>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(CppReduceComplex4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<float>> operation, const char *source,
+void RTDEF(CppReduceComplex4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::complex<float>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<float> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<float>, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(CppReduceComplex4DimValue)(Descriptor &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<float>> operation, const char *source,
int line, int dim, const Descriptor *mask,
const std::complex<float> *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::complex<float>>;
+ using Accumulator = ReduceAccumulator<std::complex<float>, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-void RTDEF(CppReduceComplex8)(std::complex<double> &result,
- const Descriptor &array, ReductionOperation<std::complex<double>> operation,
+void RTDEF(CppReduceComplex8Ref)(std::complex<double> &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<double>> operation,
const char *source, int line, int dim, const Descriptor *mask,
const std::complex<double> *identity, bool ordered) {
Terminator terminator{source, line};
result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
mask,
- ReduceAccumulator<std::complex<double>>{
+ ReduceAccumulator<std::complex<double>, false>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(CppReduceComplex8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<double>> operation, const char *source,
+void RTDEF(CppReduceComplex8Value)(std::complex<double> &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<double>> operation, const char *source,
int line, int dim, const Descriptor *mask,
const std::complex<double> *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::complex<double>>;
+ result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
+ mask,
+ ReduceAccumulator<std::complex<double>, true>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+void RTDEF(CppReduceComplex8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::complex<double>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<double> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<double>, false>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
-#if LDBL_MANT_DIG == 64
-void RTDEF(CppReduceComplex10)(std::complex<long double> &result,
+void RTDEF(CppReduceComplex8DimValue)(Descriptor &result,
const Descriptor &array,
- ReductionOperation<std::complex<long double>> operation, const char *source,
+ ValueReductionOperation<std::complex<double>> operation, const char *source,
int line, int dim, const Descriptor *mask,
+ const std::complex<double> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<double>, true>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+#if LDBL_MANT_DIG == 64
+void RTDEF(CppReduceComplex10Ref)(std::complex<long double> &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<long double>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
const std::complex<long double> *identity, bool ordered) {
Terminator terminator{source, line};
result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
dim, mask,
- ReduceAccumulator<std::complex<long double>>{
+ ReduceAccumulator<std::complex<long double>, false>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(CppReduceComplex10Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<long double>> operation, const char *source,
- int line, int dim, const Descriptor *mask,
+void RTDEF(CppReduceComplex10Value)(std::complex<long double> &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<long double>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
const std::complex<long double> *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::complex<long double>>;
+ result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
+ dim, mask,
+ ReduceAccumulator<std::complex<long double>, true>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+void RTDEF(CppReduceComplex10DimRef)(Descriptor &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<long double>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<long double> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<long double>, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(CppReduceComplex10DimValue)(Descriptor &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<long double>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<long double> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<long double>, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-void RTDEF(CppReduceComplex16)(std::complex<CppFloat128Type> &result,
+void RTDEF(CppReduceComplex16Ref)(std::complex<CppFloat128Type> &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<CppFloat128Type>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<CppFloat128Type> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
+ dim, mask,
+ ReduceAccumulator<std::complex<CppFloat128Type>, false>{
+ array, operation, identity, terminator},
+ "REDUCE");
+}
+void RTDEF(CppReduceComplex16Value)(std::complex<CppFloat128Type> &result,
const Descriptor &array,
- ReductionOperation<std::complex<CppFloat128Type>> operation,
+ ValueReductionOperation<std::complex<CppFloat128Type>> operation,
const char *source, int line, int dim, const Descriptor *mask,
const std::complex<CppFloat128Type> *identity, bool ordered) {
Terminator terminator{source, line};
result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
dim, mask,
- ReduceAccumulator<std::complex<CppFloat128Type>>{
+ ReduceAccumulator<std::complex<CppFloat128Type>, true>{
array, operation, identity, terminator},
"REDUCE");
}
-void RTDEF(CppReduceComplex16Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::complex<CppFloat128Type>> operation,
+void RTDEF(CppReduceComplex16DimRef)(Descriptor &result,
+ const Descriptor &array,
+ ReferenceReductionOperation<std::complex<CppFloat128Type>> operation,
const char *source, int line, int dim, const Descriptor *mask,
const std::complex<CppFloat128Type> *identity, bool ordered) {
Terminator terminator{source, line};
- using Accumulator = ReduceAccumulator<std::complex<CppFloat128Type>>;
+ using Accumulator = ReduceAccumulator<std::complex<CppFloat128Type>, false>;
+ Accumulator accumulator{array, operation, identity, terminator};
+ PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
+ array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
+}
+void RTDEF(CppReduceComplex16DimValue)(Descriptor &result,
+ const Descriptor &array,
+ ValueReductionOperation<std::complex<CppFloat128Type>> operation,
+ const char *source, int line, int dim, const Descriptor *mask,
+ const std::complex<CppFloat128Type> *identity, bool ordered) {
+ Terminator terminator{source, line};
+ using Accumulator = ReduceAccumulator<std::complex<CppFloat128Type>, true>;
Accumulator accumulator{array, operation, identity, terminator};
PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
}
#endif
-bool RTDEF(ReduceLogical1)(const Descriptor &array,
- ReductionOperation<std::int8_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int8_t *identity,
+bool RTDEF(ReduceLogical1Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
bool ordered) {
- return RTNAME(ReduceInteger1)(
+ return RTNAME(ReduceInteger1Ref)(
array, operation, source, line, dim, mask, identity, ordered) != 0;
}
-void RTDEF(ReduceLogical1Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int8_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int8_t *identity,
+bool RTDEF(ReduceLogical1Value)(const Descriptor &array,
+ ValueReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
+ bool ordered) {
+ return RTNAME(ReduceInteger1Value)(
+ array, operation, source, line, dim, mask, identity, ordered) != 0;
+}
+void RTDEF(ReduceLogical1DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
+ bool ordered) {
+ RTNAME(ReduceInteger1DimRef)
+ (result, array, operation, source, line, dim, mask, identity, ordered);
+}
+void RTDEF(ReduceLogical1DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int8_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int8_t *identity,
bool ordered) {
- RTNAME(ReduceInteger1Dim)
+ RTNAME(ReduceInteger1DimValue)
(result, array, operation, source, line, dim, mask, identity, ordered);
}
-bool RTDEF(ReduceLogical2)(const Descriptor &array,
- ReductionOperation<std::int16_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int16_t *identity,
+bool RTDEF(ReduceLogical2Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
bool ordered) {
- return RTNAME(ReduceInteger2)(
+ return RTNAME(ReduceInteger2Ref)(
array, operation, source, line, dim, mask, identity, ordered) != 0;
}
-void RTDEF(ReduceLogical2Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int16_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int16_t *identity,
+bool RTDEF(ReduceLogical2Value)(const Descriptor &array,
+ ValueReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
bool ordered) {
- RTNAME(ReduceInteger2Dim)
+ return RTNAME(ReduceInteger2Value)(
+ array, operation, source, line, dim, mask, identity, ordered) != 0;
+}
+void RTDEF(ReduceLogical2DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
+ bool ordered) {
+ RTNAME(ReduceInteger2DimRef)
(result, array, operation, source, line, dim, mask, identity, ordered);
}
-bool RTDEF(ReduceLogical4)(const Descriptor &array,
- ReductionOperation<std::int32_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int32_t *identity,
+void RTDEF(ReduceLogical2DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int16_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int16_t *identity,
bool ordered) {
- return RTNAME(ReduceInteger4)(
+ RTNAME(ReduceInteger2DimValue)
+ (result, array, operation, source, line, dim, mask, identity, ordered);
+}
+bool RTDEF(ReduceLogical4Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
+ bool ordered) {
+ return RTNAME(ReduceInteger4Ref)(
+ array, operation, source, line, dim, mask, identity, ordered) != 0;
+}
+bool RTDEF(ReduceLogical4Value)(const Descriptor &array,
+ ValueReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
+ bool ordered) {
+ return RTNAME(ReduceInteger4Value)(
array, operation, source, line, dim, mask, identity, ordered) != 0;
}
-void RTDEF(ReduceLogical4Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int32_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int32_t *identity,
+void RTDEF(ReduceLogical4DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
+ bool ordered) {
+ RTNAME(ReduceInteger4DimRef)
+ (result, array, operation, source, line, dim, mask, identity, ordered);
+}
+void RTDEF(ReduceLogical4DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int32_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int32_t *identity,
bool ordered) {
- RTNAME(ReduceInteger4Dim)
+ RTNAME(ReduceInteger4DimValue)
(result, array, operation, source, line, dim, mask, identity, ordered);
}
-bool RTDEF(ReduceLogical8)(const Descriptor &array,
- ReductionOperation<std::int64_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int64_t *identity,
+bool RTDEF(ReduceLogical8Ref)(const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
bool ordered) {
- return RTNAME(ReduceInteger8)(
+ return RTNAME(ReduceInteger8Ref)(
array, operation, source, line, dim, mask, identity, ordered) != 0;
}
-void RTDEF(ReduceLogical8Dim)(Descriptor &result, const Descriptor &array,
- ReductionOperation<std::int64_t> operation, const char *source, int line,
- int dim, const Descriptor *mask, const std::int64_t *identity,
+bool RTDEF(ReduceLogical8Value)(const Descriptor &array,
+ ValueReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
+ bool ordered) {
+ return RTNAME(ReduceInteger8Value)(
+ array, operation, source, line, dim, mask, identity, ordered) != 0;
+}
+void RTDEF(ReduceLogical8DimRef)(Descriptor &result, const Descriptor &array,
+ ReferenceReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
+ bool ordered) {
+ RTNAME(ReduceInteger8DimRef)
+ (result, array, operation, source, line, dim, mask, identity, ordered);
+}
+void RTDEF(ReduceLogical8DimValue)(Descriptor &result, const Descriptor &array,
+ ValueReductionOperation<std::int64_t> operation, const char *source,
+ int line, int dim, const Descriptor *mask, const std::int64_t *identity,
bool ordered) {
- RTNAME(ReduceInteger8Dim)
+ RTNAME(ReduceInteger8DimValue)
(result, array, operation, source, line, dim, mask, identity, ordered);
}
diff --git a/flang/runtime/unit.h b/flang/runtime/unit.h
index abd535fd0381..83f839e205a4 100644
--- a/flang/runtime/unit.h
+++ b/flang/runtime/unit.h
@@ -134,7 +134,7 @@ public:
RT_API_ATTRS bool OpenUnit(Fortran::common::optional<OpenStatus>,
Fortran::common::optional<Action>, Position, OwningPtr<char> &&path,
std::size_t pathLength, Convert, IoErrorHandler &);
- RT_API_ATTRS void OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
+ RT_API_ATTRS bool OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
Fortran::common::optional<Action>, Position, Convert, IoErrorHandler &);
RT_API_ATTRS void CloseUnit(CloseStatus, IoErrorHandler &);
RT_API_ATTRS void DestroyClosed();
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir
index df24a6d32aa5..ae53113f15d3 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir
@@ -1,5 +1,6 @@
-// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' 2>&1 | FileCheck %s
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file 2>&1 | FileCheck %s
+// -----
// module m
// type t
@@ -57,3 +58,54 @@ func.func @_QMmPfoo(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir
hlfir.assign %15 to %3#0 : i32, !fir.ref<i32>
return
}
+
+// -----
+
+// Same test as above focusing on aliasing between x%next and y%next data
+// CHECK-LABEL: Testing : "_QMmPfoo2"
+// CHECK-DAG: xnext#0 <-> ynext#0: MayAlias
+
+func.func @_QMmPfoo2(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "y"}) {
+ %4:2 = hlfir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)
+ %5:2 = hlfir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)
+ %6 = hlfir.designate %4#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
+ %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
+ %8 = fir.box_addr %7 {test.ptr = "xnext"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>
+
+ %9 = hlfir.designate %5#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
+ %10 = fir.load %9 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
+ %11 = fir.box_addr %10 {test.ptr = "ynext"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>
+ return
+}
+
+// -----
+
+// module m
+// type ta
+// integer, pointer :: array(:)
+// end type
+// contains
+// subroutine foo3(x, y)
+// type(t) :: x, y
+// x%array(1) = y%array(1)
+// end subroutine
+// end module
+
+// CHECK-LABEL: Testing : "_QMmPfoo3"
+// CHECK-DAG: yarray#0 <-> xarray#0: MayAlias
+
+func.func @_QMmPfoo3(%arg0: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "y"}) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>)
+ %1:2 = hlfir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>)
+ %2 = hlfir.designate %1#0{"array"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %3 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %c1 = arith.constant 1 : index
+ %4 = hlfir.designate %3 (%c1) {test.ptr = "yarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+ %5 = fir.load %4 : !fir.ref<i32>
+ %6 = hlfir.designate %0#0{"array"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+ %c1_0 = arith.constant 1 : index
+ %8 = hlfir.designate %7 (%c1_0) {test.ptr = "xarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+ hlfir.assign %5 to %8 : i32, !fir.ref<i32>
+ return
+}
diff --git a/flang/test/Driver/Inputs/libfun.f90 b/flang/test/Driver/Inputs/libfun.f90
new file mode 100644
index 000000000000..1df7b61e8bc8
--- /dev/null
+++ b/flang/test/Driver/Inputs/libfun.f90
@@ -0,0 +1,4 @@
+subroutine libfun(x)
+ integer :: x
+end subroutine
+
diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
index c94b98c7c580..5520d750e2ce 100644
--- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -50,12 +50,16 @@ end program
! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
! CHECK-NEXT: 'fir.global' Pipeline
+! CHECK-NEXT: StackReclaim
! CHECK-NEXT: CFGConversion
! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT: StackReclaim
! CHECK-NEXT: CFGConversion
! CHECK-NEXT: 'omp.declare_reduction' Pipeline
+! CHECK-NEXT: StackReclaim
! CHECK-NEXT: CFGConversion
! CHECK-NEXT: 'omp.private' Pipeline
+! CHECK-NEXT: StackReclaim
! CHECK-NEXT: CFGConversion
! CHECK-NEXT: SCFToControlFlow
diff --git a/flang/test/Driver/mlink-builtin-bc.f90 b/flang/test/Driver/mlink-builtin-bc.f90
new file mode 100644
index 000000000000..e245c1493bbc
--- /dev/null
+++ b/flang/test/Driver/mlink-builtin-bc.f90
@@ -0,0 +1,15 @@
+! Test -mlink-builtin-bitcode flag
+! RUN: %flang -emit-llvm -c -o %t.bc %S/Inputs/libfun.f90
+! RUN: %flang_fc1 -emit-llvm -o - -mlink-builtin-bitcode %t.bc %s 2>&1 | FileCheck %s
+
+! CHECK: define internal void @libfun_
+
+! RUN: not %flang_fc1 -emit-llvm -o - -mlink-builtin-bitcode %no-%t.bc %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+! ERROR: error: could not open {{.*}}.bc
+
+external libfun
+parameter(i=1)
+integer :: j
+call libfun(j)
+end program
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
index 49b1f8c5c313..6e9846fa422e 100644
--- a/flang/test/Driver/mlir-debug-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -77,12 +77,16 @@ end program
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
! ALL-NEXT: 'fir.global' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'omp.declare_reduction' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'omp.private' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: SCFToControlFlow
! ALL-NEXT: Canonicalizer
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index 8e1a3d43edd1..db4551e93fe6 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -85,12 +85,16 @@ end program
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
! ALL-NEXT: 'fir.global' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'omp.declare_reduction' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: 'omp.private' Pipeline
+! ALL-NEXT: StackReclaim
! ALL-NEXT: CFGConversion
! ALL-NEXT: SCFToControlFlow
diff --git a/flang/test/Driver/mllvm_vs_mmlir.f90 b/flang/test/Driver/mllvm_vs_mmlir.f90
index 99c3418dc6a1..074843fe9936 100644
--- a/flang/test/Driver/mllvm_vs_mmlir.f90
+++ b/flang/test/Driver/mllvm_vs_mmlir.f90
@@ -1,6 +1,6 @@
! Verify that `-mllvm` options are forwarded to LLVM and `-mmlir` to MLIR.
-! In practice, '-mmlir --help' is a super-set of '-mllvm --help' and that limits what we can test here. With a better seperation of
+! In practice, '-mmlir --help' is a super-set of '-mllvm --help' and that limits what we can test here. With a better separation of
! LLVM, MLIR and Flang global options, we should be able to write a stricter test.
! RUN: %flang_fc1 -mmlir --help | FileCheck %s --check-prefix=MLIR
diff --git a/flang/test/Driver/print-resource-dir.F90 b/flang/test/Driver/print-resource-dir.F90
deleted file mode 100644
index 8fd35f1800df..000000000000
--- a/flang/test/Driver/print-resource-dir.F90
+++ /dev/null
@@ -1,4 +0,0 @@
-! DEFINE: %{resource_dir} = %S/Inputs/resource_dir
-! RUN: %flang -print-resource-dir -resource-dir=%{resource_dir}.. \
-! RUN: | FileCheck -check-prefix=PRINT-RESOURCE-DIR -DFILE=%{resource_dir} %s
-! PRINT-RESOURCE-DIR: [[FILE]]
diff --git a/flang/test/Driver/target-cpu-features.f90 b/flang/test/Driver/target-cpu-features.f90
index 68f1403f96d0..eea7a0f665b3 100644
--- a/flang/test/Driver/target-cpu-features.f90
+++ b/flang/test/Driver/target-cpu-features.f90
@@ -31,11 +31,11 @@
! CHECK-A57: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
! CHECK-A57-SAME: "-target-cpu" "cortex-a57"
-! CHECK-A57-SAME: "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+sha2" "-target-feature" "+neon"
+! CHECK-A57-SAME: "-target-feature" "+v8a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+fp-armv8" "-target-feature" "+perfmon" "-target-feature" "+sha2" "-target-feature" "+neon"
! CHECK-A76: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
! CHECK-A76-SAME: "-target-cpu" "cortex-a76"
-! CHECK-A76-SAME: "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+ssbs"
+! CHECK-A76-SAME: "-target-feature" "+v8.2a" "-target-feature" "+aes" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+perfmon" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sha2" "-target-feature" "+neon" "-target-feature" "+ssbs"
! CHECK-ARMV9: "-fc1" "-triple" "aarch64-unknown-linux-gnu"
! CHECK-ARMV9-SAME: "-target-cpu" "generic"
diff --git a/flang/test/Evaluate/fold-ieee.f90 b/flang/test/Evaluate/fold-ieee.f90
new file mode 100644
index 000000000000..536db6481e67
--- /dev/null
+++ b/flang/test/Evaluate/fold-ieee.f90
@@ -0,0 +1,64 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+module m
+ use ieee_arithmetic
+ use ieee_exceptions
+ logical, parameter :: test_dt_all = ieee_support_datatype()
+ logical, parameter :: test_dt_4 = ieee_support_datatype(1.)
+ logical, parameter :: test_dt_8 = ieee_support_datatype(1.d0)
+ logical, parameter :: test_de_all = ieee_support_denormal()
+ logical, parameter :: test_de_4 = ieee_support_denormal(1.)
+ logical, parameter :: test_de_8 = ieee_support_denormal(1.d0)
+ logical, parameter :: test_di_all = ieee_support_divide()
+ logical, parameter :: test_di_4 = ieee_support_divide(1.)
+ logical, parameter :: test_di_8 = ieee_support_divide(1.d0)
+ logical, parameter :: test_fl_in_all = ieee_support_flag(ieee_invalid)
+ logical, parameter :: test_fl_in_4 = ieee_support_flag(ieee_invalid, 1.)
+ logical, parameter :: test_fl_in_8 = ieee_support_flag(ieee_invalid, 1.d0)
+ logical, parameter :: test_fl_ov_all = ieee_support_flag(ieee_overflow)
+ logical, parameter :: test_fl_ov_4 = ieee_support_flag(ieee_overflow, 1.)
+ logical, parameter :: test_fl_ov_8 = ieee_support_flag(ieee_overflow, 1.d0)
+ logical, parameter :: test_fl_d0_all = ieee_support_flag(ieee_divide_by_zero)
+ logical, parameter :: test_fl_d0_4 = ieee_support_flag(ieee_divide_by_zero, 1.)
+ logical, parameter :: test_fl_d0_8 = ieee_support_flag(ieee_divide_by_zero, 1.d0)
+ logical, parameter :: test_fl_un_all = ieee_support_flag(ieee_underflow)
+ logical, parameter :: test_fl_un_4 = ieee_support_flag(ieee_underflow, 1.)
+ logical, parameter :: test_fl_un_8 = ieee_support_flag(ieee_underflow, 1.d0)
+ logical, parameter :: test_fl_ix_all = ieee_support_flag(ieee_inexact)
+ logical, parameter :: test_fl_ix_4 = ieee_support_flag(ieee_inexact, 1.)
+ logical, parameter :: test_fl_ix_8 = ieee_support_flag(ieee_inexact, 1.d0)
+ logical, parameter :: test_halt_in = ieee_support_halting(ieee_invalid)
+ logical, parameter :: test_halt_ov = ieee_support_halting(ieee_overflow)
+ logical, parameter :: test_halt_d0 = ieee_support_halting(ieee_divide_by_zero)
+ logical, parameter :: test_halt_un = ieee_support_halting(ieee_underflow)
+ logical, parameter :: test_halt_ix = ieee_support_halting(ieee_inexact)
+ logical, parameter :: test_inf_all = ieee_support_inf()
+ logical, parameter :: test_inf_4 = ieee_support_inf(1.)
+ logical, parameter :: test_inf_8 = ieee_support_inf(1.d0)
+ logical, parameter :: test_io_all = ieee_support_io()
+ logical, parameter :: test_io_4 = ieee_support_io(1.)
+ logical, parameter :: test_io_8 = ieee_support_io(1.d0)
+ logical, parameter :: test_rd_0_all = ieee_support_rounding(ieee_to_zero)
+ logical, parameter :: test_rd_0_4 = ieee_support_rounding(ieee_to_zero, 1.)
+ logical, parameter :: test_rd_0_8 = ieee_support_rounding(ieee_to_zero, 1.d0)
+ logical, parameter :: test_rd_n_all = ieee_support_rounding(ieee_nearest)
+ logical, parameter :: test_rd_n_4 = ieee_support_rounding(ieee_nearest, 1.)
+ logical, parameter :: test_rd_n_8 = ieee_support_rounding(ieee_nearest, 1.d0)
+ logical, parameter :: test_rd_d_all = ieee_support_rounding(ieee_down)
+ logical, parameter :: test_rd_d_4 = ieee_support_rounding(ieee_down, 1.)
+ logical, parameter :: test_rd_d_8 = ieee_support_rounding(ieee_down, 1.d0)
+ logical, parameter :: test_rd_u_all = ieee_support_rounding(ieee_up)
+ logical, parameter :: test_rd_u_4 = ieee_support_rounding(ieee_up, 1.)
+ logical, parameter :: test_rd_u_8 = ieee_support_rounding(ieee_up, 1.d0)
+ logical, parameter :: test_sq_all = ieee_support_sqrt()
+ logical, parameter :: test_sq_4 = ieee_support_sqrt(1.)
+ logical, parameter :: test_sq_8 = ieee_support_sqrt(1.d0)
+ logical, parameter :: test_std_all = ieee_support_standard()
+ logical, parameter :: test_std_4 = ieee_support_standard(1.)
+ logical, parameter :: test_std_8 = ieee_support_standard(1.d0)
+ logical, parameter :: test_sn_all = ieee_support_subnormal()
+ logical, parameter :: test_sn_4 = ieee_support_subnormal(1.)
+ logical, parameter :: test_sn_8 = ieee_support_subnormal(1.d0)
+ logical, parameter :: test_uc_all = ieee_support_underflow_control()
+ logical, parameter :: test_uc_4 = ieee_support_underflow_control(1.)
+ logical, parameter :: test_uc_8 = ieee_support_underflow_control(1.d0)
+end
diff --git a/flang/test/Evaluate/fold-nearest.f90 b/flang/test/Evaluate/fold-nearest.f90
index bd8b020c392a..a7366e6d7540 100644
--- a/flang/test/Evaluate/fold-nearest.f90
+++ b/flang/test/Evaluate/fold-nearest.f90
@@ -28,6 +28,12 @@ module m1
logical, parameter :: test_15 = nearest(negZero, 0.) == minSubnormal
logical, parameter :: test_16 = nearest(tiny(1.),-1.) == 1.1754942E-38
logical, parameter :: test_17 = nearest(tiny(1.),1.) == 1.1754945E-38
+ contains
+ subroutine subr(a)
+ real, intent(in) :: a
+ !WARN: warning: NEAREST: S argument is zero
+ print *, nearest(a, 0.)
+ end
end module
module m2
diff --git a/flang/test/Evaluate/folding04.f90 b/flang/test/Evaluate/folding04.f90
index 86ae8debd6ef..c7815b034036 100644
--- a/flang/test/Evaluate/folding04.f90
+++ b/flang/test/Evaluate/folding04.f90
@@ -32,11 +32,22 @@ module real_tests
!WARN: warning: invalid argument on evaluation of intrinsic function or operation
real(4), parameter :: nan_r4_acos5 = acos(r4_pinf)
TEST_ISNAN(nan_r4_acos5)
- !WARN: warning: second argument to MOD must not be zero
+ !WARN: warning: MOD: P argument is zero
real(4), parameter :: nan_r4_mod = mod(3.5, 0.)
TEST_ISNAN(nan_r4_mod)
!WARN: warning: overflow on evaluation of intrinsic function or operation
logical, parameter :: test_exp_overflow = exp(256._4).EQ.r4_pinf
+ contains
+ subroutine s1(a,j)
+ !WARN: warning: MOD: P argument is zero
+ print *, mod(a, 0.)
+ !WARN: warning: MODULO: P argument is zero
+ print *, modulo(a, 0.)
+ !WARN: warning: MOD: P argument is zero
+ print *, mod(j, 0.)
+ !WARN: warning: MODULO: P argument is zero
+ print *, modulo(j, 0.)
+ end
end module
module parentheses
diff --git a/flang/test/Evaluate/rewrite06.f90 b/flang/test/Evaluate/rewrite06.f90
index 03eb463fe9bd..f27e6256556a 100644
--- a/flang/test/Evaluate/rewrite06.f90
+++ b/flang/test/Evaluate/rewrite06.f90
@@ -31,3 +31,9 @@ contains
print *, storage_size(return_pdt(k))
end subroutine
end module
+
+subroutine test_assumed_rank(x)
+ real :: x(..)
+ !CHECK: PRINT *, sizeof(x)
+ print *, sizeof(x)
+end subroutine
diff --git a/flang/test/Fir/alloc.fir b/flang/test/Fir/alloc.fir
index ca624c0d1f9d..e00fc9d6649c 100644
--- a/flang/test/Fir/alloc.fir
+++ b/flang/test/Fir/alloc.fir
@@ -156,7 +156,7 @@ func.func @allocmem_array_of_dynchar(%l: i32) -> !fir.heap<!fir.array<3x3x!fir.c
// CHECK-LABEL: define ptr @alloca_dynarray_of_nonchar(
// CHECK-SAME: i64 %[[extent:.*]])
-// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1
// CHECK: alloca [3 x i32], i64 %[[prod1]]
func.func @alloca_dynarray_of_nonchar(%e: index) -> !fir.ref<!fir.array<3x?xi32>> {
%1 = fir.alloca !fir.array<3x?xi32>, %e
@@ -165,7 +165,7 @@ func.func @alloca_dynarray_of_nonchar(%e: index) -> !fir.ref<!fir.array<3x?xi32>
// CHECK-LABEL: define ptr @alloca_dynarray_of_nonchar2(
// CHECK-SAME: i64 %[[extent:.*]])
-// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1
// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
// CHECK: alloca i32, i64 %[[prod2]]
func.func @alloca_dynarray_of_nonchar2(%e: index) -> !fir.ref<!fir.array<?x?xi32>> {
@@ -194,7 +194,7 @@ func.func @allocmem_dynarray_of_nonchar2(%e: index) -> !fir.heap<!fir.array<?x?x
// CHECK-LABEL: define ptr @alloca_dynarray_of_char(
// CHECK-SAME: i64 %[[extent:.*]])
-// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1
// CHECK: alloca [3 x [10 x i16]], i64 %[[prod1]]
func.func @alloca_dynarray_of_char(%e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,10>>> {
%1 = fir.alloca !fir.array<3x?x!fir.char<2,10>>, %e
@@ -203,7 +203,7 @@ func.func @alloca_dynarray_of_char(%e : index) -> !fir.ref<!fir.array<3x?x!fir.c
// CHECK-LABEL: define ptr @alloca_dynarray_of_char2(
// CHECK-SAME: i64 %[[extent:.*]])
-// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
+// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1
// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
// CHECK: alloca [10 x i16], i64 %[[prod2]]
func.func @alloca_dynarray_of_char2(%e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,10>>> {
@@ -334,10 +334,10 @@ func.func @allocmem_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir
}
// CHECK-LABEL: define void @alloca_unlimited_polymorphic_box
-// CHECK: %[[VAL_0:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1
// CHECK: %[[VAL_1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, i64 1
-// CHECK: %[[VAL_2:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1
+// CHECK: %[[VAL_0:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1
// CHECK: %[[VAL_3:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, i64 1
+// CHECK: %[[VAL_2:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1
func.func @alloca_unlimited_polymorphic_box() {
%0 = fir.alloca !fir.class<none>
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index dd184d99cb80..7bbfd709b0aa 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -85,12 +85,16 @@ func.func @_QQmain() {
// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
// PASSES-NEXT: 'fir.global' Pipeline
+// PASSES-NEXT: StackReclaim
// PASSES-NEXT: CFGConversion
// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT: StackReclaim
// PASSES-NEXT: CFGConversion
// PASSES-NEXT: 'omp.declare_reduction' Pipeline
+// PASSES-NEXT: StackReclaim
// PASSES-NEXT: CFGConversion
// PASSES-NEXT: 'omp.private' Pipeline
+// PASSES-NEXT: StackReclaim
// PASSES-NEXT: CFGConversion
// PASSES-NEXT: SCFToControlFlow
diff --git a/flang/test/Fir/boxproc.fir b/flang/test/Fir/boxproc.fir
index 1fed16a808af..9e4ea0bc2107 100644
--- a/flang/test/Fir/boxproc.fir
+++ b/flang/test/Fir/boxproc.fir
@@ -1,12 +1,12 @@
// RUN: tco %s | FileCheck %s
// CHECK-LABEL: define void @_QPtest_proc_dummy()
-// CHECK: %[[VAL_0:.*]] = alloca i32, i64 1, align 4
+// CHECK: %[[VAL_3:.*]] = alloca [32 x i8], i64 1, align 1
// CHECK: %[[VAL_1:.*]] = alloca { ptr }, i64 1, align 8
+// CHECK: %[[VAL_0:.*]] = alloca i32, i64 1, align 4
// CHECK: %[[VAL_2:.*]] = getelementptr { ptr }, ptr %[[VAL_1]], i32 0, i32 0
// CHECK: store ptr %[[VAL_0]], ptr %[[VAL_2]], align 8
// CHECK: store i32 1, ptr %[[VAL_0]], align 4
-// CHECK: %[[VAL_3:.*]] = alloca [32 x i8], i64 1, align 1
// CHECK: call void @llvm.init.trampoline(ptr %[[VAL_3]], ptr @_QFtest_proc_dummyPtest_proc_dummy_a, ptr %[[VAL_1]])
// CHECK: %[[VAL_6:.*]] = call ptr @llvm.adjust.trampoline(ptr %[[VAL_3]])
// CHECK: call void @_QPtest_proc_dummy_other(ptr %[[VAL_6]])
@@ -16,9 +16,7 @@
// CHECK-LABEL: define void @_QPtest_proc_dummy_other(ptr
// CHECK-SAME: %[[VAL_0:.*]])
-// CHECK: %[[VAL_1:.*]] = alloca i32, i64 1, align 4
-// CHECK: store i32 4, ptr %[[VAL_1]], align 4
-// CHECK: call void %[[VAL_0]](ptr %[[VAL_1]])
+// CHECK: call void %[[VAL_0]](ptr %{{.*}})
func.func @_QPtest_proc_dummy() {
%c0_i32 = arith.constant 0 : i32
@@ -61,9 +59,10 @@ func.func @_QPtest_proc_dummy_other(%arg0: !fir.boxproc<() -> ()>) {
}
// CHECK-LABEL: define void @_QPtest_proc_dummy_char()
-// CHECK: %[[VAL_0:.*]] = alloca [40 x i8], i64 1, align 1
-// CHECK: %[[VAL_1:.*]] = alloca [10 x i8], i64 1, align 1
+// CHECK: %[[VAL_20:.*]] = alloca [32 x i8], i64 1, align 1
// CHECK: %[[VAL_2:.*]] = alloca { { ptr, i64 } }, i64 1, align 8
+// CHECK: %[[VAL_1:.*]] = alloca [10 x i8], i64 1, align 1
+// CHECK: %[[VAL_0:.*]] = alloca [40 x i8], i64 1, align 1
// CHECK: %[[VAL_3:.*]] = getelementptr { { ptr, i64 } }, ptr %[[VAL_2]], i32 0, i32 0
// CHECK: %[[VAL_5:.*]] = insertvalue { ptr, i64 } undef, ptr %[[VAL_1]], 0
// CHECK: %[[VAL_6:.*]] = insertvalue { ptr, i64 } %[[VAL_5]], i64 10, 1
@@ -75,7 +74,6 @@ func.func @_QPtest_proc_dummy_other(%arg0: !fir.boxproc<() -> ()>) {
// CHECK: %[[VAL_15:.*]] = icmp sgt i64 %[[VAL_13]], 0
// CHECK: %[[VAL_18:.*]] = getelementptr [10 x [1 x i8]], ptr %[[VAL_1]], i32 0, i64 %[[VAL_11]]
// CHECK: store [1 x i8] c" ", ptr %[[VAL_18]], align 1
-// CHECK: %[[VAL_20:.*]] = alloca [32 x i8], i64 1, align 1
// CHECK: call void @llvm.init.trampoline(ptr %[[VAL_20]], ptr @_QFtest_proc_dummy_charPgen_message, ptr %[[VAL_2]])
// CHECK: %[[VAL_23:.*]] = call ptr @llvm.adjust.trampoline(ptr %[[VAL_20]])
// CHECK: %[[VAL_25:.*]] = insertvalue { ptr, i64 } undef, ptr %[[VAL_23]], 0
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index 72cd0a763e71..8b62787bb309 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -26,6 +26,7 @@ func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!
// CHECK-LABEL: _QPsb1
// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) {
+// CHECK: %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: omp.parallel {
@@ -207,6 +208,7 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK-LABEL: _QPsimd1
// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) {
+// CHECK: %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: omp.parallel {
@@ -280,58 +282,58 @@ func.func @_QPomp_target_data() {
return
}
- // CHECK-LABEL: llvm.func @_QPomp_target_data() {
- // CHECK: %0 = llvm.mlir.constant(1024 : index) : i64
- // CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
- // CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
- // CHECK: %3 = llvm.mlir.constant(1024 : index) : i64
- // CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64
- // CHECK: %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x !llvm.array<1024 x i32> {bindc_name = "b"} : (i64) -> !llvm.ptr
- // CHECK: %6 = llvm.mlir.constant(1024 : index) : i64
- // CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i64) : i64
- // CHECK: %[[VAL_5:.*]] = llvm.alloca %[[VAL_4]] x !llvm.array<1024 x i32> {bindc_name = "c"} : (i64) -> !llvm.ptr
- // CHECK: %9 = llvm.mlir.constant(1024 : index) : i64
- // CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i64
- // CHECK: %[[VAL_7:.*]] = llvm.alloca %[[VAL_6]] x !llvm.array<1024 x i32> {bindc_name = "d"} : (i64) -> !llvm.ptr
- // CHECK: %12 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %13 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %14 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %15 = omp.map.bounds lower_bound(%13 : i64) upper_bound(%14 : i64) extent(%0 : i64) stride(%12 : i64) start_idx(%12 : i64)
- // CHECK: %16 = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%15) -> !llvm.ptr {name = "a"}
- // CHECK: %17 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %18 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %19 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %20 = omp.map.bounds lower_bound(%18 : i64) upper_bound(%19 : i64) extent(%3 : i64) stride(%17 : i64) start_idx(%17 : i64)
- // CHECK: %21 = omp.map.info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%20) -> !llvm.ptr {name = "b"}
- // CHECK: %22 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %23 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %24 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %25 = omp.map.bounds lower_bound(%23 : i64) upper_bound(%24 : i64) extent(%6 : i64) stride(%22 : i64) start_idx(%22 : i64)
- // CHECK: %26 = omp.map.info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%25) -> !llvm.ptr {name = "c"}
- // CHECK: omp.target_enter_data map_entries(%16, %21, %26 : !llvm.ptr, !llvm.ptr, !llvm.ptr)
- // CHECK: %27 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %28 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %29 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %30 = omp.map.bounds lower_bound(%28 : i64) upper_bound(%29 : i64) extent(%0 : i64) stride(%27 : i64) start_idx(%27 : i64)
- // CHECK: %31 = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%30) -> !llvm.ptr {name = "a"}
- // CHECK: %32 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %33 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %34 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %35 = omp.map.bounds lower_bound(%33 : i64) upper_bound(%34 : i64) extent(%3 : i64) stride(%32 : i64) start_idx(%32 : i64)
- // CHECK: %36 = omp.map.info var_ptr(%[[VAL_3]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%35) -> !llvm.ptr {name = "b"}
- // CHECK: %37 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %38 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %39 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %40 = omp.map.bounds lower_bound(%38 : i64) upper_bound(%39 : i64) extent(%6 : i64) stride(%37 : i64) start_idx(%37 : i64)
- // CHECK: %41 = omp.map.info var_ptr(%[[VAL_5]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%40) -> !llvm.ptr {name = "c"}
- // CHECK: %42 = llvm.mlir.constant(1 : index) : i64
- // CHECK: %43 = llvm.mlir.constant(0 : index) : i64
- // CHECK: %44 = llvm.mlir.constant(1023 : index) : i64
- // CHECK: %45 = omp.map.bounds lower_bound(%43 : i64) upper_bound(%44 : i64) extent(%9 : i64) stride(%42 : i64) start_idx(%42 : i64)
- // CHECK: %46 = omp.map.info var_ptr(%[[VAL_7]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%45) -> !llvm.ptr {name = "d"}
- // CHECK: omp.target_exit_data map_entries(%31, %36, %41, %46 : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr)
- // CHECK: llvm.return
- // CHECK: }
+// CHECK-LABEL: llvm.func @_QPomp_target_data() {
+// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[VAL_2:.*]] = llvm.alloca %[[VAL_1]] x !llvm.array<1024 x i32> {bindc_name = "d"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[VAL_4:.*]] = llvm.alloca %[[VAL_3]] x !llvm.array<1024 x i32> {bindc_name = "c"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[VAL_6:.*]] = llvm.alloca %[[VAL_5]] x !llvm.array<1024 x i32> {bindc_name = "b"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[VAL_8:.*]] = llvm.alloca %[[VAL_7]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1024 : index) : i64
+// CHECK: %[[VAL_9:.*]] = llvm.mlir.constant(1024 : index) : i64
+// CHECK: %[[VAL_10:.*]] = llvm.mlir.constant(1024 : index) : i64
+// CHECK: %[[VAL_11:.*]] = llvm.mlir.constant(1024 : index) : i64
+// CHECK: %[[VAL_12:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_13:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_14:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_15:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : i64) upper_bound(%[[VAL_14]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_12]] : i64) start_idx(%[[VAL_12]] : i64)
+// CHECK: %[[VAL_16:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_15]]) -> !llvm.ptr {name = "a"}
+// CHECK: %[[VAL_17:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_18:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_19:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_20:.*]] = omp.map.bounds lower_bound(%[[VAL_18]] : i64) upper_bound(%[[VAL_19]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_17]] : i64) start_idx(%[[VAL_17]] : i64)
+// CHECK: %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_20]]) -> !llvm.ptr {name = "b"}
+// CHECK: %[[VAL_22:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_23:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_24:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_25:.*]] = omp.map.bounds lower_bound(%[[VAL_23]] : i64) upper_bound(%[[VAL_24]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_22]] : i64) start_idx(%[[VAL_22]] : i64)
+// CHECK: %[[VAL_26:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_25]]) -> !llvm.ptr {name = "c"}
+// CHECK: omp.target_enter_data map_entries(%[[VAL_16]], %[[VAL_21]], %[[VAL_26]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)
+// CHECK: %[[VAL_27:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_29:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_30:.*]] = omp.map.bounds lower_bound(%[[VAL_28]] : i64) upper_bound(%[[VAL_29]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_27]] : i64) start_idx(%[[VAL_27]] : i64)
+// CHECK: %[[VAL_31:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_30]]) -> !llvm.ptr {name = "a"}
+// CHECK: %[[VAL_32:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_33:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_34:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_35:.*]] = omp.map.bounds lower_bound(%[[VAL_33]] : i64) upper_bound(%[[VAL_34]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_32]] : i64) start_idx(%[[VAL_32]] : i64)
+// CHECK: %[[VAL_36:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_35]]) -> !llvm.ptr {name = "b"}
+// CHECK: %[[VAL_37:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_38:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_39:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_40:.*]] = omp.map.bounds lower_bound(%[[VAL_38]] : i64) upper_bound(%[[VAL_39]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_37]] : i64) start_idx(%[[VAL_37]] : i64)
+// CHECK: %[[VAL_41:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_40]]) -> !llvm.ptr {name = "c"}
+// CHECK: %[[VAL_42:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[VAL_43:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[VAL_44:.*]] = llvm.mlir.constant(1023 : index) : i64
+// CHECK: %[[VAL_45:.*]] = omp.map.bounds lower_bound(%[[VAL_43]] : i64) upper_bound(%[[VAL_44]] : i64) extent(%[[VAL_11]] : i64) stride(%[[VAL_42]] : i64) start_idx(%[[VAL_42]] : i64)
+// CHECK: %[[VAL_46:.*]] = omp.map.info var_ptr(%[[VAL_2]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%[[VAL_45]]) -> !llvm.ptr {name = "d"}
+// CHECK: omp.target_exit_data map_entries(%[[VAL_31]], %[[VAL_36]], %[[VAL_41]], %[[VAL_46]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr)
+// CHECK: llvm.return
+// CHECK: }
// -----
@@ -373,10 +375,10 @@ func.func @_QPopenmp_target_data_region() {
}
// CHECK-LABEL: llvm.func @_QPopenmp_target_data_region() {
-// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
// CHECK: %[[VAL_MAX:.*]] = llvm.mlir.constant(1024 : index) : i64
// CHECK: %[[VAL_ONE:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[VAL_ZERO:.*]] = llvm.mlir.constant(0 : index) : i64
@@ -459,15 +461,15 @@ func.func @_QPomp_target() {
}
// CHECK-LABEL: llvm.func @_QPomp_target() {
-// CHECK: %[[EXTENT:.*]] = llvm.mlir.constant(512 : index) : i64
// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<512 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
+// CHECK: %[[EXTENT:.*]] = llvm.mlir.constant(512 : index) : i64
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(64 : i32) : i32
// CHECK: %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[LOWER:.*]] = llvm.mlir.constant(0 : index) : i64
// CHECK: %[[UPPER:.*]] = llvm.mlir.constant(511 : index) : i64
// CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LOWER]] : i64) upper_bound(%[[UPPER]] : i64) extent(%[[EXTENT]] : i64) stride(%[[STRIDE]] : i64) start_idx(%[[STRIDE]] : i64)
-// CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%2 : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"}
+// CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<512 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"}
// CHECK: omp.target thread_limit(%[[VAL_2]] : i32) map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !llvm.ptr) {
// CHECK: ^bb0(%[[ARG_0]]: !llvm.ptr):
// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(10 : i32) : i32
@@ -675,9 +677,9 @@ func.func @_QPsb() {
}
// CHECK: llvm.func @_QPsb() {
-// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[LI_REF:.*]] = llvm.alloca %6 x i32 {bindc_name = "li"} : (i64) -> !llvm.ptr
+// CHECK: %[[LI_REF:.*]] = llvm.alloca %[[SIZE]] x i32 {bindc_name = "li"} : (i64) -> !llvm.ptr
+// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: omp.sections {
// CHECK: omp.section {
// CHECK: llvm.br ^[[BB_ENTRY:.*]]({{.*}})
@@ -715,7 +717,8 @@ func.func @_QPsb() {
// CHECK: }
// CHECK-LABEL: @_QPsimple_reduction
// CHECK-SAME: %[[ARRAY_REF:.*]]: !llvm.ptr
-// CHECK: %[[RED_ACCUMULATOR:.*]] = llvm.alloca %2 x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
+// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[RED_ACCUMULATOR:.*]] = llvm.alloca %[[VAL_1]] x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
// CHECK: omp.parallel {
// CHECK: omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) {
// CHECK-NEXT: omp.loop_nest
@@ -797,6 +800,7 @@ func.func @_QPs(%arg0: !fir.ref<!fir.complex<4>> {fir.bindc_name = "x"}) {
// Test if llvm.alloca is properly inserted in the omp section
+//CHECK: %[[CONST0:.*]] = llvm.mlir.constant(1 : i64) : i64
//CHECK: %[[CONST:.*]] = llvm.mlir.constant(1 : i64) : i64
//CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[CONST]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {bindc_name = "iattr"} : (i64) -> !llvm.ptr
//CHECK: omp.parallel {
@@ -907,9 +911,9 @@ omp.critical.declare @help hint(contended)
// CHECK: llvm.func @omp_critical_() {
func.func @omp_critical_() {
-// CHECK: %[[X_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
- %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_criticalEx"}
// CHECK: %[[Y_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "y"} : (i64) -> !llvm.ptr
+ %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_criticalEx"}
+// CHECK: %[[X_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
%1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"}
// CHECK: omp.critical(@help)
omp.critical(@help) {
@@ -1002,3 +1006,77 @@ func.func @omp_map_info_nested_derived_type_explicit_member_conversion(%arg0 : !
}
// -----
+
+// CHECK-LABEL: llvm.func @omp_map_common_block_using_common_block_symbol
+
+// CHECK: %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr
+// CHECK: %[[CB_MAP:.*]] = omp.map.info var_ptr(%[[ADDR_OF]] : !llvm.ptr, !llvm.array<8 x i8>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var_common"}
+// CHECK: omp.target map_entries(%[[CB_MAP]] -> %[[ARG0:.*]] : !llvm.ptr) {
+// CHECK: ^bb0(%[[ARG0]]: !llvm.ptr):
+// CHECK: %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64
+// CHECK: %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+
+func.func @omp_map_common_block_using_common_block_symbol() {
+ %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
+ %1 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<8xi8>>, !fir.array<8xi8>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.array<8xi8>> {name = "var_common"}
+ omp.target map_entries(%1 -> %arg0 : !fir.ref<!fir.array<8xi8>>) {
+ ^bb0(%arg0: !fir.ref<!fir.array<8xi8>>):
+ %c4 = arith.constant 4 : index
+ %c0 = arith.constant 0 : index
+ %c20_i32 = arith.constant 20 : i32
+ %2 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+ %3 = fir.coordinate_of %2, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+ %4 = fir.convert %3 : (!fir.ref<i8>) -> !fir.ref<i32>
+ %5 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+ %6 = fir.coordinate_of %5, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+ %7 = fir.convert %6 : (!fir.ref<i8>) -> !fir.ref<i32>
+ %8 = fir.load %4 : !fir.ref<i32>
+ %9 = arith.addi %8, %c20_i32 : i32
+ fir.store %9 to %7 : !fir.ref<i32>
+ omp.terminator
+ }
+ return
+}
+
+fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
+
+// -----
+
+// CHECK-LABEL: llvm.func @omp_map_common_block_using_common_block_members
+
+// CHECK: %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64
+// CHECK: %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr
+// CHECK: %[[VAR_1_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %[[VAR_2_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %[[MAP_CB_VAR_1:.*]] = omp.map.info var_ptr(%[[VAR_1_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var1"}
+// CHECK: %[[MAP_CB_VAR_2:.*]] = omp.map.info var_ptr(%[[VAR_2_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var2"}
+// CHECK: omp.target map_entries(%[[MAP_CB_VAR_1]] -> %[[ARG0:.*]], %[[MAP_CB_VAR_2]] -> %[[ARG1:.*]] : !llvm.ptr, !llvm.ptr) {
+// CHECK: ^bb0(%[[ARG0]]: !llvm.ptr, %[[ARG1]]: !llvm.ptr):
+
+func.func @omp_map_common_block_using_common_block_members() {
+ %c4 = arith.constant 4 : index
+ %c0 = arith.constant 0 : index
+ %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
+ %1 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+ %2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+ %3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32>
+ %4 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+ %5 = fir.coordinate_of %4, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+ %6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<i32>
+ %7 = omp.map.info var_ptr(%3 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var1"}
+ %8 = omp.map.info var_ptr(%6 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var2"}
+ omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !fir.ref<i32>, !fir.ref<i32>) {
+ ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>):
+ %c10_i32 = arith.constant 10 : i32
+ %9 = fir.load %arg0 : !fir.ref<i32>
+ %10 = arith.muli %9, %c10_i32 : i32
+ fir.store %10 to %arg1 : !fir.ref<i32>
+ omp.terminator
+ }
+ return
+}
+
+fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index ee116e998c22..c7f3160328f7 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -895,6 +895,25 @@ func.func @store_unlimited_polymorphic_box(%arg0 : !fir.class<none>, %arg1 : !fi
// -----
+func.func @store_assumed_rank_box(%box: !fir.box<!fir.array<*:f32>>, %ref: !fir.ref<!fir.box<!fir.array<*:f32>>>) {
+ fir.store %box to %ref : !fir.ref<!fir.box<!fir.array<*:f32>>>
+ return
+}
+
+// CHECK-LABEL: llvm.func @store_assumed_rank_box(
+// CHECK-SAME: %[[VAL_0:[^:]*]]: !llvm.ptr,
+// CHECK-SAME: %[[VAL_1:.*]]: !llvm.ptr) {
+// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(24 : i32) : i32
+// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)>
+// CHECK: %[[VAL_4:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i8
+// CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i8 to i32
+// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(24 : i32) : i32
+// CHECK: %[[VAL_7:.*]] = llvm.mul %[[VAL_6]], %[[VAL_5]] : i32
+// CHECK: %[[VAL_8:.*]] = llvm.add %[[VAL_2]], %[[VAL_7]] : i32
+// CHECK: "llvm.intr.memcpy"(%[[VAL_1]], %[[VAL_0]], %[[VAL_8]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
+
+// -----
+
// Test `fir.load` --> `llvm.load` conversion
func.func @test_load_index(%addr : !fir.ref<index>) {
@@ -1178,7 +1197,7 @@ func.func @alloca_fixed_char_array(%e : index) -> !fir.ref<!fir.array<?x?x!fir.c
// CHECK-LABEL: llvm.func @alloca_fixed_char_array
// CHECK-SAME: ([[E:%.*]]: i64) -> !llvm.ptr
// CHECK-DAG: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: [[PROD1:%.*]] = llvm.mul [[ONE]], [[E]] : i64
+// CHECK: [[PROD1:%.*]] = llvm.mul [[E]], [[ONE]] : i64
// CHECK: [[PROD2:%.*]] = llvm.mul [[PROD1]], [[E]] : i64
// GENERIC: [[A:%.*]] = llvm.alloca [[PROD2]] x !llvm.array<8 x i8>
// AMDGPU: [[AA:%.*]] = llvm.alloca [[PROD2]] x !llvm.array<8 x i8> : (i64) -> !llvm.ptr<5>
@@ -1225,7 +1244,7 @@ func.func @alloca_multidim_array(%0 : index) -> !fir.ref<!fir.array<8x16x32xf32>
// CHECK-SAME: ([[OP1:%.*]]: i64) -> !llvm.ptr
// CHECK: [[OP2:%.*]] = llvm.mlir.constant(24 : index) : i64
// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: [[MUL1:%.*]] = llvm.mul [[ONE]], [[OP1]] : i64
+// CHECK: [[MUL1:%.*]] = llvm.mul [[OP1]], [[ONE]] : i64
// CHECK: [[TOTAL:%.*]] = llvm.mul [[MUL1]], [[OP2]] : i64
// GENERIC: [[A:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<32 x array<16 x array<8 x f32>>>
// AMDGPU: [[AA:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<32 x array<16 x array<8 x f32>>> : (i64) -> !llvm.ptr<5>
@@ -1246,7 +1265,7 @@ func.func @alloca_const_interior_array(%0 : index) -> !fir.ref<!fir.array<8x9x?x
// CHECK-SAME: ([[OP1:%.*]]: i64) -> !llvm.ptr
// CHECK: [[OP2:%.*]] = llvm.mlir.constant(64 : index) : i64
// CHECK: [[ONE:%.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: [[MUL1:%.*]] = llvm.mul [[ONE]], [[OP1]] : i64
+// CHECK: [[MUL1:%.*]] = llvm.mul [[OP1]], [[ONE]] : i64
// CHECK: [[TOTAL:%.*]] = llvm.mul [[MUL1]], [[OP2]] : i64
// GENERIC: [[A:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<9 x array<8 x f32>>
// AMDGPU: [[AA:%.*]] = llvm.alloca [[TOTAL]] x !llvm.array<9 x array<8 x f32>> : (i64) -> !llvm.ptr<5>
@@ -1277,6 +1296,20 @@ func.func @alloca_array_with_holes(%0 : index, %1 : index) -> !fir.ref<!fir.arra
// -----
+// Test alloca of assumed-rank box
+
+func.func @alloca_assumed_rank_box() -> !fir.ref<!fir.box<!fir.array<*:f32>>> {
+ %a = fir.alloca !fir.box<!fir.array<*:f32>>
+ return %a : !fir.ref<!fir.box<!fir.array<*:f32>>>
+}
+// CHECK-LABEL: llvm.func @alloca_assumed_rank_box
+// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
+// GENERIC: llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> : (i64) -> !llvm.ptr
+// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ONE]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)> : (i64) -> !llvm.ptr<5>
+// AMDGPU: llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr
+
+// -----
+
// Test `fir.select_case` operation conversion with INTEGER.
func.func @select_case_integer(%arg0: !fir.ref<i32>) -> i32 {
@@ -1937,7 +1970,7 @@ func.func private @_QPxb(!fir.box<!fir.array<?x?xf64>>)
// CHECK: %[[N2_TMP:.*]] = llvm.sub %[[N]], %[[SH2]] : i64
// CHECK: %[[N2:.*]] = llvm.add %[[N2_TMP]], %[[C1]] : i64
// CHECK: %[[C1_0:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ARR_SIZE_TMP1:.*]] = llvm.mul %[[C1_0]], %[[N1]] : i64
+// CHECK: %[[ARR_SIZE_TMP1:.*]] = llvm.mul %[[N1]], %[[C1_0]] : i64
// CHECK: %[[ARR_SIZE:.*]] = llvm.mul %[[ARR_SIZE_TMP1]], %[[N2]] : i64
// GENERIC: %[[ARR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr"} : (i64) -> !llvm.ptr
// AMDGPU: %[[AR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr"} : (i64) -> !llvm.ptr<5>
@@ -2014,18 +2047,18 @@ func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)
// GENERIC: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
// AMDGPU: %[[AA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>
// AMDGPU: %[[ALLOCA:.*]] = llvm.addrspacecast %[[AA]] : !llvm.ptr<5> to !llvm.ptr
-// CHECK: %[[C20:.*]] = llvm.mlir.constant(20 : index) : i64
-// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[C10:.*]] = llvm.mlir.constant(10 : i64) : i64
-// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : i64) : i64
-// CHECK: %[[ALLOCA_SIZE_V:.*]] = llvm.mlir.constant(1 : i64) : i64
-// GENERIC: %[[V:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr
-// AMDGPU: %[[AB:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr<5>
-// AMDGPU: %[[V:.*]] = llvm.addrspacecast %[[AB]] : !llvm.ptr<5> to !llvm.ptr
// CHECK: %[[ALLOCA_SIZE_X:.*]] = llvm.mlir.constant(1 : i64) : i64
// GENERIC: %[[X:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x"} : (i64) -> !llvm.ptr
// AMDGPU: %[[AC:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x"} : (i64) -> !llvm.ptr<5>
// AMDGPU: %[[X:.*]] = llvm.addrspacecast %[[AC]] : !llvm.ptr<5> to !llvm.ptr
+// CHECK: %[[ALLOCA_SIZE_V:.*]] = llvm.mlir.constant(1 : i64) : i64
+// GENERIC: %[[V:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr
+// AMDGPU: %[[AB:.*]] = llvm.alloca %[[ALLOCA_SIZE_V]] x i32 {bindc_name = "v"} : (i64) -> !llvm.ptr<5>
+// AMDGPU: %[[V:.*]] = llvm.addrspacecast %[[AB]] : !llvm.ptr<5> to !llvm.ptr
+// CHECK: %[[C20:.*]] = llvm.mlir.constant(20 : index) : i64
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK: %[[C10:.*]] = llvm.mlir.constant(10 : i64) : i64
+// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : i64) : i64
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i32
// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
diff --git a/flang/test/Fir/rebox_assumed_rank_codegen.fir b/flang/test/Fir/rebox_assumed_rank_codegen.fir
index 6f9cd6edda31..3c4de0bef509 100644
--- a/flang/test/Fir/rebox_assumed_rank_codegen.fir
+++ b/flang/test/Fir/rebox_assumed_rank_codegen.fir
@@ -34,10 +34,18 @@ func.func @test_new_dtype(%arg0: !fir.box<!fir.array<*:!t2>> ) {
return
}
+!sometype = !fir.type<sometype{i:i32}>
+func.func @test_poly_to_nonepoly(%arg0: !fir.class<!fir.array<*:!sometype>>) {
+ %1 = fir.rebox_assumed_rank %arg0 lbs ones : (!fir.class<!fir.array<*:!sometype>>) -> !fir.box<!fir.array<*:!sometype>>
+ fir.call @takes_assumed_rank_t(%1) : (!fir.box<!fir.array<*:!sometype>>) -> ()
+ return
+}
+
func.func private @somefunc(!fir.box<!fir.array<*:f32>>)
func.func private @somefuncalloc(!fir.box<!fir.heap<!fir.array<*:f32>>>)
func.func private @somefuncpointer(!fir.box<!fir.ptr<!fir.array<*:f32>>>)
func.func private @somefunct1(!fir.box<!fir.array<*:!t1>>)
+func.func private @takes_assumed_rank_t(!fir.box<!fir.array<*:!sometype>>)
// CHECK-LABEL: func.func @test_simple(
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>>) {
@@ -108,4 +116,9 @@ func.func private @somefunct1(!fir.box<!fir.array<*:!t1>>)
// CHECK: return
// CHECK: }
+// CHECK-LABEL: func.func @test_poly_to_nonepoly(
+// CHECK: %[[VAL_4:.*]] = fir.type_desc !fir.type<sometype{i:i32}>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]] : (!fir.tdesc<!fir.type<sometype{i:i32}>>) -> !fir.ref<none>
+// CHECK: %[[VAL_8:.*]] = fir.call @_FortranACopyAndUpdateDescriptor(%{{.*}}, %{{.*}}, %[[VAL_7]],
+
// CHECK: func.func private @_FortranACopyAndUpdateDescriptor(!fir.ref<!fir.box<none>> {llvm.nocapture}, !fir.box<none> {llvm.nocapture}, !fir.ref<none>, i8, i32) -> none attributes {fir.runtime}
diff --git a/flang/test/Fir/tbaa.fir b/flang/test/Fir/tbaa.fir
index 5800e608da41..89679afc386c 100644
--- a/flang/test/Fir/tbaa.fir
+++ b/flang/test/Fir/tbaa.fir
@@ -407,3 +407,22 @@ func.func private @some_assumed_rank_func(!fir.box<!fir.array<*:f64>>) -> ()
// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_3]], %[[VAL_8]] : i32
// CHECK: "llvm.intr.memcpy"(%[[VAL_2]], %[[VAL_0]], %[[VAL_9]]) <{isVolatile = false, tbaa = [#[[$BOXT]]]}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
// CHECK: llvm.call @some_assumed_rank_func(%[[VAL_2]]) : (!llvm.ptr) -> ()
+
+// -----
+
+func.func @store_assumed_rank_box(%box: !fir.box<!fir.array<*:f32>>, %ref: !fir.ref<!fir.box<!fir.array<*:f32>>>) {
+ fir.store %box to %ref : !fir.ref<!fir.box<!fir.array<*:f32>>>
+ return
+}
+
+// CHECK-DAG: #[[ROOT:.*]] = #llvm.tbaa_root<id = "Flang function root ">
+// CHECK-DAG: #[[ANYACC:.*]] = #llvm.tbaa_type_desc<id = "any access", members = {<#[[ROOT]], 0>}>
+// CHECK-DAG: #[[BOXMEM:.*]] = #llvm.tbaa_type_desc<id = "descriptor member", members = {<#[[ANYACC]], 0>}>
+// CHECK-DAG: #[[$BOXT:.*]] = #llvm.tbaa_tag<base_type = #[[BOXMEM]], access_type = #[[BOXMEM]], offset = 0>
+
+// CHECK-LABEL: llvm.func @store_assumed_rank_box(
+// CHECK-SAME: %[[VAL_0:[^:]*]]: !llvm.ptr,
+// CHECK-SAME: %[[VAL_1:.*]]: !llvm.ptr) {
+// CHECK: %[[VAL_3:.*]] = llvm.getelementptr %[[VAL_0]][0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<15 x array<3 x i64>>)>
+// CHECK: %[[VAL_4:.*]] = llvm.load %[[VAL_3]] {tbaa = [#[[$BOXT]]]} : !llvm.ptr -> i8
+// CHECK: "llvm.intr.memcpy"(%[[VAL_1]], %[[VAL_0]], %{{.*}}) <{isVolatile = false, tbaa = [#[[$BOXT]]]}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
diff --git a/flang/test/Fir/vector-always-cfg.fir b/flang/test/Fir/vector-always-cfg.fir
new file mode 100644
index 000000000000..45c2ea056a70
--- /dev/null
+++ b/flang/test/Fir/vector-always-cfg.fir
@@ -0,0 +1,32 @@
+// RUN: fir-opt --fir-to-llvm-ir %s | FileCheck %s
+
+#access_group = #llvm.access_group<id = distinct[0]<>>
+// CHECK: #[[ACCESS:.*]] = #llvm.access_group<id = distinct[0]<>>
+#loop_vectorize = #llvm.loop_vectorize<disable = false>
+// CHECK: #[[VECTORIZE:.*]] = #llvm.loop_vectorize<disable = false>
+#loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize, parallelAccesses = #access_group>
+// CHECK: #[[ANNOTATION:.*]] = #llvm.loop_annotation<vectorize = #[[VECTORIZE]], parallelAccesses = #[[ACCESS]]>
+
+func.func @_QPvector_always() -> i32 {
+ %c1 = arith.constant 1 : index
+ %c10_i32 = arith.constant 10 : i32
+ %c1_i32 = arith.constant 1 : i32
+ %c10 = arith.constant 10 : index
+ %0 = arith.subi %c10, %c1 : index
+ %1 = arith.addi %0, %c1 : index
+ %2 = arith.divsi %1, %c1 : index
+ cf.br ^bb1(%c1, %c1_i32, %2 : index, i32, index)
+^bb1(%3: index, %4: i32, %5: index): // 2 preds: ^bb0, ^bb2
+ %c0 = arith.constant 0 : index
+ %6 = arith.cmpi sgt, %5, %c0 : index
+ cf.cond_br %6, ^bb2, ^bb3 {loop_annotation = #loop_annotation}
+// CHECK: llvm.cond_br %{{.*}}, ^{{.*}}, ^{{.*}} {loop_annotation = #[[ANNOTATION]]}
+^bb2: // pred: ^bb1
+ %7 = arith.addi %3, %c1 : index
+ %c1_0 = arith.constant 1 : index
+ %8 = arith.subi %5, %c1_0 : index
+ cf.br ^bb1(%7, %c1_i32, %8 : index, i32, index)
+^bb3: // pred: ^bb1
+ return %4 : i32
+}
+
diff --git a/flang/test/Fir/vector-always.fir b/flang/test/Fir/vector-always.fir
new file mode 100644
index 000000000000..00eb0e7a756e
--- /dev/null
+++ b/flang/test/Fir/vector-always.fir
@@ -0,0 +1,21 @@
+// RUN: fir-opt --cfg-conversion %s | FileCheck %s
+
+#access_group = #llvm.access_group<id = distinct[0]<>>
+// CHECK: #[[ACCESS:.*]] = #llvm.access_group<id = distinct[0]<>>
+#loop_vectorize = #llvm.loop_vectorize<disable = false>
+// CHECK: #[[VECTORIZE:.*]] = #llvm.loop_vectorize<disable = false>
+#loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize, parallelAccesses = #access_group>
+// CHECK: #[[ANNOTATION:.*]] = #llvm.loop_annotation<vectorize = #[[VECTORIZE]], parallelAccesses = #[[ACCESS]]>
+
+// CHECK-LABEL: @_QPvector_always
+func.func @_QPvector_always() -> i32 {
+ %c1 = arith.constant 1 : index
+ %c10_i32 = arith.constant 10 : i32
+ %c1_i32 = arith.constant 1 : i32
+ %c10 = arith.constant 10 : index
+// CHECK: cf.cond_br %{{.*}}, ^{{.*}}, ^{{.*}} {loop_annotation = #[[ANNOTATION]]}
+ %8:2 = fir.do_loop %arg0 = %c1 to %c10 step %c1 iter_args(%arg1 = %c1_i32) -> (index, i32) attributes {loopAnnotation = #loop_annotation} {
+ fir.result %c1, %c1_i32 : index, i32
+ }
+ return %8#1 : i32
+ }
diff --git a/flang/test/HLFIR/assumed-type-actual-args.f90 b/flang/test/HLFIR/assumed-type-actual-args.f90
index 7ce1067d7acd..855542709f62 100644
--- a/flang/test/HLFIR/assumed-type-actual-args.f90
+++ b/flang/test/HLFIR/assumed-type-actual-args.f90
@@ -132,10 +132,10 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.call @_QPs4(%[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }
@@ -144,18 +144,17 @@ end subroutine
! CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest3bEx"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
-! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
-! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
-! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: %[[VAL_3:.*]]:3 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>) -> (!fir.box<!fir.array<?xnone>>, i1)
+! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
-! CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_7:.*]] = arith.constant false
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
-! CHECK: fir.result %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: fir.result %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: fir.call @_QPs3b(%[[VAL_9:.*]]#0) fastmath<contract> : (!fir.box<!fir.array<?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_9]]#1, %[[VAL_9]]#2 to %[[VAL_9]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_9]]#1 to %[[VAL_9]]#2 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }
@@ -164,19 +163,18 @@ end subroutine
! CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest4bEx"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
-! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
-! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
+! CHECK: %[[VAL_3:.*]]:3 = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>) -> (!fir.box<!fir.array<?xnone>>, i1)
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.ref<!fir.array<?xnone>>
-! CHECK: fir.result %[[VAL_5]], %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: fir.result %[[VAL_5]], %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.ref<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
-! CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<!fir.array<?xnone>>
-! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
+! CHECK: %[[VAL_7:.*]] = fir.absent !fir.ref<!fir.array<?xnone>>
! CHECK: %[[VAL_8:.*]] = arith.constant false
! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
-! CHECK: fir.result %[[VAL_6]], %[[VAL_7]], %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: fir.result %[[VAL_7]], %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: fir.call @_QPs4b(%[[VAL_10:.*]]#0) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_10]]#1, %[[VAL_10]]#2 to %[[VAL_10]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_10]]#1 to %[[VAL_10]]#2 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }
@@ -219,18 +217,17 @@ end subroutine
! CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest5bEx"} : (!fir.box<!fir.array<?xnone>>, !fir.dscope) -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> i1
-! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
-! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xnone>>) -> (!fir.box<!fir.array<?xnone>>, i1)
-! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: %[[VAL_3:.*]]:3 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) {
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>) -> (!fir.box<!fir.array<?xnone>>, i1)
+! CHECK: fir.result %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: } else {
-! CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_6:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
! CHECK: %[[VAL_7:.*]] = arith.constant false
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<?xnone>>
-! CHECK: fir.result %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
+! CHECK: fir.result %[[VAL_6]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>
! CHECK: }
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_10:.*]]#0 : (!fir.box<!fir.array<?xnone>>) -> !fir.box<!fir.array<*:none>>
! CHECK: fir.call @_QPs5b(%[[VAL_9]]) fastmath<contract> : (!fir.box<!fir.array<*:none>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_10]]#1, %[[VAL_10]]#2 to %[[VAL_10]]#3 : (!fir.box<!fir.array<?xnone>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_10]]#1 to %[[VAL_10]]#2 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xnone>>>>, i1, !fir.box<!fir.array<?xnone>>) -> ()
! CHECK: return
! CHECK: }
diff --git a/flang/test/HLFIR/assumed_shape_with_value_keyword.f90 b/flang/test/HLFIR/assumed_shape_with_value_keyword.f90
index da3dff16382c..197efc08422c 100644
--- a/flang/test/HLFIR/assumed_shape_with_value_keyword.f90
+++ b/flang/test/HLFIR/assumed_shape_with_value_keyword.f90
@@ -10,10 +10,10 @@ end
! CHECK-LABEL: func.func @_QPtest_integer_value1(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_integer_value1Ex"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.box<!fir.array<?xi32>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
! CHECK: fir.call @_QPinternal_call1(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?xi32>>, i1, !fir.box<!fir.array<?xi32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, i1, !fir.box<!fir.array<?xi32>>) -> ()
! CHECK: return
! CHECK: }
@@ -24,10 +24,10 @@ end
! CHECK-LABEL: func.func @_QPtest_integer_value2(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_integer_value2Ex"} : (!fir.box<!fir.array<?x?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xi32>>, !fir.box<!fir.array<?x?xi32>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xi32>>) -> (!fir.box<!fir.array<?x?xi32>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> (!fir.box<!fir.array<?x?xi32>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?xi32>>) -> !fir.ref<!fir.array<?x?xi32>>
! CHECK: fir.call @_QPinternal_call2(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?x?xi32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xi32>>, i1, !fir.box<!fir.array<?x?xi32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>, i1, !fir.box<!fir.array<?x?xi32>>) -> ()
! CHECK: return
! CHECK: }
@@ -38,10 +38,10 @@ end
! CHECK-LABEL: func.func @_QPtest_real_value1(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_real_value1Ex"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.box<!fir.array<?xf32>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
! CHECK: fir.call @_QPinternal_call3(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
! CHECK: return
! CHECK: }
@@ -52,10 +52,10 @@ end
! CHECK-LABEL: func.func @_QPtest_real_value2(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_real_value2Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xf32>>) -> (!fir.box<!fir.array<?x?xf32>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>) -> (!fir.box<!fir.array<?x?xf32>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
! CHECK: fir.call @_QPinternal_call4(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?x?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xf32>>, i1, !fir.box<!fir.array<?x?xf32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, i1, !fir.box<!fir.array<?x?xf32>>) -> ()
! CHECK: return
! CHECK: }
@@ -66,10 +66,10 @@ end
! CHECK-LABEL: func.func @_QPtest_complex_value1(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x!fir.complex<4>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_complex_value1Ex"} : (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.box<!fir.array<?x!fir.complex<4>>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.complex<4>>>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> !fir.ref<!fir.array<?x!fir.complex<4>>>
! CHECK: fir.call @_QPinternal_call5(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?x!fir.complex<4>>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?x!fir.complex<4>>>, i1, !fir.box<!fir.array<?x!fir.complex<4>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.complex<4>>>>>, i1, !fir.box<!fir.array<?x!fir.complex<4>>>) -> ()
! CHECK: return
! CHECK: }
@@ -80,10 +80,10 @@ end
! CHECK-LABEL: func.func @_QPtest_complex_value2(
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?x!fir.complex<4>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QFtest_complex_value2Ex"} : (!fir.box<!fir.array<?x?x!fir.complex<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x?x!fir.complex<4>>>, !fir.box<!fir.array<?x?x!fir.complex<4>>>)
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x?x!fir.complex<4>>>, i1)
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?x!fir.complex<4>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.complex<4>>>>>) -> (!fir.box<!fir.array<?x?x!fir.complex<4>>>, i1)
! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.complex<4>>>) -> !fir.ref<!fir.array<?x?x!fir.complex<4>>>
! CHECK: fir.call @_QPinternal_call6(%[[VAL_2]]) fastmath<contract> : (!fir.ref<!fir.array<?x?x!fir.complex<4>>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_1]]#0, %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?x!fir.complex<4>>>, i1, !fir.box<!fir.array<?x?x!fir.complex<4>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_1]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.complex<4>>>>>, i1, !fir.box<!fir.array<?x?x!fir.complex<4>>>) -> ()
! CHECK: return
! CHECK: }
@@ -98,10 +98,10 @@ end
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<optional, value>, uniq_name = "_QFtest_optional1Ex"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]]#1 : (!fir.box<!fir.array<?xf32>>) -> i1
! CHECK: fir.if %[[VAL_1:.*]] {
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.box<!fir.array<?xf32>>, i1)
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
! CHECK: fir.call @_QPinternal_call7(%[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.array<?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
! CHECK: } else {
! CHECK: }
! CHECK: return
@@ -118,10 +118,10 @@ end
! CHECK: %[[VAL_0:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<optional, value>, uniq_name = "_QFtest_optional2Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
! CHECK: %[[VAL_1:.*]] = fir.is_present %[[VAL_0]]#1 : (!fir.box<!fir.array<?x?xf32>>) -> i1
! CHECK: fir.if %[[VAL_1:.*]] {
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xf32>>) -> (!fir.box<!fir.array<?x?xf32>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_0]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>) -> (!fir.box<!fir.array<?x?xf32>>, i1)
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
! CHECK: fir.call @_QPinternal_call8(%[[VAL_3]]) fastmath<contract> : (!fir.ref<!fir.array<?x?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_0]]#0 : (!fir.box<!fir.array<?x?xf32>>, i1, !fir.box<!fir.array<?x?xf32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_0]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>, i1, !fir.box<!fir.array<?x?xf32>>) -> ()
! CHECK: } else {
! CHECK: }
! CHECK: return
diff --git a/flang/test/HLFIR/copy-in-out-codegen.fir b/flang/test/HLFIR/copy-in-out-codegen.fir
index c766c2e9fdc4..8031536550bd 100644
--- a/flang/test/HLFIR/copy-in-out-codegen.fir
+++ b/flang/test/HLFIR/copy-in-out-codegen.fir
@@ -2,133 +2,115 @@
// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
-func.func @test_copy_in(%box: !fir.box<!fir.array<?xf64>>) {
- %0:2 = hlfir.copy_in %box : (!fir.box<!fir.array<?xf64>>) -> (!fir.box<!fir.array<?xf64>>, i1)
+func.func @test_copy_in(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) {
+ %0:2 = hlfir.copy_in %box to %temp : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.box<!fir.array<?xf64>>, i1)
return
}
// CHECK-LABEL: func.func @test_copy_in(
-// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>) {
-// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf64>>>
-// CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_2]]) : (!fir.box<none>) -> i1
-// CHECK: %[[VAL_4:.*]] = fir.if %[[VAL_3]] -> (!fir.box<!fir.array<?xf64>>) {
-// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?xf64>>
-// CHECK: } else {
-// CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf64>>
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
-// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
-// CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.heap<!fir.array<?xf64>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf64>>>
-// CHECK: fir.store %[[VAL_8]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_15:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_12]], %[[VAL_13]],
-// CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-// CHECK: %[[VAL_17:.*]] = fir.rebox %[[VAL_16]] : (!fir.box<!fir.heap<!fir.array<?xf64>>>) -> !fir.box<!fir.array<?xf64>>
-// CHECK: fir.result %[[VAL_17]] : !fir.box<!fir.array<?xf64>>
-// CHECK: }
-// CHECK: %[[VAL_18:.*]] = arith.constant false
-// CHECK: %[[VAL_19:.*]] = arith.cmpi eq, %[[VAL_3]], %[[VAL_18]] : i1
-// CHECK: return
-// CHECK: }
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) {
+// CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
+// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_2]]) : (!fir.box<none>) -> i1
+// CHECK: %[[VAL_4:.*]] = fir.if %[[VAL_3]] -> (!fir.box<!fir.array<?xf64>>) {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?xf64>>
+// CHECK: } else {
+// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
+// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACopyInAssign(%[[VAL_8]], %[[VAL_9]],
+// CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+// CHECK: %[[VAL_13:.*]] = fir.rebox %[[VAL_12]] : (!fir.box<!fir.heap<!fir.array<?xf64>>>) -> !fir.box<!fir.array<?xf64>>
+// CHECK: fir.result %[[VAL_13]] : !fir.box<!fir.array<?xf64>>
+// CHECK: }
+// CHECK: %[[VAL_14:.*]] = arith.constant false
+// CHECK: %[[VAL_15:.*]] = arith.cmpi eq, %[[VAL_3]], %[[VAL_14]] : i1
+// CHECK: return
+// CHECK: }
-func.func @test_copy_in_optional(%box: !fir.box<!fir.array<?xf64>>, %is_present: i1) {
- %0:2 = hlfir.copy_in %box handle_optional %is_present : (!fir.box<!fir.array<?xf64>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
+func.func @test_copy_in_optional(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %is_present: i1) {
+ %0:2 = hlfir.copy_in %box to %temp handle_optional %is_present : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
return
}
// CHECK-LABEL: func.func @test_copy_in_optional(
-// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_1:.*]]: i1) {
-// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf64>>>
-// CHECK: %[[VAL_3:.*]]:2 = fir.if %[[VAL_1]] -> (!fir.box<!fir.array<?xf64>>, i1) {
-// CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) : (!fir.box<none>) -> i1
-// CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.box<!fir.array<?xf64>>) {
-// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?xf64>>
-// CHECK: } else {
-// CHECK: %[[VAL_7:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf64>>
-// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index
-// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1>
-// CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_7]](%[[VAL_9]]) : (!fir.heap<!fir.array<?xf64>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf64>>>
-// CHECK: fir.store %[[VAL_10]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_17:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_14]], %[[VAL_15]],
-// CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-// CHECK: %[[VAL_19:.*]] = fir.rebox %[[VAL_18]] : (!fir.box<!fir.heap<!fir.array<?xf64>>>) -> !fir.box<!fir.array<?xf64>>
-// CHECK: fir.result %[[VAL_19]] : !fir.box<!fir.array<?xf64>>
-// CHECK: }
-// CHECK: %[[VAL_20:.*]] = arith.constant false
-// CHECK: %[[VAL_21:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_20]] : i1
-// CHECK: fir.result %[[VAL_22:.*]], %[[VAL_21]] : !fir.box<!fir.array<?xf64>>, i1
-// CHECK: } else {
-// CHECK: %[[VAL_23:.*]] = fir.absent !fir.box<!fir.array<?xf64>>
-// CHECK: fir.result %[[VAL_23]], %[[VAL_1]] : !fir.box<!fir.array<?xf64>>, i1
-// CHECK: }
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>,
+// CHECK-SAME: %[[VAL_2:.*]]: i1) {
+// CHECK: %[[VAL_3:.*]]:2 = fir.if %[[VAL_2]] -> (!fir.box<!fir.array<?xf64>>, i1) {
+// CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
+// CHECK: %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) : (!fir.box<none>) -> i1
+// CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.box<!fir.array<?xf64>>) {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?xf64>>
+// CHECK: } else {
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
+// CHECK: %[[VAL_13:.*]] = fir.call @_FortranACopyInAssign(%[[VAL_10]], %[[VAL_11]],
+// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+// CHECK: %[[VAL_15:.*]] = fir.rebox %[[VAL_14]] : (!fir.box<!fir.heap<!fir.array<?xf64>>>) -> !fir.box<!fir.array<?xf64>>
+// CHECK: fir.result %[[VAL_15]] : !fir.box<!fir.array<?xf64>>
+// CHECK: }
+// CHECK: %[[VAL_16:.*]] = arith.constant false
+// CHECK: %[[VAL_17:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_16]] : i1
+// CHECK: fir.result %[[VAL_6]], %[[VAL_17]] : !fir.box<!fir.array<?xf64>>, i1
+// CHECK: } else {
+// CHECK: %[[VAL_18:.*]] = fir.absent !fir.box<!fir.array<?xf64>>
+// CHECK: fir.result %[[VAL_18]], %[[VAL_2]] : !fir.box<!fir.array<?xf64>>, i1
+// CHECK: }
+// CHECK: return
+// CHECK: }
-func.func @test_copy_out_no_copy_back(%temp: !fir.box<!fir.array<?xf64>>, %was_copied: i1) {
- hlfir.copy_out %temp, %was_copied : (!fir.box<!fir.array<?xf64>>, i1) -> ()
+func.func @test_copy_out_no_copy_back(%temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %was_copied: i1) {
+ hlfir.copy_out %temp, %was_copied : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> ()
return
}
// CHECK-LABEL: func.func @test_copy_out_no_copy_back(
-// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_1:.*]]: i1) {
-// CHECK-NEXT: fir.if %[[VAL_1]] {
-// CHECK-NEXT: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK-NEXT: %[[VAL_3:.*]] = fir.call @_FortranADestroyWithoutFinalization(%[[VAL_2]]) : (!fir.box<none>) -> none
-// CHECK-NEXT: %[[VAL_4:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
-// CHECK-NEXT: fir.freemem %[[VAL_4]] : !fir.heap<!fir.array<?xf64>>
-// CHECK-NEXT: }
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>,
+// CHECK-SAME: %[[VAL_1:.*]]: i1) {
+// CHECK: fir.if %[[VAL_1]] {
+// CHECK: %[[VAL_2:.*]] = fir.zero_bits !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+// CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_9:.*]] = fir.call @_FortranACopyOutAssign(%[[VAL_6]], %[[VAL_7]],
+// CHECK: }
+// CHECK: return
+// CHECK: }
-func.func @test_copy_out_copy_back(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.box<!fir.array<?xf64>>, %was_copied: i1) {
- hlfir.copy_out %temp, %was_copied to %box : (!fir.box<!fir.array<?xf64>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
+func.func @test_copy_out_copy_back(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %was_copied: i1) {
+ hlfir.copy_out %temp, %was_copied to %box : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
return
}
// CHECK-LABEL: func.func @test_copy_out_copy_back(
-// CHECK-SAME: %[[VAL_0:[^:]*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_2:.*]]: i1) {
-// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.array<?xf64>>
-// CHECK: fir.if %[[VAL_2]] {
-// CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.array<?xf64>>>
-// CHECK: %[[VAL_7:.*]] = arith.constant true
-// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.box<!fir.array<?xf64>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACopyOutAssign(%[[VAL_8]], %[[VAL_9]], %[[VAL_7]],
-// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
-// CHECK: %[[VAL_13:.*]] = fir.call @_FortranADestroyWithoutFinalization(%[[VAL_12]]) : (!fir.box<none>) -> none
-// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
-// CHECK: fir.freemem %[[VAL_14]] : !fir.heap<!fir.array<?xf64>>
-// CHECK: }
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>,
+// CHECK-SAME: %[[VAL_2:.*]]: i1) {
+// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.array<?xf64>>
+// CHECK: fir.if %[[VAL_2]] {
+// CHECK: fir.store %[[VAL_0]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.array<?xf64>>>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.box<!fir.array<?xf64>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_10:.*]] = fir.call @_FortranACopyOutAssign(%[[VAL_7]], %[[VAL_8]],
+// CHECK: }
+// CHECK: return
+// CHECK: }
-func.func @test_copy_in_poly(%poly : !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) {
- %0:2 = hlfir.copy_in %poly : (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) -> (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>, i1)
+func.func @test_copy_in_poly(%poly : !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>, %temp: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>) {
+ %0:2 = hlfir.copy_in %poly to %temp : (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>) -> (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>, i1)
return
}
// CHECK-LABEL: func.func @test_copy_in_poly(
-// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) {
-// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>) {
// CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) -> !fir.box<none>
// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_2]]) : (!fir.box<none>) -> i1
// CHECK: %[[VAL_4:.*]] = fir.if %[[VAL_3]] -> (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) {
// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
// CHECK: } else {
-// CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
-// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
-// CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>
-// CHECK: fir.store %[[VAL_8]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>
-// CHECK: %[[VAL_9:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-// CHECK: %[[VAL_10:.*]] = arith.constant {{.*}} : index
-// CHECK: %[[VAL_11:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) -> !fir.box<none>
-// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: %[[VAL_15:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_12]], %[[VAL_13]], %[[VAL_14]], %[[VAL_11]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
-// CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>
-// CHECK: %[[VAL_17:.*]] = fir.rebox %[[VAL_16]] : (!fir.box<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>) -> !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
-// CHECK: fir.result %[[VAL_17]] : !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
+// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>) -> !fir.box<none>
+// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACopyInAssign(%[[VAL_8]], %[[VAL_9]],
+// CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>>
+// CHECK: %[[VAL_13:.*]] = fir.rebox %[[VAL_12]] : (!fir.class<!fir.heap<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>>) -> !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
+// CHECK: fir.result %[[VAL_13]] : !fir.class<!fir.array<?x!fir.type<test_copy_in_polyTt1{i:i32}>>>
// CHECK: }
-// CHECK: %[[VAL_18:.*]] = arith.constant false
-// CHECK: %[[VAL_19:.*]] = arith.cmpi eq, %[[VAL_3]], %[[VAL_18]] : i1
+// CHECK: %[[VAL_14:.*]] = arith.constant false
+// CHECK: %[[VAL_15:.*]] = arith.cmpi eq, %[[VAL_3]], %[[VAL_14]] : i1
// CHECK: return
// CHECK: }
diff --git a/flang/test/HLFIR/copy-in-out.fir b/flang/test/HLFIR/copy-in-out.fir
index be24dcc975fe..2db0c89c7e44 100644
--- a/flang/test/HLFIR/copy-in-out.fir
+++ b/flang/test/HLFIR/copy-in-out.fir
@@ -3,25 +3,26 @@
// RUN: fir-opt %s | fir-opt | FileCheck %s
-func.func @test_copy_in(%box: !fir.box<!fir.array<?xf64>>, %is_present: i1) {
- %0:2 = hlfir.copy_in %box : (!fir.box<!fir.array<?xf64>>) -> (!fir.box<!fir.array<?xf64>>, i1)
- %1:2 = hlfir.copy_in %box handle_optional %is_present : (!fir.box<!fir.array<?xf64>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
+func.func @test_copy_in(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %is_present: i1) {
+ %0:2 = hlfir.copy_in %box to %temp : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.box<!fir.array<?xf64>>, i1)
+ %1:2 = hlfir.copy_in %box to %temp handle_optional %is_present : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
return
}
// CHECK-LABEL: func.func @test_copy_in(
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_1:.*]]: i1
-// CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> (!fir.box<!fir.array<?xf64>>, i1)
-// CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_0]] handle_optional %[[VAL_1]] : (!fir.box<!fir.array<?xf64>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>,
+// CHECK-SAME: %[[VAL_2:.*]]: i1
+// CHECK: hlfir.copy_in %[[VAL_0]] to %[[VAL_1]] : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.box<!fir.array<?xf64>>, i1)
+// CHECK: hlfir.copy_in %[[VAL_0]] to %[[VAL_1]] handle_optional %[[VAL_2]] : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> (!fir.box<!fir.array<?xf64>>, i1)
-func.func @test_copy_out(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.box<!fir.array<?xf64>>, %was_copied: i1) {
- hlfir.copy_out %temp, %was_copied : (!fir.box<!fir.array<?xf64>>, i1) -> ()
- hlfir.copy_out %temp, %was_copied to %box : (!fir.box<!fir.array<?xf64>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
+func.func @test_copy_out(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %was_copied: i1) {
+ hlfir.copy_out %temp, %was_copied : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> ()
+ hlfir.copy_out %temp, %was_copied to %box : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
return
}
// CHECK-LABEL: func.func @test_copy_out(
// CHECK-SAME: %[[VAL_0:[^:]*]]: !fir.box<!fir.array<?xf64>>,
-// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xf64>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>,
// CHECK-SAME: %[[VAL_2:.*]]: i1) {
-// CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_2]] : (!fir.box<!fir.array<?xf64>>, i1) -> ()
-// CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_2]] to %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
+// CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> ()
+// CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_2]] to %[[VAL_0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
diff --git a/flang/test/HLFIR/memory-effects.fir b/flang/test/HLFIR/memory-effects.fir
index 32d6b264d6c1..cac887ebe67d 100644
--- a/flang/test/HLFIR/memory-effects.fir
+++ b/flang/test/HLFIR/memory-effects.fir
@@ -3,214 +3,186 @@
func.func @concat(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<1, 20>>) {
// expected-remark@+1 {{operation has no memory effects}}
%c30 = arith.constant 30 : index
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.concat %arg0, %arg1 len %c30 : (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,20>>, index) -> (!hlfir.expr<!fir.char<1,30>>)
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @all_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
// expected-remark@+1 {{operation has no memory effects}}
%all = hlfir.all %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> !fir.logical<4>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @all_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%all = hlfir.all %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> !hlfir.expr<?x!fir.logical<4>>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @any_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
// expected-remark@+1 {{operation has no memory effects}}
%all = hlfir.any %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> !fir.logical<4>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @any_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%all = hlfir.any %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> !hlfir.expr<?x!fir.logical<4>>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @count_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
// expected-remark@+1 {{operation has no memory effects}}
%all = hlfir.count %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> i32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @count_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%all = hlfir.count %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> i32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @product_no_effects(%arg0: !hlfir.expr<?xf32>) {
// expected-remark@+1 {{operation has no memory effects}}
%product = hlfir.product %arg0 : (!hlfir.expr<?xf32>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @product_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%product = hlfir.product %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @set_length_read(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: index) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.set_length %arg0 len %arg1 : (!fir.ref<!fir.char<1,10>>, index) -> !hlfir.expr<!fir.char<1,?>>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @sum_no_effects(%arg0: !hlfir.expr<?xf32>) {
// expected-remark@+1 {{operation has no memory effects}}
%sum = hlfir.sum %arg0 : (!hlfir.expr<?xf32>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @sum_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%sum = hlfir.sum %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @maxval_no_effects(%arg0: !hlfir.expr<?xf32>) {
// expected-remark@+1 {{operation has no memory effects}}
%maxval = hlfir.maxval %arg0 : (!hlfir.expr<?xf32>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @maxval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%maxval = hlfir.maxval %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @minval_no_effects(%arg0: !hlfir.expr<?xf32>) {
// expected-remark@+1 {{operation has no memory effects}}
%minval = hlfir.minval %arg0 : (!hlfir.expr<?xf32>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @minval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%minval = hlfir.minval %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @minloc_effects_simple(%arg0: !hlfir.expr<?xf32>) {
-// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
%minloc = hlfir.minloc %arg0 : (!hlfir.expr<?xf32>) -> !hlfir.expr<?xi32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @minloc_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%minloc = hlfir.minloc %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xi32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @maxloc_effects_simple(%arg0: !hlfir.expr<?xf32>) {
-// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
%maxloc = hlfir.maxloc %arg0 : (!hlfir.expr<?xf32>) -> !hlfir.expr<?xi32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @maxloc_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xi32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @dot_product_no_effects(%arg0: !hlfir.expr<?xf32>, %arg1: !hlfir.expr<?xf32>) {
// expected-remark@+1 {{operation has no memory effects}}
%0 = hlfir.dot_product %arg0 %arg1 : (!hlfir.expr<?xf32>, !hlfir.expr<?xf32>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @dot_product_effects(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<!fir.array<10xf32>>) {
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.dot_product %arg0 %arg1 : (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) -> f32
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @matmul_no_reads(%arg0: !hlfir.expr<?x?xf32>, %arg1: !hlfir.expr<?x?xf32>) {
-// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
%0 = hlfir.matmul %arg0 %arg1 : (!hlfir.expr<?x?xf32>, !hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @matmul_reads(%arg0: !fir.ref<!fir.array<10x5xf32>>, %arg1: !fir.ref<!fir.array<5x10xf32>>) {
-// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.matmul %arg0 %arg1 : (!fir.ref<!fir.array<10x5xf32>>, !fir.ref<!fir.array<5x10xf32>>) -> !hlfir.expr<10x10xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @transpose_no_reads(%arg0: !hlfir.expr<?x?xf32>) {
-// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
%0 = hlfir.transpose %arg0 : (!hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @transpose_read(%arg0: !fir.ref<!fir.array<10x5xf32>>) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.transpose %arg0 : (!fir.ref<!fir.array<10x5xf32>>) -> !hlfir.expr<5x10xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @matmul_transpose_no_reads(%arg0: !hlfir.expr<?x?xf32>, %arg1: !hlfir.expr<?x?xf32>) {
-// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
%0 = hlfir.matmul_transpose %arg0 %arg1 : (!hlfir.expr<?x?xf32>, !hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @matmul_transpose_reads(%arg0: !fir.ref<!fir.array<5x10xf32>>, %arg1: !fir.ref<!fir.array<5x10xf32>>) {
-// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.matmul_transpose %arg0 %arg1 : (!fir.ref<!fir.array<5x10xf32>>, !fir.ref<!fir.array<5x10xf32>>) -> !hlfir.expr<10x10xf32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
@@ -219,45 +191,41 @@ func.func @associate(%arg0: i32) {
%0:3 = hlfir.associate %arg0 {uniq_name = "x"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
hlfir.end_associate %0#1, %0#2 : !fir.ref<i32>, i1
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @as_expr_read(%arg0: !fir.ref<!fir.array<2xi32>>) {
-// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.as_expr %arg0 : (!fir.ref<!fir.array<2xi32>>) -> !hlfir.expr<?xi32>
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
hlfir.destroy %0 : !hlfir.expr<?xi32>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
func.func @char_extremum(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<1,20>>) {
-// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
%0 = hlfir.char_extremum min, %arg0, %arg1 : (!fir.ref<!fir.char<1, 10>>, !fir.ref<!fir.char<1,20>>) -> !hlfir.expr<!fir.char<1,10>>
-// expected-remark@+1 {{operation has no memory effects}}
return
}
-func.func @copy_in(%box: !fir.box<!fir.array<?xf64>>, %is_present: i1) {
-// expected-remark@+2 {{found an instance of 'allocate' on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
- %0:2 = hlfir.copy_in %box : (!fir.box<!fir.array<?xf64>>) -> (!fir.box<!fir.array<?xf64>>, i1)
-// expected-remark@+1 {{operation has no memory effects}}
+func.func @copy_in(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %is_present: i1) {
+// expected-remark@+3 {{found an instance of 'allocate' on resource '<Default>'}}
+// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource '<Default>'}}
+ %0:2 = hlfir.copy_in %box to %temp : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.box<!fir.array<?xf64>>, i1)
return
}
-func.func @copy_out(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.box<!fir.array<?xf64>>, %was_copied: i1) {
+func.func @copy_out(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %was_copied: i1) {
// expected-remark@+2 {{found an instance of 'free' on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
- hlfir.copy_out %temp, %was_copied : (!fir.box<!fir.array<?xf64>>, i1) -> ()
+// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
+ hlfir.copy_out %temp, %was_copied : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> ()
// expected-remark@+3 {{found an instance of 'free' on resource '<Default>'}}
-// expected-remark@+2 {{found an instance of 'read' on a value, on resource '<Default>'}}
-// expected-remark@+1 {{found an instance of 'write' on a value, on resource '<Default>'}}
- hlfir.copy_out %temp, %was_copied to %box : (!fir.box<!fir.array<?xf64>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
-// expected-remark@+1 {{operation has no memory effects}}
+// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
+// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource '<Default>'}}
+ hlfir.copy_out %temp, %was_copied to %box : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
return
}
diff --git a/flang/test/Integration/OpenMP/copyprivate.f90 b/flang/test/Integration/OpenMP/copyprivate.f90
index d32319a18c28..dd69ebdb881a 100644
--- a/flang/test/Integration/OpenMP/copyprivate.f90
+++ b/flang/test/Integration/OpenMP/copyprivate.f90
@@ -33,8 +33,8 @@
!CHECK-NEXT: }
!CHECK-LABEL: define internal void @test_scalar_..omp_par({{.*}})
-!CHECK: %[[I:.*]] = alloca i32, i64 1
!CHECK: %[[J:.*]] = alloca i32, i64 1
+!CHECK: %[[I:.*]] = alloca i32, i64 1
!CHECK: %[[DID_IT:.*]] = alloca i32
!CHECK: store i32 0, ptr %[[DID_IT]]
!CHECK: %[[THREAD_NUM1:.*]] = call i32 @__kmpc_global_thread_num(ptr @[[LOC:.*]])
diff --git a/flang/test/Integration/OpenMP/map-types-and-sizes.f90 b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
index f3a20690f05a..591be0b680a5 100644
--- a/flang/test/Integration/OpenMP/map-types-and-sizes.f90
+++ b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
@@ -231,6 +231,31 @@ subroutine mapType_char
!$omp end target
end subroutine mapType_char
+!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [1 x i64] [i64 8]
+!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [1 x i64] [i64 35]
+subroutine mapType_common_block
+ implicit none
+ common /var_common/ var1, var2
+ integer :: var1, var2
+!$omp target map(tofrom: /var_common/)
+ var1 = var1 + 20
+ var2 = var2 + 30
+!$omp end target
+end subroutine mapType_common_block
+
+!CHECK: @.offload_sizes{{.*}} = private unnamed_addr constant [2 x i64] [i64 4, i64 4]
+!CHECK: @.offload_maptypes{{.*}} = private unnamed_addr constant [2 x i64] [i64 35, i64 35]
+subroutine mapType_common_block_members
+ implicit none
+ common /var_common/ var1, var2
+ integer :: var1, var2
+
+!$omp target map(tofrom: var1, var2)
+ var2 = var1
+!$omp end target
+end subroutine mapType_common_block_members
+
+
!CHECK-LABEL: define {{.*}} @{{.*}}maptype_ptr_explicit_{{.*}}
!CHECK: %[[ALLOCA:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }, i64 1, align 8
!CHECK: %[[ALLOCA_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8 }, ptr %[[ALLOCA]], i32 1
@@ -346,3 +371,19 @@ end subroutine mapType_char
!CHECK: store ptr %[[ALLOCA]], ptr %[[BASE_PTR_ARR]], align 8
!CHECK: %[[OFFLOAD_PTR_ARR:.*]] = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0
!CHECK: store ptr %[[ARR_OFF]], ptr %[[OFFLOAD_PTR_ARR]], align 8
+
+!CHECK-LABEL: define {{.*}} @{{.*}}maptype_common_block_{{.*}}
+!CHECK: %[[BASE_PTR_ARR:.*]] = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0
+!CHECK: store ptr @var_common_, ptr %[[BASE_PTR_ARR]], align 8
+!CHECK: %[[OFFLOAD_PTR_ARR:.*]] = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0
+!CHECK: store ptr @var_common_, ptr %[[OFFLOAD_PTR_ARR]], align 8
+
+!CHECK-LABEL: define {{.*}} @{{.*}}maptype_common_block_members_{{.*}}
+!CHECK: %[[BASE_PTR_ARR:.*]] = getelementptr inbounds [2 x ptr], ptr %.offload_baseptrs, i32 0, i32 0
+!CHECK: store ptr @var_common_, ptr %[[BASE_PTR_ARR]], align 8
+!CHECK: %[[OFFLOAD_PTR_ARR:.*]] = getelementptr inbounds [2 x ptr], ptr %.offload_ptrs, i32 0, i32 0
+!CHECK: store ptr @var_common_, ptr %[[OFFLOAD_PTR_ARR]], align 8
+!CHECK: %[[BASE_PTR_ARR_1:.*]] = getelementptr inbounds [2 x ptr], ptr %.offload_baseptrs, i32 0, i32 1
+!CHECK: store ptr getelementptr (i8, ptr @var_common_, i64 4), ptr %[[BASE_PTR_ARR_1]], align 8
+!CHECK: %[[OFFLOAD_PTR_ARR_1:.*]] = getelementptr inbounds [2 x ptr], ptr %.offload_ptrs, i32 0, i32 1
+!CHECK: store ptr getelementptr (i8, ptr @var_common_, i64 4), ptr %[[OFFLOAD_PTR_ARR_1]], align 8
diff --git a/flang/test/Integration/debug-allocatable-1.f90 b/flang/test/Integration/debug-allocatable-1.f90
new file mode 100644
index 000000000000..471c8cdb7d54
--- /dev/null
+++ b/flang/test/Integration/debug-allocatable-1.f90
@@ -0,0 +1,24 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+subroutine ff(n, m)
+ integer n, m, i, j
+ integer, allocatable :: ar1(:, :)
+ real, allocatable :: sc
+
+ allocate(ar1(n, m))
+ allocate(sc)
+ sc = 3.14
+
+ print *, sc
+ print *, ar1
+end subroutine ff
+
+
+! CHECK-DAG: !DILocalVariable(name: "ar1"{{.*}}type: ![[TY1:[0-9]+]])
+! CHECK-DAG: ![[TY1]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS2:[0-9]+]]{{.*}}dataLocation{{.*}}allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne))
+! CHECK-DAG: ![[ELEMS2]] = !{![[ELEM1:[0-9]+]], ![[ELEM2:[0-9]+]]}
+! CHECK-DAG: ![[ELEM1]] = !DISubrange
+! CHECK-DAG: ![[ELEM2]] = !DISubrange
+! CHECK-DAG: !DILocalVariable(name: "sc"{{.*}}type: ![[TY2:[0-9]+]])
+! CHECK-DAG: ![[TY2]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[TY3:[0-9]+]]{{.*}})
+! CHECK-DAG: ![[TY3]] = !DIBasicType(name: "real"{{.*}})
diff --git a/flang/test/Integration/debug-assumed-shape-array.f90 b/flang/test/Integration/debug-assumed-shape-array.f90
new file mode 100644
index 000000000000..7b0801c12dba
--- /dev/null
+++ b/flang/test/Integration/debug-assumed-shape-array.f90
@@ -0,0 +1,13 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+subroutine ff(arr)
+ implicit none
+ integer :: arr(:, :)
+ return arr(1,1)
+end subroutine ff
+
+! CHECK-DAG: !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS:[0-9]+]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
+! CHECK-DAG: ![[ELEMS]] = !{![[ELEM1:[0-9]+]], ![[ELEM2:[0-9]+]]}
+! CHECK-DAG: ![[ELEM1]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref))
+! CHECK-DAG: ![[ELEM2]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
+
diff --git a/flang/test/Integration/debug-char-type-1.f90 b/flang/test/Integration/debug-char-type-1.f90
new file mode 100644
index 000000000000..5068663aa9e2
--- /dev/null
+++ b/flang/test/Integration/debug-char-type-1.f90
@@ -0,0 +1,25 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+module helper
+ character(len=40) :: str
+ character(len=:), allocatable :: str2
+end module helper
+
+program test
+ use helper
+ character(kind=4, len=8) :: first
+ character(len=10) :: second
+ first = '3.14 = π'
+ second = 'Fortran'
+ str = 'Hello World!'
+ str2 = 'A quick brown fox jumps over a lazy dog'
+end program test
+
+! CHECK-DAG: !DIGlobalVariable(name: "str"{{.*}}type: ![[TY40:[0-9]+]]{{.*}})
+! CHECK-DAG: ![[TY40]] = !DIStringType(size: 320, encoding: DW_ATE_ASCII)
+! CHECK-DAG: !DIGlobalVariable(name: "str2"{{.*}}type: ![[TY:[0-9]+]]{{.*}})
+! CHECK-DAG: ![[TY]] = !DIStringType(stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), encoding: DW_ATE_ASCII)
+! CHECK-DAG: !DILocalVariable(name: "first"{{.*}}type: ![[TY8:[0-9]+]])
+! CHECK-DAG: ![[TY8]] = !DIStringType(size: 256, encoding: DW_ATE_UCS)
+! CHECK-DAG: !DILocalVariable(name: "second"{{.*}}type: ![[TY10:[0-9]+]])
+! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)
diff --git a/flang/test/Integration/debug-local-var-2.f90 b/flang/test/Integration/debug-local-var-2.f90
new file mode 100644
index 000000000000..79fe1bab6e35
--- /dev/null
+++ b/flang/test/Integration/debug-local-var-2.f90
@@ -0,0 +1,110 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -mllvm --write-experimental-debuginfo=false -o - | FileCheck %s --check-prefixes=BOTH,INTRINSICS
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -mllvm --write-experimental-debuginfo=true -o - | FileCheck %s --check-prefixes=BOTH,RECORDS
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=line-tables-only %s -mllvm --write-experimental-debuginfo=false -o - | FileCheck --check-prefix=LINEONLY %s
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=line-tables-only %s -mllvm --write-experimental-debuginfo=true -o - | FileCheck --check-prefix=LINEONLY %s
+
+! This tests checks the debug information for local variables in llvm IR.
+
+! BOTH-LABEL: define void @_QQmain
+! BOTH-DAG: %[[AL16:.*]] = alloca double
+! BOTH-DAG: %[[AL15:.*]] = alloca float
+! BOTH-DAG: %[[AL14:.*]] = alloca i32
+! BOTH-DAG: %[[AL13:.*]] = alloca i8
+! BOTH-DAG: %[[AL12:.*]] = alloca i64
+! BOTH-DAG: %[[AL11:.*]] = alloca i32
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL11]], metadata ![[I4:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL12]], metadata ![[I8:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL13]], metadata ![[L1:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL14]], metadata ![[L4:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL15]], metadata ![[R4:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL16]], metadata ![[R8:.*]], metadata !DIExpression())
+! RECORDS-DAG: #dbg_declare(ptr %[[AL11]], ![[I4:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[AL12]], ![[I8:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[AL13]], ![[L1:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[AL14]], ![[L4:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[AL15]], ![[R4:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[AL16]], ![[R8:.*]], !DIExpression(), !{{.*}})
+! BOTH-LABEL: }
+
+! BOTH-LABEL: define {{.*}}i64 @_QFPfn1
+! BOTH-SAME: (ptr %[[ARG1:.*]], ptr %[[ARG2:.*]], ptr %[[ARG3:.*]])
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[ARG1]], metadata ![[A1:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[ARG2]], metadata ![[B1:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[ARG3]], metadata ![[C1:.*]], metadata !DIExpression())
+! RECORDS-DAG: #dbg_declare(ptr %[[ARG1]], ![[A1:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[ARG2]], ![[B1:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[ARG3]], ![[C1:.*]], !DIExpression(), !{{.*}})
+! BOTH-DAG: %[[AL2:.*]] = alloca i64
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL2]], metadata ![[RES1:.*]], metadata !DIExpression())
+! RECORDS-DAG: #dbg_declare(ptr %[[AL2]], ![[RES1:.*]], !DIExpression(), !{{.*}})
+! BOTH-LABEL: }
+
+! BOTH-LABEL: define {{.*}}i32 @_QFPfn2
+! BOTH-SAME: (ptr %[[FN2ARG1:.*]], ptr %[[FN2ARG2:.*]], ptr %[[FN2ARG3:.*]])
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[FN2ARG1]], metadata ![[A2:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[FN2ARG2]], metadata ![[B2:.*]], metadata !DIExpression())
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[FN2ARG3]], metadata ![[C2:.*]], metadata !DIExpression())
+! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG1]], ![[A2:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG2]], ![[B2:.*]], !DIExpression(), !{{.*}})
+! RECORDS-DAG: #dbg_declare(ptr %[[FN2ARG3]], ![[C2:.*]], !DIExpression(), !{{.*}})
+! BOTH-DAG: %[[AL3:.*]] = alloca i32
+! INTRINSICS-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL3]], metadata ![[RES2:.*]], metadata !DIExpression())
+! RECORDS-DAG: #dbg_declare(ptr %[[AL3]], ![[RES2:.*]], !DIExpression(), !{{.*}})
+! BOTH-LABEL: }
+
+program mn
+! BOTH-DAG: ![[MAIN:.*]] = distinct !DISubprogram(name: "_QQmain", {{.*}})
+
+! BOTH-DAG: ![[TYI32:.*]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
+! BOTH-DAG: ![[TYI64:.*]] = !DIBasicType(name: "integer", size: 64, encoding: DW_ATE_signed)
+! BOTH-DAG: ![[TYL8:.*]] = !DIBasicType(name: "logical", size: 8, encoding: DW_ATE_boolean)
+! BOTH-DAG: ![[TYL32:.*]] = !DIBasicType(name: "logical", size: 32, encoding: DW_ATE_boolean)
+! BOTH-DAG: ![[TYR32:.*]] = !DIBasicType(name: "real", size: 32, encoding: DW_ATE_float)
+! BOTH-DAG: ![[TYR64:.*]] = !DIBasicType(name: "real", size: 64, encoding: DW_ATE_float)
+
+! BOTH-DAG: ![[I4]] = !DILocalVariable(name: "i4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYI32]])
+! BOTH-DAG: ![[I8]] = !DILocalVariable(name: "i8", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYI64]])
+! BOTH-DAG: ![[R4]] = !DILocalVariable(name: "r4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYR32]])
+! BOTH-DAG: ![[R8]] = !DILocalVariable(name: "r8", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYR64]])
+! BOTH-DAG: ![[L1]] = !DILocalVariable(name: "l1", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYL8]])
+! BOTH-DAG: ![[L4]] = !DILocalVariable(name: "l4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYL32]])
+ integer(kind=4) :: i4
+ integer(kind=8) :: i8
+ real(kind=4) :: r4
+ real(kind=8) :: r8
+ logical(kind=1) :: l1
+ logical(kind=4) :: l4
+
+ i8 = fn1(i4, r8, l1)
+ i4 = fn2(i8, r4, l4)
+contains
+! BOTH-DAG: ![[FN1:.*]] = distinct !DISubprogram(name: "fn1", {{.*}})
+! BOTH-DAG: ![[A1]] = !DILocalVariable(name: "a1", arg: 1, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI32]])
+! BOTH-DAG: ![[B1]] = !DILocalVariable(name: "b1", arg: 2, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYR64]])
+! BOTH-DAG: ![[C1]] = !DILocalVariable(name: "c1", arg: 3, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYL8]])
+! BOTH-DAG: ![[RES1]] = !DILocalVariable(name: "res1", scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI64]])
+ function fn1(a1, b1, c1) result (res1)
+ integer(kind=4), intent(in) :: a1
+ real(kind=8), intent(in) :: b1
+ logical(kind=1), intent(in) :: c1
+ integer(kind=8) :: res1
+
+ res1 = a1 + b1
+ end function
+
+! BOTH-DAG: ![[FN2:.*]] = distinct !DISubprogram(name: "fn2", {{.*}})
+! BOTH-DAG: ![[A2]] = !DILocalVariable(name: "a2", arg: 1, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI64]])
+! BOTH-DAG: ![[B2]] = !DILocalVariable(name: "b2", arg: 2, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYR32]])
+! BOTH-DAG: ![[C2]] = !DILocalVariable(name: "c2", arg: 3, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYL32]])
+! BOTH-DAG: ![[RES2]] = !DILocalVariable(name: "res2", scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI32]])
+ function fn2(a2, b2, c2) result (res2)
+ integer(kind=8), intent(in) :: a2
+ real(kind=4), intent(in) :: b2
+ logical(kind=4), intent(in) :: c2
+ integer(kind=4) :: res2
+
+ res2 = a2 + b2
+ end function
+end program
+
+LINEONLY-NOT: DILocalVariable
diff --git a/flang/test/Integration/debug-ptr-type.f90 b/flang/test/Integration/debug-ptr-type.f90
new file mode 100644
index 000000000000..bff7bcb862b5
--- /dev/null
+++ b/flang/test/Integration/debug-ptr-type.f90
@@ -0,0 +1,48 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+subroutine ff(n, m)
+ implicit none
+ integer i, j, m, n
+ real(4), pointer :: par(:, :)
+ integer, pointer :: psc
+ integer, pointer :: par2(:)
+ character(len=16), pointer :: pstr
+ real(4), target :: ar(4, 5)
+ integer, target :: sc
+ integer, target, allocatable :: ar2(:)
+ character(len=:), target, allocatable :: str
+
+ str = 'Hello'
+ pstr => str
+ allocate(ar2(4))
+ par2 => ar2
+ do i=1,5
+ do j=1,4
+ ar(j,i) = 0.1
+ par2(j) = j
+ end do
+ end do
+ sc = 3
+ psc => sc
+ par => ar
+
+ print *, sc
+ print *, ar
+ print *, ar2
+ print *, str
+ print *, psc
+ print *, par
+ print *, par2
+ print *, pstr
+end subroutine ff
+
+
+! CHECK-DAG: ![[INT_TY:[0-9]+]] = !DIBasicType(name: "integer"{{.*}})
+! CHECK-DAG: ![[ELEMS1:[0-9]+]] = !{!{{[0-9]+}}}
+! CHECK-DAG: !DILocalVariable(name: "par"{{.*}}type: ![[ARR_TY1:[0-9]+]])
+! CHECK-DAG: ![[ARR_TY1]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS2:[0-9]+]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne))
+! CHECK-DAG: ![[ELEMS2]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
+! CHECK-DAG: !DILocalVariable(name: "par2"{{.*}}type: ![[ARR_TY2:[0-9]+]])
+! CHECK-DAG: ![[ARR_TY2]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}, elements: ![[ELEMS1]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne))
+! CHECK-DAG: !DILocalVariable(name: "psc"{{.*}}type: ![[PTR_TY:[0-9]+]])
+! CHECK-DAG: ![[PTR_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[INT_TY]]{{.*}})
diff --git a/flang/test/Integration/vector-always.f90 b/flang/test/Integration/vector-always.f90
new file mode 100644
index 000000000000..7216698f901c
--- /dev/null
+++ b/flang/test/Integration/vector-always.f90
@@ -0,0 +1,14 @@
+! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s
+
+! CHECK-LABEL: vector_always
+subroutine vector_always
+ integer :: a(10)
+ !dir$ vector always
+ ! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[ANNOTATION:.*]]
+ do i=1,10
+ a(i)=i
+ end do
+end subroutine vector_always
+
+! CHECK: ![[ANNOTATION]] = distinct !{![[ANNOTATION]], ![[VECTORIZE:.*]]}
+! CHECK: ![[VECTORIZE]] = !{!"llvm.loop.vectorize.enable", i1 true}
diff --git a/flang/test/Lower/CUDA/cuda-data-attribute.cuf b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
index f7f58a43a143..192ef044913b 100644
--- a/flang/test/Lower/CUDA/cuda-data-attribute.cuf
+++ b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
@@ -4,15 +4,30 @@
! Test lowering of CUDA attribute on variables.
module cuda_var
+
+ type :: t1
+ integer :: a
+ end type
+
real, constant :: mod_a_rc
! CHECK: fir.global @_QMcuda_varEmod_a_rc {data_attr = #cuf.cuda<constant>} : f32
real, device :: mod_b_ra
! CHECK: fir.global @_QMcuda_varEmod_b_ra {data_attr = #cuf.cuda<device>} : f32
real, allocatable, managed :: mod_c_rm
! CHECK: fir.global @_QMcuda_varEmod_c_rm {data_attr = #cuf.cuda<managed>} : !fir.box<!fir.heap<f32>>
+
+ integer, device, dimension(10) :: mod_d_i_init = (/ (i, i = 1, 10) /)
+! CHECK: fir.global @_QMcuda_varEmod_d_i_init(dense<[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]> : tensor<10xi32>) {data_attr = #cuf.cuda<device>} : !fir.array<10xi32>
+
+ real, device, dimension(10) :: mod_d_rinit = (/ (i, i = 1, 10) /)
+! CHECK: fir.global @_QMcuda_varEmod_d_rinit(dense<[{{.*}}]> : tensor<10xf32>) {data_attr = #cuf.cuda<device>} : !fir.array<10xf32>
+
real, allocatable, pinned :: mod_d_rp
! CHECK: fir.global @_QMcuda_varEmod_d_rp {data_attr = #cuf.cuda<pinned>} : !fir.box<!fir.heap<f32>>
+ type(t1), device :: mod_d_t(2)
+! CHECK: fir.global @_QMcuda_varEmod_d_t {data_attr = #cuf.cuda<device>} : !fir.array<2x!fir.type<_QMcuda_varTt1{a:i32}>>
+
contains
subroutine local_var_attrs
@@ -71,7 +86,7 @@ end
! CHECK-LABEL: func.func @_QMcuda_varPcuda_alloc_free
! CHECK: %[[ALLOC_A:.*]] = cuf.alloc !fir.array<10xf32> {bindc_name = "a", data_attr = #cuf.cuda<device>, uniq_name = "_QMcuda_varFcuda_alloc_freeEa"} -> !fir.ref<!fir.array<10xf32>>
-! CHECK: %[[SHAPE:.*]] = fir.shape %c10 : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE:.*]] = fir.shape %c10{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ALLOC_A]](%[[SHAPE]]) {data_attr = #cuf.cuda<device>, uniq_name = "_QMcuda_varFcuda_alloc_freeEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
! CHECK: %[[ALLOC_U:.*]] = cuf.alloc i32 {bindc_name = "u", data_attr = #cuf.cuda<unified>, uniq_name = "_QMcuda_varFcuda_alloc_freeEu"} -> !fir.ref<i32>
diff --git a/flang/test/Lower/CUDA/cuda-data-transfer.cuf b/flang/test/Lower/CUDA/cuda-data-transfer.cuf
index 42fa4d09c95e..5dbf39c58c44 100644
--- a/flang/test/Lower/CUDA/cuda-data-transfer.cuf
+++ b/flang/test/Lower/CUDA/cuda-data-transfer.cuf
@@ -179,3 +179,46 @@ end subroutine
! CHECK: cuf.data_transfer %[[A]]#0 to %[[B]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
! CHECK: cuf.data_transfer %[[B]]#0 to %[[A]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
! CHECK: cuf.data_transfer %[[A]]#0 to %[[C]]#0 {transfer_kind = #cuf.cuda_transfer<device_device>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+
+subroutine sub8(a, b, n)
+ integer :: n
+ integer, device :: a(n)
+ integer :: b(10)
+ b = a
+ a = b
+end subroutine
+
+! CHECK-LABEL: func.func @_QPsub8(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "b"}, %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"})
+! CHECK: %[[B:.*]]:2 = hlfir.declare %[[ARG1]](%{{.*}}) dummy_scope %{{.*}} {uniq_name = "_QFsub8Eb"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub8Ea"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+! CHECK: cuf.data_transfer %[[A]]#0 to %[[B]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<10xi32>>
+! CHECK: cuf.data_transfer %[[B]]#0 to %[[A]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.box<!fir.array<?xi32>>
+
+subroutine sub9(a)
+ integer, pinned, allocatable :: a(:)
+ do concurrent (i = 1 : 10)
+ a(i) = 10 + a(i)
+ end do
+end subroutine
+
+! CHECK-LABEL: func.func @_QPsub9
+! CHECK-NOT: cuf.data_transfer
+
+subroutine sub10(a, b)
+ integer, device :: a
+ integer, allocatable, pinned :: b
+ integer :: res
+
+ res = a + b
+end subroutine
+
+
+
+! CHECK-LABEL: func.func @_QPsub10(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}
+
+! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %1 {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub10Ea"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: cuf.data_transfer %[[A]]#1 to %{{.*}}#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<i32>, !fir.ref<i32>
+! CHECK-NOT: cuf.data_transfer
+
diff --git a/flang/test/Lower/CUDA/cuda-kernel-do-reduction.cuf b/flang/test/Lower/CUDA/cuda-kernel-do-reduction.cuf
new file mode 100644
index 000000000000..94a269e9aa35
--- /dev/null
+++ b/flang/test/Lower/CUDA/cuda-kernel-do-reduction.cuf
@@ -0,0 +1,37 @@
+! Test CUDA Fortran kernel do reduction
+! RUN: bbc -emit-fir -fcuda -o - %s | FileCheck %s
+
+module mod1
+contains
+ subroutine host_sub()
+ integer, parameter :: asize = 4
+ integer, device :: adev(asize)
+ integer :: ahost(asize)
+ integer :: q
+ integer, device :: add_reduce_var
+ integer, device :: mul_reduce_var
+ ! CHECK: %[[VAL_0:.*]] = fir.declare %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QMmod1Fhost_subEadd_reduce_var"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ ! CHECK: %[[VAL_1:.*]] = fir.declare %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QMmod1Fhost_subEmul_reduce_var"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ do i = 1, asize
+ ahost(i) = i
+ enddo
+ adev = ahost
+ add_reduce_var = 0.0
+ mul_reduce_var = 1.0
+ ! CHECK: {{.*}} reduce(%[[VAL_0:.*]], %[[VAL_1:.*]] : !fir.ref<i32>, !fir.ref<i32> : [#fir.reduce_attr<add>, #fir.reduce_attr<multiply>]) {{.*}}
+ !$cuf kernel do <<< *, * >>> reduce(+:add_reduce_var) reduce(*:mul_reduce_var)
+ do i = 1, asize
+ add_reduce_var = add_reduce_var + adev(i)
+ mul_reduce_var = mul_reduce_var * adev(i)
+ end do
+ q = rsum
+ ahost = adev
+ print *, q
+ end
+end
+
+program test
+ use mod1
+ implicit none
+ call host_sub()
+end program test
diff --git a/flang/test/Lower/HLFIR/assumed-rank-calls.f90 b/flang/test/Lower/HLFIR/assumed-rank-calls.f90
new file mode 100644
index 000000000000..9d4503fef6fc
--- /dev/null
+++ b/flang/test/Lower/HLFIR/assumed-rank-calls.f90
@@ -0,0 +1,118 @@
+! Test passing of assumed-ranks that require creating a
+! a new descriptor for the dummy argument (different lower bounds,
+! attribute, or dynamic type)
+! RUN: bbc -emit-hlfir -allow-assumed-rank -o - %s | FileCheck %s
+
+subroutine test_alloc_to_nonalloc(x)
+ real, allocatable :: x(..)
+ interface
+ subroutine takes_assumed_rank(x)
+ real :: x(..)
+ end subroutine
+ end interface
+ call takes_assumed_rank(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_alloc_to_nonalloc(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_alloc_to_nonallocEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_4:.*]] = fir.rebox_assumed_rank %[[VAL_3]] lbs ones : (!fir.box<!fir.heap<!fir.array<*:f32>>>) -> !fir.box<!fir.array<*:f32>>
+! CHECK: fir.call @_QPtakes_assumed_rank(%[[VAL_4]]) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
+! CHECK: return
+! CHECK: }
+
+subroutine test_to_bindc(x)
+ real :: x(..)
+ interface
+ subroutine bindc_func(x) bind(c)
+ real :: x(..)
+ end subroutine
+ end interface
+ call bindc_func(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_to_bindc(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_to_bindcEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_3:.*]] = fir.rebox_assumed_rank %[[VAL_2]]#0 lbs zeroes : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
+! CHECK: fir.call @bindc_func(%[[VAL_3]]) fastmath<contract> {is_bind_c} : (!fir.box<!fir.array<*:f32>>) -> ()
+! CHECK: return
+! CHECK: }
+
+subroutine test_target_to_pointer(x)
+ real, target :: x(..)
+ interface
+ subroutine takes_target_as_pointer(x)
+ real, pointer, intent(in) :: x(..)
+ end subroutine
+ end interface
+ call takes_target_as_pointer(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_target_to_pointer(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x", fir.target}) {
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<*:f32>>>
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtest_target_to_pointerEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_4:.*]] = fir.rebox_assumed_rank %[[VAL_3]]#0 lbs preserve : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.ptr<!fir.array<*:f32>>>
+! CHECK: fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: fir.call @_QPtakes_target_as_pointer(%[[VAL_1]]) fastmath<contract> : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>) -> ()
+
+subroutine test_poly_to_nonepoly(x)
+ type t
+ integer :: i
+ end type
+ class(t) :: x(..)
+ interface
+ subroutine takes_assumed_rank_t(x)
+ import :: t
+ type(t) :: x(..)
+ end subroutine
+ end interface
+ call takes_assumed_rank_t(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_poly_to_nonepoly(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_poly_to_nonepolyEx"} : (!fir.class<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>, !fir.dscope) -> (!fir.class<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>, !fir.class<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>)
+! CHECK: %[[VAL_3:.*]] = fir.rebox_assumed_rank %[[VAL_2]]#0 lbs ones : (!fir.class<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>) -> !fir.box<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>
+! CHECK: fir.call @_QPtakes_assumed_rank_t(%[[VAL_3]]) fastmath<contract> : (!fir.box<!fir.array<*:!fir.type<_QFtest_poly_to_nonepolyTt{i:i32}>>>) -> ()
+! CHECK: return
+! CHECK: }
+
+
+subroutine test_copy_in_out(x)
+ real :: x(..)
+ interface
+ subroutine takes_contiguous(x)
+ real, contiguous :: x(..)
+ end subroutine
+ end interface
+ call takes_contiguous(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_copy_in_out(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<*:f32>>>
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_copy_in_outEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_3]]#0 to %[[VAL_1]] : (!fir.box<!fir.array<*:f32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> (!fir.box<!fir.array<*:f32>>, i1)
+! CHECK: fir.call @_QPtakes_contiguous(%[[VAL_4]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
+! CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_4]]#1 to %[[VAL_3]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, i1, !fir.box<!fir.array<*:f32>>) -> ()
+
+subroutine test_copy_in_out_2(x)
+ real :: x(..)
+ interface
+ subroutine takes_contiguous_intentin(x)
+ real, intent(in), contiguous :: x(..)
+ end subroutine
+ end interface
+ call takes_contiguous_intentin(x)
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_copy_in_out_2(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<*:f32>>>
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_copy_in_out_2Ex"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_3]]#0 to %[[VAL_1]] : (!fir.box<!fir.array<*:f32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> (!fir.box<!fir.array<*:f32>>, i1)
+! CHECK: fir.call @_QPtakes_contiguous_intentin(%[[VAL_4]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
+! CHECK: hlfir.copy_out %[[VAL_1]], %[[VAL_4]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, i1) -> ()
diff --git a/flang/test/Lower/HLFIR/assumed-rank-entry.f90 b/flang/test/Lower/HLFIR/assumed-rank-entry.f90
new file mode 100644
index 000000000000..9928f5459f71
--- /dev/null
+++ b/flang/test/Lower/HLFIR/assumed-rank-entry.f90
@@ -0,0 +1,28 @@
+! Test assumed-rank dummy argument that is not present in
+! all ENTRY statements.
+! RUN: bbc -emit-hlfir -allow-assumed-rank -o - %s | FileCheck %s
+
+subroutine test_main_entry(x)
+ real :: x(..)
+ interface
+ subroutine some_proc(x)
+ real :: x(..)
+ end subroutine
+ end interface
+ call some_proc(x)
+entry test_alternate_entry()
+ call the_end()
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_main_entry(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_main_entryEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+
+! CHECK-LABEL: func.func @_QPtest_alternate_entry() {
+! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<*:f32>>>
+! CHECK: %[[VAL_1:.*]] = fir.zero_bits !fir.heap<f32>
+! CHECK: %[[VAL_2:.*]] = fir.embox %[[VAL_1]] : (!fir.heap<f32>) -> !fir.box<!fir.heap<f32>>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.box<!fir.heap<f32>>) -> !fir.box<!fir.heap<!fir.array<*:f32>>>
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QFtest_main_entryEx"} : (!fir.box<!fir.heap<!fir.array<*:f32>>>) -> (!fir.box<!fir.heap<!fir.array<*:f32>>>, !fir.box<!fir.heap<!fir.array<*:f32>>>)
diff --git a/flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f90 b/flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f90
index 353e944a8ac1..6c8f5ba48d1b 100644
--- a/flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f90
+++ b/flang/test/Lower/HLFIR/assumed-rank-inquiries-2.f90
@@ -29,7 +29,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_size_1Ex"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_2]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
! CHECK: %[[VAL_7:.*]] = fir.call @_FortranASize(%[[VAL_5]]
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> i32
! CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_8]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
@@ -49,13 +49,13 @@ end subroutine
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (i32) {
-! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
! CHECK: %[[VAL_13:.*]] = fir.call @_FortranASize(%[[VAL_11]]
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32
! CHECK: fir.result %[[VAL_14]] : i32
! CHECK: } else {
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
-! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
! CHECK: %[[VAL_20:.*]] = fir.call @_FortranASizeDim(%[[VAL_18]]
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> i32
! CHECK: fir.result %[[VAL_21]] : i32
@@ -76,13 +76,13 @@ end subroutine
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (i32) {
-! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
! CHECK: %[[VAL_13:.*]] = fir.call @_FortranASize(%[[VAL_11]],
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32
! CHECK: fir.result %[[VAL_14]] : i32
! CHECK: } else {
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<i32>
-! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
! CHECK: %[[VAL_20:.*]] = fir.call @_FortranASizeDim(%[[VAL_18]]
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> i32
! CHECK: fir.result %[[VAL_21]] : i32
@@ -97,7 +97,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_size_4Ex"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_3]] : (!fir.box<!fir.heap<!fir.array<*:f32>>>) -> !fir.box<none>
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranASize(%[[VAL_6]]
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> i32
diff --git a/flang/test/Lower/HLFIR/assumed-rank-inquiries-3.f90 b/flang/test/Lower/HLFIR/assumed-rank-inquiries-3.f90
new file mode 100644
index 000000000000..fb44efcad3ce
--- /dev/null
+++ b/flang/test/Lower/HLFIR/assumed-rank-inquiries-3.f90
@@ -0,0 +1,194 @@
+! Test shape lowering for assumed-rank
+! RUN: bbc -emit-hlfir -o - %s -allow-assumed-rank | FileCheck %s
+
+subroutine test_shape(x)
+ real :: x(..)
+ call takes_integer_array(shape(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_shape(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAShape(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant false
+! CHECK: %[[VAL_16:.*]] = hlfir.as_expr %[[VAL_14]]#0 move %[[VAL_15]] : (!fir.box<!fir.array<?xi32>>, i1) -> !hlfir.expr<?xi32>
+! CHECK: %[[VAL_17:.*]]:3 = hlfir.associate %[[VAL_16]](%[[VAL_13]]) {adapt.valuebyref} : (!hlfir.expr<?xi32>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
+! CHECK: fir.call @_QPtakes_integer_array(%[[VAL_17]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
+! CHECK: hlfir.end_associate %[[VAL_17]]#1, %[[VAL_17]]#2 : !fir.ref<!fir.array<?xi32>>, i1
+! CHECK: hlfir.destroy %[[VAL_16]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+subroutine test_shape_kind(x)
+ real :: x(..)
+ call takes_integer8_array(shape(x, kind=8))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_shape_kind(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi64>
+! CHECK: %[[VAL_4:.*]] = arith.constant 8 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAShape(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.ref<!fir.array<?xi64>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi64>>, !fir.ref<!fir.array<?xi64>>)
+
+subroutine test_shape_2(x)
+ real, pointer :: x(..)
+ call takes_integer_array(shape(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_shape_2(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
+! CHECK: %[[VAL_11:.*]] = fir.call @_FortranAShape(%[[VAL_8]], %[[VAL_9]], %[[VAL_5]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_13:.*]] = fir.box_rank %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> index
+! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_14]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+
+
+subroutine test_lbound(x)
+ real :: x(..)
+ call takes_integer_array(lbound(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_lbound(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranALbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant false
+! CHECK: %[[VAL_16:.*]] = hlfir.as_expr %[[VAL_14]]#0 move %[[VAL_15]] : (!fir.box<!fir.array<?xi32>>, i1) -> !hlfir.expr<?xi32>
+! CHECK: %[[VAL_17:.*]]:3 = hlfir.associate %[[VAL_16]](%[[VAL_13]]) {adapt.valuebyref} : (!hlfir.expr<?xi32>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
+! CHECK: fir.call @_QPtakes_integer_array(%[[VAL_17]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
+! CHECK: hlfir.end_associate %[[VAL_17]]#1, %[[VAL_17]]#2 : !fir.ref<!fir.array<?xi32>>, i1
+! CHECK: hlfir.destroy %[[VAL_16]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+subroutine test_lbound_kind(x)
+ real :: x(..)
+ call takes_integer8_array(lbound(x, kind=8))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_lbound_kind(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi64>
+! CHECK: %[[VAL_4:.*]] = arith.constant 8 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranALbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.ref<!fir.array<?xi64>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi64>>, !fir.ref<!fir.array<?xi64>>)
+
+subroutine test_lbound_2(x)
+ real, pointer :: x(..)
+ call takes_integer_array(lbound(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_lbound_2(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
+! CHECK: %[[VAL_11:.*]] = fir.call @_FortranALbound(%[[VAL_8]], %[[VAL_9]], %[[VAL_5]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_13:.*]] = fir.box_rank %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> index
+! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_14]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+
+subroutine test_ubound(x)
+ real :: x(..)
+ call takes_integer_array(ubound(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_ubound(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAUbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant false
+! CHECK: %[[VAL_16:.*]] = hlfir.as_expr %[[VAL_14]]#0 move %[[VAL_15]] : (!fir.box<!fir.array<?xi32>>, i1) -> !hlfir.expr<?xi32>
+! CHECK: %[[VAL_17:.*]]:3 = hlfir.associate %[[VAL_16]](%[[VAL_13]]) {adapt.valuebyref} : (!hlfir.expr<?xi32>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
+! CHECK: fir.call @_QPtakes_integer_array(%[[VAL_17]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
+! CHECK: hlfir.end_associate %[[VAL_17]]#1, %[[VAL_17]]#2 : !fir.ref<!fir.array<?xi32>>, i1
+! CHECK: hlfir.destroy %[[VAL_16]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+subroutine test_ubound_kind(x)
+ real :: x(..)
+ call takes_integer8_array(ubound(x, kind=8))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_ubound_kind(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi64>
+! CHECK: %[[VAL_4:.*]] = arith.constant 8 : i32
+! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_3:.*]] : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_10:.*]] = fir.call @_FortranAUbound(%[[VAL_7]], %[[VAL_8]], %[[VAL_4]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi64>>) -> !fir.ref<!fir.array<?xi64>>
+! CHECK: %[[VAL_12:.*]] = fir.box_rank %[[VAL_3]] : (!fir.box<!fir.array<*:f32>>) -> index
+! CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_13]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi64>>, !fir.ref<!fir.array<?xi64>>)
+
+subroutine test_ubound_2(x)
+ real, pointer :: x(..)
+ call takes_integer_array(ubound(x))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_ubound_2(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<15xi32>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]] = arith.constant 4 : i32
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.llvm_ptr<i8>
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
+! CHECK: %[[VAL_11:.*]] = fir.call @_FortranAUbound(%[[VAL_8]], %[[VAL_9]], %[[VAL_5]], %{{.*}}, %{{.*}})
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<15xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_13:.*]] = fir.box_rank %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> index
+! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_14]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)
+
+subroutine test_lbound_dim(x)
+ real :: x(..)
+ call takes_integer(lbound(x, dim=2))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_lbound_dim(
+! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2:.*]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_8:.*]] = fir.call @_FortranALboundDim(%[[VAL_6]], %[[VAL_3]],
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> i32
+! CHECK: %[[VAL_10:.*]]:3 = hlfir.associate %[[VAL_9]]
+
+
+subroutine test_ubound_dim(x)
+ real :: x(..)
+ call takes_integer(ubound(x, dim=2))
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_ubound_dim(
+! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2:.*]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_8:.*]] = fir.call @_FortranASizeDim(%[[VAL_6]], %[[VAL_3]],
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> i32
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.box<none>
+! CHECK: %[[VAL_14:.*]] = fir.call @_FortranALboundDim(%[[VAL_12]], %[[VAL_3]],
+! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32
+! CHECK: %[[VAL_16:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]], %[[VAL_16]] : i32
+! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_17]], %[[VAL_9]] : i32
+! CHECK: %[[VAL_19:.*]]:3 = hlfir.associate %[[VAL_18]]
diff --git a/flang/test/Lower/HLFIR/assumed-rank-inquiries.f90 b/flang/test/Lower/HLFIR/assumed-rank-inquiries.f90
index e8610aa7d0e7..a1d150a21d14 100644
--- a/flang/test/Lower/HLFIR/assumed-rank-inquiries.f90
+++ b/flang/test/Lower/HLFIR/assumed-rank-inquiries.f90
@@ -99,7 +99,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_allocatedEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.heap<!fir.array<*:f32>>>) -> !fir.heap<!fir.array<*:f32>>
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.heap<!fir.array<*:f32>>) -> i64
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
@@ -115,7 +115,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_associated_1Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.ptr<!fir.array<*:f32>>
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ptr<!fir.array<*:f32>>) -> i64
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
@@ -133,7 +133,7 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_associated_2Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtest_associated_2Ey"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
-! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
@@ -150,8 +150,8 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_associated_3Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_associated_3Ey"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
-! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (!fir.box<!fir.ptr<!fir.array<*:f32>>>) -> !fir.box<none>
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_7]], %[[VAL_8]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
@@ -166,7 +166,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:!fir.char<1,?>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_len_1Ex"} : (!fir.box<!fir.array<*:!fir.char<1,?>>>, !fir.dscope) -> (!fir.box<!fir.array<*:!fir.char<1,?>>>, !fir.box<!fir.array<*:!fir.char<1,?>>>)
-! CHECK: %[[VAL_3:.*]] = fir.box_elesize %[[VAL_2]]#1 : (!fir.box<!fir.array<*:!fir.char<1,?>>>) -> index
+! CHECK: %[[VAL_3:.*]] = fir.box_elesize %[[VAL_2]]#0 : (!fir.box<!fir.array<*:!fir.char<1,?>>>) -> index
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (index) -> i32
! CHECK: %[[VAL_5:.*]]:3 = hlfir.associate %[[VAL_4]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
! CHECK: fir.call @_QPtakes_integer(%[[VAL_5]]#1) fastmath<contract> : (!fir.ref<i32>) -> ()
@@ -191,7 +191,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<*:none>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_storage_size_1Ex"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
-! CHECK: %[[VAL_3:.*]] = fir.box_elesize %[[VAL_2]]#1 : (!fir.class<!fir.array<*:none>>) -> i32
+! CHECK: %[[VAL_3:.*]] = fir.box_elesize %[[VAL_2]]#0 : (!fir.class<!fir.array<*:none>>) -> i32
! CHECK: %[[VAL_4:.*]] = arith.constant 8 : i32
! CHECK: %[[VAL_5:.*]] = arith.muli %[[VAL_3]], %[[VAL_4]] : i32
! CHECK: %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
@@ -204,7 +204,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_storage_size_2Ex"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.ptr<!fir.array<*:none>>
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ptr<!fir.array<*:none>>) -> i64
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
@@ -212,7 +212,7 @@ end subroutine
! CHECK: fir.if %[[VAL_7]] {
! CHECK: %[[VAL_13:.*]] = fir.call @_FortranAReportFatalUserError
! CHECK: }
-! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
! CHECK: %[[VAL_15:.*]] = fir.box_elesize %[[VAL_14]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> i32
! CHECK: %[[VAL_16:.*]] = arith.constant 8 : i32
! CHECK: %[[VAL_17:.*]] = arith.muli %[[VAL_15]], %[[VAL_16]] : i32
@@ -226,7 +226,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<*:none>> {fir.bindc_name = "x", fir.optional}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest_present_1Ex"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
-! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_2]]#1 : (!fir.class<!fir.array<*:none>>) -> i1
+! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_2]]#0 : (!fir.class<!fir.array<*:none>>) -> i1
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4>
! CHECK: %[[VAL_5:.*]]:3 = hlfir.associate %[[VAL_4]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
! CHECK: fir.call @_QPtakes_logical(%[[VAL_5]]#1) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
@@ -238,7 +238,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>> {fir.bindc_name = "x", fir.optional}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<optional, pointer>, uniq_name = "_QFtest_present_2Ex"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_2]]#1 : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>) -> i1
+! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_2]]#0 : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>) -> i1
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4>
! CHECK: %[[VAL_5:.*]]:3 = hlfir.associate %[[VAL_4]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
! CHECK: fir.call @_QPtakes_logical(%[[VAL_5]]#1) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
@@ -250,7 +250,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<*:none>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_is_contiguous_1Ex"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
-! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#1 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
! CHECK: %[[VAL_4:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_3]]) fastmath<contract> : (!fir.box<none>) -> i1
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
! CHECK: %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
@@ -263,7 +263,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_is_contiguous_2Ex"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.box<none>
! CHECK: %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) fastmath<contract> : (!fir.box<none>) -> i1
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i1) -> !fir.logical<4>
@@ -279,8 +279,8 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_same_type_as_1Ex"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_same_type_as_1Ey"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
-! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
! CHECK: %[[VAL_7:.*]] = fir.call @_FortranASameTypeAs(%[[VAL_5]], %[[VAL_6]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i1) -> !fir.logical<4>
! CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_8]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
@@ -295,8 +295,8 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_same_type_as_2Ex"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_same_type_as_2Ey"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
-! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
-! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.box<none>
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.box<none>
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranASameTypeAs(%[[VAL_7]], %[[VAL_8]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
@@ -313,8 +313,8 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_extends_type_of_1Ex"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {uniq_name = "_QFtest_extends_type_of_1Ey"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
-! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_3]]#0 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.class<!fir.array<*:none>>) -> !fir.box<none>
! CHECK: %[[VAL_7:.*]] = fir.call @_FortranAExtendsTypeOf(%[[VAL_5]], %[[VAL_6]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i1) -> !fir.logical<4>
! CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_8]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
@@ -329,8 +329,8 @@ end subroutine
! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_extends_type_of_2Ex"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_extends_type_of_2Ey"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>)
-! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
-! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<*:none>>>>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.box<none>
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (!fir.class<!fir.ptr<!fir.array<*:none>>>) -> !fir.box<none>
! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAExtendsTypeOf(%[[VAL_7]], %[[VAL_8]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
@@ -348,7 +348,7 @@ end subroutine
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
! CHECK: %[[VAL_4:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_4]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
-! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_2]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.ref<!fir.array<*:f32>>
+! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> !fir.ref<!fir.array<*:f32>>
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<*:f32>>) -> i64
! CHECK: fir.store %[[VAL_7]] to %[[VAL_5]] : !fir.ref<i64>
! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = ".tmp.intrinsic_result"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
@@ -365,7 +365,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFc_loc_2Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>
! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
! CHECK: %[[VAL_5:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
! CHECK: %[[VAL_6:.*]] = fir.coordinate_of %[[VAL_4]], %[[VAL_5]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
diff --git a/flang/test/Lower/HLFIR/assumed-rank-internal-proc.f90 b/flang/test/Lower/HLFIR/assumed-rank-internal-proc.f90
new file mode 100644
index 000000000000..f8d5e84696c5
--- /dev/null
+++ b/flang/test/Lower/HLFIR/assumed-rank-internal-proc.f90
@@ -0,0 +1,128 @@
+! Test assumed-rank capture inside internal procedures.
+! RUN: bbc -emit-hlfir -o - %s -allow-assumed-rank | FileCheck %s
+
+subroutine test_assumed_rank(x)
+ real :: x(..)
+interface
+subroutine some_sub(x)
+ real :: x(..)
+end subroutine
+end interface
+ call internal()
+contains
+subroutine internal()
+ call some_sub(x)
+end subroutine
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_assumed_rank(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<*:f32>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFtest_assumed_rankEx"} : (!fir.box<!fir.array<*:f32>>, !fir.dscope) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_3:.*]] = fir.alloca tuple<!fir.box<!fir.array<*:f32>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_4]] : (!fir.ref<tuple<!fir.box<!fir.array<*:f32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<*:f32>>>
+! CHECK: %[[VAL_6:.*]] = fir.rebox_assumed_rank %[[VAL_2]]#0 lbs preserve : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
+! CHECK: fir.store %[[VAL_6]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<*:f32>>>
+! CHECK: fir.call @_QFtest_assumed_rankPinternal(%[[VAL_3]]) fastmath<contract> : (!fir.ref<tuple<!fir.box<!fir.array<*:f32>>>>) -> ()
+! CHECK: return
+! CHECK: }
+
+! CHECK-LABEL: func.func private @_QFtest_assumed_rankPinternal(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.box<!fir.array<*:f32>>>> {fir.host_assoc})
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<tuple<!fir.box<!fir.array<*:f32>>>>, i32) -> !fir.ref<!fir.box<!fir.array<*:f32>>>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.array<*:f32>>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<host_assoc>, uniq_name = "_QFtest_assumed_rankEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: fir.call @_QPsome_sub(%[[VAL_5]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
+! CHECK: return
+! CHECK: }
+
+
+subroutine test_assumed_rank_optional(x)
+ class(*), optional :: x(..)
+interface
+subroutine some_sub2(x)
+ class(*) :: x(..)
+end subroutine
+end interface
+ call internal()
+contains
+subroutine internal()
+ call some_sub2(x)
+end subroutine
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_assumed_rank_optional(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.class<!fir.array<*:none>> {fir.bindc_name = "x", fir.optional}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFtest_assumed_rank_optionalEx"} : (!fir.class<!fir.array<*:none>>, !fir.dscope) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
+! CHECK: %[[VAL_3:.*]] = fir.alloca tuple<!fir.class<!fir.array<*:none>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_4]] : (!fir.ref<tuple<!fir.class<!fir.array<*:none>>>>, i32) -> !fir.ref<!fir.class<!fir.array<*:none>>>
+! CHECK: %[[VAL_6:.*]] = fir.is_present %[[VAL_2]]#0 : (!fir.class<!fir.array<*:none>>) -> i1
+! CHECK: fir.if %[[VAL_6]] {
+! CHECK: %[[VAL_7:.*]] = fir.rebox_assumed_rank %[[VAL_2]]#0 lbs preserve : (!fir.class<!fir.array<*:none>>) -> !fir.class<!fir.array<*:none>>
+! CHECK: fir.store %[[VAL_7]] to %[[VAL_5]] : !fir.ref<!fir.class<!fir.array<*:none>>>
+! CHECK: } else {
+! CHECK: %[[VAL_8:.*]] = fir.zero_bits !fir.ref<none>
+! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_8]] : (!fir.ref<none>) -> !fir.class<none>
+! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.class<none>) -> !fir.class<!fir.array<*:none>>
+! CHECK: fir.store %[[VAL_10]] to %[[VAL_5]] : !fir.ref<!fir.class<!fir.array<*:none>>>
+! CHECK: }
+! CHECK: fir.call @_QFtest_assumed_rank_optionalPinternal(%[[VAL_3]]) fastmath<contract> : (!fir.ref<tuple<!fir.class<!fir.array<*:none>>>>) -> ()
+! CHECK: return
+! CHECK: }
+
+! CHECK-LABEL: func.func private @_QFtest_assumed_rank_optionalPinternal(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.class<!fir.array<*:none>>>> {fir.host_assoc})
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<tuple<!fir.class<!fir.array<*:none>>>>, i32) -> !fir.ref<!fir.class<!fir.array<*:none>>>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.class<!fir.array<*:none>>>
+! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.class<!fir.array<*:none>>) -> !fir.ref<!fir.array<*:none>>
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.array<*:none>>) -> i64
+! CHECK: %[[VAL_7:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_8:.*]] = arith.cmpi ne, %[[VAL_6]], %[[VAL_7]] : i64
+! CHECK: %[[VAL_9:.*]] = fir.absent !fir.class<!fir.array<*:none>>
+! CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_8]], %[[VAL_4]], %[[VAL_9]] : !fir.class<!fir.array<*:none>>
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {fortran_attrs = #fir.var_attrs<optional, host_assoc>, uniq_name = "_QFtest_assumed_rank_optionalEx"} : (!fir.class<!fir.array<*:none>>) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
+! CHECK: fir.call @_QPsome_sub2(%[[VAL_11]]#0) fastmath<contract> : (!fir.class<!fir.array<*:none>>) -> ()
+! CHECK: return
+! CHECK: }
+
+
+subroutine test_assumed_rank_ptr(x)
+ real, pointer :: x(..)
+interface
+subroutine some_sub3(x)
+ real, pointer :: x(..)
+end subroutine
+end interface
+ call internal()
+contains
+subroutine internal()
+ call some_sub3(x)
+end subroutine
+end subroutine
+! CHECK-LABEL: func.func @_QPtest_assumed_rank_ptr(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_assumed_rank_ptrEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
+! CHECK: %[[VAL_3:.*]] = fir.alloca tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_4]] : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>
+! CHECK: fir.store %[[VAL_2]]#0 to %[[VAL_5]] : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>
+! CHECK: fir.call @_QFtest_assumed_rank_ptrPinternal(%[[VAL_3]]) fastmath<contract> : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>>) -> ()
+! CHECK: return
+! CHECK: }
+
+! CHECK-LABEL: func.func private @_QFtest_assumed_rank_ptrPinternal(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>> {fir.host_assoc})
+! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<pointer, host_assoc>, uniq_name = "_QFtest_assumed_rank_ptrEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>)
+! CHECK: fir.call @_QPsome_sub3(%[[VAL_5]]#0) fastmath<contract> : (!fir.ref<!fir.box<!fir.ptr<!fir.array<*:f32>>>>) -> ()
+! CHECK: return
+! CHECK: }
diff --git a/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90
index c363ab0df2fe..ccbc1df96a73 100644
--- a/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90
+++ b/flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90
@@ -58,7 +58,7 @@ contains
! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_char_copy_in_copy_out(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMbindc_seq_assocFtest_char_copy_in_copy_outEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>)
! CHECK: %[[VAL_2:.*]] = arith.constant 100 : i32
-! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1)
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_5:.*]] = fir.shift %[[VAL_4]], %[[VAL_4]] : (index, index) -> !fir.shift<2>
! CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_3]]#0(%[[VAL_5]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
@@ -81,7 +81,7 @@ contains
! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_23]](%[[VAL_20]]) typeparams %[[VAL_21]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shapeshift<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
! CHECK: fir.call @takes_char(%[[VAL_24]], %[[VAL_7]]#1) fastmath<contract> {is_bind_c} : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.ref<i32>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
! CHECK: hlfir.end_associate %[[VAL_7]]#1, %[[VAL_7]]#2 : !fir.ref<i32>, i1
! CHECK: return
! CHECK: }
@@ -92,7 +92,7 @@ contains
end subroutine
! CHECK-LABEL: func.func @_QMbindc_seq_assocPtest_char_assumed_size(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMbindc_seq_assocFtest_char_assumed_sizeEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.box<!fir.array<?x?x!fir.char<1,?>>>)
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>>) -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1)
! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_4:.*]] = fir.shift %[[VAL_3]], %[[VAL_3]] : (index, index) -> !fir.shift<2>
! CHECK: %[[VAL_5:.*]] = fir.rebox %[[VAL_2]]#0(%[[VAL_4]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
@@ -114,7 +114,7 @@ contains
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<10x?x!fir.char<1,?>>>
! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_21]](%[[VAL_18]]) typeparams %[[VAL_19]] : (!fir.ref<!fir.array<10x?x!fir.char<1,?>>>, !fir.shapeshift<2>, index) -> !fir.box<!fir.array<10x?x!fir.char<1,?>>>
! CHECK: fir.call @takes_char_assumed_size(%[[VAL_22]]) fastmath<contract> {is_bind_c} : (!fir.box<!fir.array<10x?x!fir.char<1,?>>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>>, i1, !fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
! CHECK: return
! CHECK: }
@@ -216,7 +216,7 @@ contains
! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_poly_copy_in_copy_out(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMpoly_seq_assocFtest_poly_copy_in_copy_outEx"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
! CHECK: %[[VAL_2:.*]] = arith.constant 100 : i32
-! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.class<!fir.array<?x?xnone>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
! CHECK: %[[VAL_4:.*]]:3 = hlfir.associate %[[VAL_2]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]]#1 {uniq_name = "_QMpoly_seq_assocFtakes_polyEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
@@ -234,7 +234,7 @@ contains
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) source_box %[[VAL_3]]#0 : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>, !fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?xnone>>
! CHECK: fir.call @_QPtakes_poly(%[[VAL_19]], %[[VAL_4]]#1) fastmath<contract> : (!fir.class<!fir.array<?xnone>>, !fir.ref<i32>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_3]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
! CHECK: hlfir.end_associate %[[VAL_4]]#1, %[[VAL_4]]#2 : !fir.ref<i32>, i1
! CHECK: return
! CHECK: }
@@ -245,7 +245,7 @@ contains
end subroutine
! CHECK-LABEL: func.func @_QMpoly_seq_assocPtest_poly_assumed_size(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:.*]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMpoly_seq_assocFtest_poly_assumed_sizeEx"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.class<!fir.array<?x?xnone>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
! CHECK: %[[VAL_3:.*]] = arith.constant 10 : i64
! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_5:.*]] = arith.subi %[[VAL_3]], %[[VAL_4]] : i64
@@ -262,7 +262,7 @@ contains
! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<10x?xnone>>
! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_16]](%[[VAL_14]]) source_box %[[VAL_2]]#0 : (!fir.ref<!fir.array<10x?xnone>>, !fir.shape<2>, !fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<10x?xnone>>
! CHECK: fir.call @_QPtakes_poly_assumed_size(%[[VAL_17]]) fastmath<contract> : (!fir.class<!fir.array<10x?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
! CHECK: return
! CHECK: }
diff --git a/flang/test/Lower/HLFIR/calls-assumed-shape.f90 b/flang/test/Lower/HLFIR/calls-assumed-shape.f90
index cfe607a69102..ee8eda5be6a6 100644
--- a/flang/test/Lower/HLFIR/calls-assumed-shape.f90
+++ b/flang/test/Lower/HLFIR/calls-assumed-shape.f90
@@ -42,10 +42,10 @@ end subroutine
! CHECK-LABEL: func.func @_QPtest_ptr_to_contiguous_assumed(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_ptr_to_contiguous_assumedEp"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_2]] to %[[TMP_BOX:.*]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1)
! CHECK: %[[VAL_4:.*]] = fir.rebox %[[VAL_3]]#0 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.box<!fir.array<?xf32>>
! CHECK: fir.call @_QPtakes_contiguous_assumed(%[[VAL_4]]) {{.*}} : (!fir.box<!fir.array<?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_3]]#1 to %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> ()
subroutine test_ptr_to_contiguous_assumed_classstar(p)
interface
@@ -59,10 +59,10 @@ end subroutine
! CHECK-LABEL: func.func @_QPtest_ptr_to_contiguous_assumed_classstar(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_ptr_to_contiguous_assumed_classstarEp"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.copy_in %[[VAL_2]] to %[[TMP_BOX:.*]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1)
! CHECK: %[[VAL_4:.*]] = fir.rebox %[[VAL_3]]#0 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.class<!fir.array<?xnone>>
! CHECK: fir.call @_QPtakes_contiguous_assumed_classstar(%[[VAL_4]]) {{.*}} : (!fir.class<!fir.array<?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_3]]#0, %[[VAL_3]]#1 to %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, i1, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_3]]#1 to %[[VAL_2]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1, !fir.box<!fir.ptr<!fir.array<?xf32>>>) -> ()
subroutine test_ptr_to_assumed_typestar(p)
interface
diff --git a/flang/test/Lower/HLFIR/calls-constant-expr-arg.f90 b/flang/test/Lower/HLFIR/calls-constant-expr-arg.f90
index 7c8faf4fca8f..61e7ef959d33 100644
--- a/flang/test/Lower/HLFIR/calls-constant-expr-arg.f90
+++ b/flang/test/Lower/HLFIR/calls-constant-expr-arg.f90
@@ -37,10 +37,10 @@ end subroutine sub
! CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_16]], %[[VAL_13]] : index
! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_18]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_20:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_11]]:%[[VAL_8]]:%[[VAL_12]]) shape %[[VAL_19]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! CHECK: %[[VAL_21:.*]]:2 = hlfir.copy_in %[[VAL_20]] : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, i1)
+! CHECK: %[[VAL_21:.*]]:2 = hlfir.copy_in %[[VAL_20]] to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.box<!fir.array<?xi32>>, i1)
! CHECK: %[[VAL_22:.*]] = fir.box_addr %[[VAL_21]]#0 : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
! CHECK: fir.call @_QPsub2(%[[VAL_22]]) fastmath<contract> : (!fir.ref<!fir.array<?xi32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_21]]#0, %[[VAL_21]]#1 to %[[VAL_20]] : (!fir.box<!fir.array<?xi32>>, i1, !fir.box<!fir.array<?xi32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_21]]#1 to %[[VAL_20]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, i1, !fir.box<!fir.array<?xi32>>) -> ()
! CHECK: return
! CHECK: }
diff --git a/flang/test/Lower/HLFIR/calls-optional.f90 b/flang/test/Lower/HLFIR/calls-optional.f90
index 1ada5b198aed..69a6e7fafff2 100644
--- a/flang/test/Lower/HLFIR/calls-optional.f90
+++ b/flang/test/Lower/HLFIR/calls-optional.f90
@@ -16,19 +16,18 @@ end subroutine
! CHECK-LABEL: func.func @_QPoptional_copy_in_out(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFoptional_copy_in_outEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.box<!fir.array<?xf32>>) -> i1
-! CHECK: %[[VAL_3:.*]]:4 = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>) {
-! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, i1)
+! CHECK: %[[VAL_3:.*]]:3 = fir.if %[[VAL_2]] -> (!fir.ref<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>) {
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.box<!fir.array<?xf32>>, i1)
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]]#0 : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK: fir.result %[[VAL_5]], %[[VAL_4]]#0, %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.ref<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>
+! CHECK: fir.result %[[VAL_5]], %[[VAL_4]]#1, %[[VAL_1]]#0 : !fir.ref<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>
! CHECK: } else {
-! CHECK: %[[VAL_6:.*]] = fir.absent !fir.ref<!fir.array<?xf32>>
-! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<!fir.array<?xf32>>
+! CHECK: %[[VAL_7:.*]] = fir.absent !fir.ref<!fir.array<?xf32>>
! CHECK: %[[VAL_8:.*]] = arith.constant false
! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<!fir.array<?xf32>>
-! CHECK: fir.result %[[VAL_6]], %[[VAL_7]], %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>
+! CHECK: fir.result %[[VAL_7]], %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>
! CHECK: }
! CHECK: fir.call @_QPtakes_optional_explicit(%[[VAL_3]]#0) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_3]]#1, %[[VAL_3]]#2 to %[[VAL_3]]#3 : (!fir.box<!fir.array<?xf32>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_3]]#1 to %[[VAL_3]]#2 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1, !fir.box<!fir.array<?xf32>>) -> ()
subroutine optional_value_copy(x)
interface
diff --git a/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 b/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90
index 05885e729f93..d607e7422a31 100644
--- a/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90
+++ b/flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90
@@ -13,8 +13,8 @@ subroutine pass_poly_to_assumed_type_assumed_size(x)
end subroutine
! CHECK-LABEL: func.func @_QPpass_poly_to_assumed_type_assumed_size(
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFpass_poly_to_assumed_type_assumed_sizeEx"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 to %[[TMP_BOX:.*]] : (!fir.class<!fir.array<?x?xnone>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?xnone>>
! CHECK: fir.call @_QPassumed_type_assumed_size(%[[VAL_4]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()
diff --git a/flang/test/Lower/HLFIR/convert-variable-assumed-rank.f90 b/flang/test/Lower/HLFIR/convert-variable-assumed-rank.f90
index cd65696ca5ed..3b60b0d04e9f 100644
--- a/flang/test/Lower/HLFIR/convert-variable-assumed-rank.f90
+++ b/flang/test/Lower/HLFIR/convert-variable-assumed-rank.f90
@@ -103,7 +103,7 @@ end subroutine
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs<allocatable, intent_out>, uniq_name = "_QMassumed_rank_testsFtest_intentoutEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
-! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>
! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.heap<!fir.array<*:f32>>>) -> !fir.heap<!fir.array<*:f32>>
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.heap<!fir.array<*:f32>>) -> i64
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
@@ -111,7 +111,7 @@ end subroutine
! CHECK: fir.if %[[VAL_7]] {
! CHECK: %[[VAL_8:.*]] = arith.constant false
! CHECK: %[[VAL_9:.*]] = fir.absent !fir.box<none>
-! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> !fir.ref<!fir.box<none>>
! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAAllocatableDeallocate(%[[VAL_12]], %[[VAL_8]], %[[VAL_9]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
! CHECK: }
! CHECK: return
diff --git a/flang/test/Lower/HLFIR/elemental-result-length.f90 b/flang/test/Lower/HLFIR/elemental-result-length.f90
index 0aaf7c93770c..278ef013d952 100644
--- a/flang/test/Lower/HLFIR/elemental-result-length.f90
+++ b/flang/test/Lower/HLFIR/elemental-result-length.f90
@@ -8,12 +8,6 @@ elemental function fct1(a, b) result(t)
t = a // b
end function
-elemental function fct2(c) result(t)
- integer, intent(in) :: c
- character(c) :: t
-
-end function
-
subroutine sub2(a,b,c)
character(*), intent(inout) :: c
character(*), intent(in) :: a, b
@@ -42,25 +36,6 @@ end subroutine
! CHECK: %[[RES:.*]] = fir.alloca !fir.char<1,?>(%[[RES_LENGTH]] : index) {bindc_name = ".result"}
! CHECK: fir.call @_QMm1Pfct1
-subroutine sub3(c)
- character(*), intent(inout) :: c(:)
-
- c = fct2(10)
-end subroutine
-
-! CHECK-LABEL: func.func @_QMm1Psub3(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c"}) {
-! CHECK: %[[C10:.*]] = arith.constant 10 : i32
-! CHECK: %[[C:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QMm1Fsub3Ec"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.box<!fir.array<?x!fir.char<1,?>>>)
-! CHECK: %[[ASSOC:.*]]:3 = hlfir.associate %[[C10]] {adapt.valuebyref} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
-! CHECK: %[[INPUT_ARG0:.*]]:2 = hlfir.declare %[[ASSOC]]#1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMm1Ffct2Ec"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[LOAD_INPUT_ARG0:.*]] = fir.load %[[INPUT_ARG0]]#0 : !fir.ref<i32>
-! CHECK: %[[LOAD_INPUT_ARG0_IDX:.*]] = fir.convert %[[LOAD_INPUT_ARG0]] : (i32) -> index
-! CHECK: %[[CMPI:.*]] = arith.cmpi sgt, %[[LOAD_INPUT_ARG0_IDX]], %c0{{.*}} : index
-! CHECK: %[[LENGTH:.*]] = arith.select %[[CMPI]], %[[LOAD_INPUT_ARG0_IDX]], %c0{{.*}} : index
-! CHECK: %[[RES:.*]] = fir.alloca !fir.char<1,?>(%[[LENGTH]] : index) {bindc_name = ".result"}
-! CHECK: fir.call @_QMm1Pfct2
-
subroutine sub4(a,b,c)
character(*), intent(inout) :: c(:)
character(*), intent(in) :: a(:), b(:)
diff --git a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90
index f5ec7c35594b..3f97a9f848d4 100644
--- a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90
+++ b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90
@@ -25,9 +25,9 @@ end subroutine test1
! CHECK: %[[VAL_26:.*]] = fir.shape %[[VAL_25]]#1 : (index) -> !fir.shape<1>
! CHECK: %[[VAL_27:.*]]:3 = hlfir.associate %[[VAL_23]](%[[VAL_26]]) {adapt.valuebyref} : (!hlfir.expr<?x!fir.type<_QMtypesTt>?>, !fir.shape<1>) -> (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, i1)
! CHECK: %[[VAL_28:.*]] = fir.rebox %[[VAL_27]]#0 : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>) -> !fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>
-! CHECK: %[[VAL_29:.*]]:2 = hlfir.copy_in %[[VAL_28]] : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>) -> (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1)
+! CHECK: %[[VAL_29:.*]]:2 = hlfir.copy_in %[[VAL_28]] to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>>) -> (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1)
! CHECK: fir.call @_QMtypesPcallee(%[[VAL_29]]#0) fastmath<contract> : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_29]]#0, %[[VAL_29]]#1 : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_29]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>>, i1) -> ()
! CHECK: hlfir.end_associate %[[VAL_27]]#0, %[[VAL_27]]#2 : !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, i1
! CHECK: hlfir.destroy %[[VAL_23]] : !hlfir.expr<?x!fir.type<_QMtypesTt>?>
@@ -40,8 +40,8 @@ end subroutine test2
! CHECK: %[[VAL_5:.*]] = hlfir.elemental %{{.*}} mold %{{.*}} unordered : (!fir.shape<1>, !fir.class<!fir.array<?x!fir.type<_QMtypesTt>>>) -> !hlfir.expr<?x!fir.type<_QMtypesTt>?> {
! CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_5]](%{{.*}}) {adapt.valuebyref} : (!hlfir.expr<?x!fir.type<_QMtypesTt>?>, !fir.shape<1>) -> (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, i1)
! CHECK: %[[VAL_10:.*]] = fir.rebox %[[VAL_9]]#0 : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>) -> !fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>
-! CHECK: %[[VAL_11:.*]]:2 = hlfir.copy_in %[[VAL_10]] : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>) -> (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1)
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.copy_in %[[VAL_10]] to %[[TMP_BOX:.*]] : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>>) -> (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1)
! CHECK: fir.call @_QMtypesPcallee(%[[VAL_11]]#0) fastmath<contract> : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>) -> ()
-! CHECK: hlfir.copy_out %[[VAL_11]]#0, %[[VAL_11]]#1 : (!fir.box<!fir.array<?x!fir.type<_QMtypesTt>>>, i1) -> ()
+! CHECK: hlfir.copy_out %[[TMP_BOX]], %[[VAL_11]]#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>>, i1) -> ()
! CHECK: hlfir.end_associate %[[VAL_9]]#0, %[[VAL_9]]#2 : !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt>>>>, i1
! CHECK: hlfir.destroy %[[VAL_5]] : !hlfir.expr<?x!fir.type<_QMtypesTt>?>
diff --git a/flang/test/Lower/HLFIR/select-rank.f90 b/flang/test/Lower/HLFIR/select-rank.f90
index 84987531f141..211b7565bab8 100644
--- a/flang/test/Lower/HLFIR/select-rank.f90
+++ b/flang/test/Lower/HLFIR/select-rank.f90
@@ -319,7 +319,7 @@ end subroutine
! CHECK: %[[VAL_6:.*]] = fir.is_assumed_size %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> i1
! CHECK: cf.cond_br %[[VAL_6]], ^bb1, ^bb2
! CHECK: ^bb1:
-! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {uniq_name = "_QFtest_simple_caseEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {uniq_name = "_QFtest_simple_caseEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPrdefault(%[[VAL_7]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb2:
@@ -362,7 +362,7 @@ end subroutine
! CHECK: fir.call @_QPr2(%[[VAL_8]]#0) fastmath<contract> : (!fir.box<!fir.array<?x?xf32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb3:
-! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {uniq_name = "_QFtest_rank_starEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {uniq_name = "_QFtest_rank_starEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPrdefault(%[[VAL_9]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb4:
@@ -431,7 +431,7 @@ end subroutine
! CHECK: fir.call @_QPr2(%[[VAL_7]]#0) fastmath<contract> : (!fir.box<!fir.array<?x?xf32>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb3:
-! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {fortran_attrs = #fir.var_attrs<asynchronous, target>, uniq_name = "_QFtest_rank_star_attributesEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {fortran_attrs = #fir.var_attrs<asynchronous, target>, uniq_name = "_QFtest_rank_star_attributesEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPrdefault(%[[VAL_8]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb4:
@@ -469,7 +469,7 @@ end subroutine
! CHECK: fir.call @_QPr2_implicit(%[[VAL_14]]#1) fastmath<contract> : (!fir.ref<!fir.array<?x?xf32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb3:
-! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtest_rank_star_contiguousEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtest_rank_star_contiguousEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPrdefault(%[[VAL_15]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb4:
@@ -518,7 +518,7 @@ end subroutine
! CHECK: fir.call @_QPrc0_implicit(%[[VAL_16]]#0) fastmath<contract> : (!fir.boxchar<1>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb3:
-! CHECK: %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_8]]#1 typeparams %[[VAL_7]] {uniq_name = "_QFtest_rank_star_contiguous_characterEx"} : (!fir.box<!fir.array<*:!fir.char<1,?>>>, i64) -> (!fir.box<!fir.array<*:!fir.char<1,?>>>, !fir.box<!fir.array<*:!fir.char<1,?>>>)
+! CHECK: %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_8]]#0 typeparams %[[VAL_7]] {uniq_name = "_QFtest_rank_star_contiguous_characterEx"} : (!fir.box<!fir.array<*:!fir.char<1,?>>>, i64) -> (!fir.box<!fir.array<*:!fir.char<1,?>>>, !fir.box<!fir.array<*:!fir.char<1,?>>>)
! CHECK: fir.call @_QPrcdefault(%[[VAL_17]]#0) fastmath<contract> : (!fir.box<!fir.array<*:!fir.char<1,?>>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb4:
@@ -568,7 +568,7 @@ end subroutine
! CHECK: fir.call @_QPra0(%[[VAL_10]]#0) fastmath<contract> : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb3:
-! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_simple_allocEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_simple_allocEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>)
! CHECK: fir.call @_QPradefault(%[[VAL_11]]#0) fastmath<contract> : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:f32>>>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb4:
@@ -588,7 +588,7 @@ end subroutine
! CHECK: %[[VAL_4:.*]] = fir.box_rank %[[VAL_2]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> i8
! CHECK: fir.select_case %[[VAL_4]] : i8 [#fir.point, %[[VAL_3]], ^bb2, unit, ^bb1]
! CHECK: ^bb1:
-! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_character_allocEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_character_allocEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
! CHECK: cf.br ^bb3
! CHECK: ^bb2:
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
@@ -614,7 +614,7 @@ end subroutine
! CHECK: %[[VAL_10:.*]] = fir.box_rank %[[VAL_8]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> i8
! CHECK: fir.select_case %[[VAL_10]] : i8 [#fir.point, %[[VAL_9]], ^bb2, unit, ^bb1]
! CHECK: ^bb1:
-! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_8]]#1 typeparams %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_explicit_character_ptrEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, i64) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_8]]#0 typeparams %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_explicit_character_ptrEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, i64) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
! CHECK: cf.br ^bb3
! CHECK: ^bb2:
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_8]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
@@ -634,7 +634,7 @@ end subroutine
! CHECK: %[[VAL_6:.*]] = fir.box_rank %[[VAL_4]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> i8
! CHECK: fir.select_case %[[VAL_6]] : i8 [#fir.point, %[[VAL_5]], ^bb2, unit, ^bb1]
! CHECK: ^bb1:
-! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_4]]#1 typeparams %[[VAL_3]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_assumed_character_ptrEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, index) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_4]]#0 typeparams %[[VAL_3]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest_assumed_character_ptrEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, index) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>)
! CHECK: cf.br ^bb3
! CHECK: ^bb2:
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<*:!fir.char<1,?>>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
@@ -661,7 +661,7 @@ end subroutine
! CHECK: fir.call @_QPrup1(%[[VAL_8]]#0) fastmath<contract> : (!fir.class<!fir.array<?xnone>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb3:
-! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {uniq_name = "_QFtest_polymorphicEx"} : (!fir.class<!fir.array<*:none>>) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {uniq_name = "_QFtest_polymorphicEx"} : (!fir.class<!fir.array<*:none>>) -> (!fir.class<!fir.array<*:none>>, !fir.class<!fir.array<*:none>>)
! CHECK: fir.call @_QPrupdefault(%[[VAL_9]]#0) fastmath<contract> : (!fir.class<!fir.array<*:none>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb4:
@@ -711,7 +711,7 @@ end subroutine
! CHECK: fir.call @_QPr1(%[[VAL_20]]#0) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: cf.br ^bb7
! CHECK: ^bb6:
-! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_4]]#1 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_4]]#0 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPr0(%[[VAL_11]]#1) fastmath<contract> : (!fir.ref<f32>) -> ()
! CHECK: fir.call @_QPrdefault(%[[VAL_21]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb7
@@ -741,14 +741,14 @@ end subroutine
! CHECK: fir.call @_QPr1(%[[VAL_32]]#0) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: cf.br ^bb13
! CHECK: ^bb12:
-! CHECK: %[[VAL_33:.*]]:2 = hlfir.declare %[[VAL_4]]#1 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_33:.*]]:2 = hlfir.declare %[[VAL_4]]#0 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPr1(%[[VAL_23]]#0) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.call @_QPrdefault(%[[VAL_33]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb13
! CHECK: ^bb13:
! CHECK: cf.br ^bb20
! CHECK: ^bb14:
-! CHECK: %[[VAL_34:.*]]:2 = hlfir.declare %[[VAL_3]]#1 {uniq_name = "_QFtest_nested_select_rankEx1"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_34:.*]]:2 = hlfir.declare %[[VAL_3]]#0 {uniq_name = "_QFtest_nested_select_rankEx1"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: %[[VAL_35:.*]] = arith.constant 0 : i8
! CHECK: %[[VAL_36:.*]] = arith.constant 1 : i8
! CHECK: %[[VAL_37:.*]] = fir.is_assumed_size %[[VAL_4]]#0 : (!fir.box<!fir.array<*:f32>>) -> i1
@@ -770,7 +770,7 @@ end subroutine
! CHECK: fir.call @_QPr1(%[[VAL_43]]#0) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: cf.br ^bb19
! CHECK: ^bb18:
-! CHECK: %[[VAL_44:.*]]:2 = hlfir.declare %[[VAL_4]]#1 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_44:.*]]:2 = hlfir.declare %[[VAL_4]]#0 {uniq_name = "_QFtest_nested_select_rankEx2"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: fir.call @_QPrdefault(%[[VAL_34]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: fir.call @_QPrdefault(%[[VAL_44]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb19
@@ -789,7 +789,7 @@ end subroutine
! CHECK: %[[VAL_5:.*]] = fir.is_assumed_size %[[VAL_2]]#0 : (!fir.box<!fir.array<*:f32>>) -> i1
! CHECK: cf.cond_br %[[VAL_5]], ^bb1, ^bb2
! CHECK: ^bb1:
-! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2]]#1 {uniq_name = "_QFtest_branchingEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
+! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2]]#0 {uniq_name = "_QFtest_branchingEx"} : (!fir.box<!fir.array<*:f32>>) -> (!fir.box<!fir.array<*:f32>>, !fir.box<!fir.array<*:f32>>)
! CHECK: %[[VAL_7:.*]] = fir.call @_QPjump() fastmath<contract> : () -> !fir.logical<4>
! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.logical<4>) -> i1
! CHECK: %[[VAL_9:.*]] = arith.constant true
diff --git a/flang/test/Lower/Intrinsics/Todo/reduce.f90 b/flang/test/Lower/Intrinsics/Todo/reduce.f90
deleted file mode 100644
index 7aa6f4a9f3ad..000000000000
--- a/flang/test/Lower/Intrinsics/Todo/reduce.f90
+++ /dev/null
@@ -1,13 +0,0 @@
-! RUN: %not_todo_cmd bbc -emit-fir %s -o - 2>&1 | FileCheck %s
-
-interface
- pure function chfunc(a,b)
- character(*),intent(in) :: a,b
- character(3) :: chfunc
- end function
- end interface
- character(3) x(5)
- print*, reduce(x,chfunc)
-end program
-
-! CHECK: not yet implemented: intrinsic: reduce
diff --git a/flang/test/Lower/Intrinsics/erfc_scaled.f90 b/flang/test/Lower/Intrinsics/erfc_scaled.f90
new file mode 100644
index 000000000000..ab5e90cb2409
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/erfc_scaled.f90
@@ -0,0 +1,23 @@
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPerfc_scaled4(
+! CHECK-SAME: %[[x:[^:]+]]: !fir.ref<f32>{{.*}}) -> f32
+function erfc_scaled4(x)
+ real(kind=4) :: erfc_scaled4
+ real(kind=4) :: x
+ erfc_scaled4 = erfc_scaled(x);
+! CHECK: %[[a1:.*]] = fir.load %[[x]] : !fir.ref<f32>
+! CHECK: %{{.*}} = fir.call @_FortranAErfcScaled4(%[[a1]]) {{.*}}: (f32) -> f32
+end function erfc_scaled4
+
+
+! CHECK-LABEL: func @_QPerfc_scaled8(
+! CHECK-SAME: %[[x:[^:]+]]: !fir.ref<f64>{{.*}}) -> f64
+function erfc_scaled8(x)
+ real(kind=8) :: erfc_scaled8
+ real(kind=8) :: x
+ erfc_scaled8 = erfc_scaled(x);
+! CHECK: %[[a1:.*]] = fir.load %[[x]] : !fir.ref<f64>
+! CHECK: %{{.*}} = fir.call @_FortranAErfcScaled8(%[[a1]]) {{.*}}: (f64) -> f64
+end function erfc_scaled8
diff --git a/flang/test/Lower/Intrinsics/ieee_femodes.f90 b/flang/test/Lower/Intrinsics/ieee_femodes.f90
index 75ff8291854d..abb264cb027e 100644
--- a/flang/test/Lower/Intrinsics/ieee_femodes.f90
+++ b/flang/test/Lower/Intrinsics/ieee_femodes.f90
@@ -5,57 +5,57 @@ program m
use ieee_arithmetic
use ieee_exceptions
- ! CHECK: %[[V_59:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}> {bindc_name = "modes", uniq_name = "_QFEmodes"}
- ! CHECK: %[[V_60:[0-9]+]] = fir.declare %[[V_59]] {uniq_name = "_QFEmodes"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>
+ ! CHECK: %[[VAL_69:.*]] = fir.alloca !fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}> {bindc_name = "modes", uniq_name = "_QFEmodes"}
+ ! CHECK: %[[VAL_70:.*]] = fir.declare %[[VAL_69]] {uniq_name = "_QFEmodes"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>
type(ieee_modes_type) :: modes
- ! CHECK: %[[V_61:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}> {bindc_name = "round", uniq_name = "_QFEround"}
- ! CHECK: %[[V_62:[0-9]+]] = fir.declare %[[V_61]] {uniq_name = "_QFEround"} : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>
+ ! CHECK: %[[VAL_71:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}> {bindc_name = "round", uniq_name = "_QFEround"}
+ ! CHECK: %[[VAL_72:.*]] = fir.declare %[[VAL_71]] {uniq_name = "_QFEround"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>
type(ieee_round_type) :: round
- ! CHECK: %[[V_68:[0-9]+]] = fir.address_of(@_QQro._QMieee_arithmeticTieee_round_type.0) : !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>
- ! CHECK: %[[V_69:[0-9]+]] = fir.declare %[[V_68]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QMieee_arithmeticTieee_round_type.0"} : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>
+ ! CHECK: %[[VAL_78:.*]] = fir.address_of(@_QQro._QM__fortran_builtinsT__builtin_ieee_round_type.0) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>
+ ! CHECK: %[[VAL_79:.*]] = fir.declare %[[VAL_78]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_round_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>
- ! CHECK: %[[V_70:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_71:[0-9]+]] = fir.coordinate_of %[[V_69]], %[[V_70]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_72:[0-9]+]] = fir.load %[[V_71]] : !fir.ref<i8>
- ! CHECK: %[[V_73:[0-9]+]] = fir.convert %[[V_72]] : (i8) -> i32
- ! CHECK: fir.call @llvm.set.rounding(%[[V_73]]) fastmath<contract> : (i32) -> ()
+ ! CHECK: %[[VAL_80:.*]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[VAL_81:.*]] = fir.coordinate_of %[[VAL_79]], %[[VAL_80]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[VAL_82:.*]] = fir.load %[[VAL_81]] : !fir.ref<i8>
+ ! CHECK: %[[VAL_83:.*]] = fir.convert %[[VAL_82]] : (i8) -> i32
+ ! CHECK: fir.call @llvm.set.rounding(%[[VAL_83]]) fastmath<contract> : (i32) -> ()
call ieee_set_rounding_mode(ieee_up)
- ! CHECK: %[[V_74:[0-9]+]] = fir.coordinate_of %[[V_62]], %[[V_70]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_75:[0-9]+]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
- ! CHECK: %[[V_76:[0-9]+]] = fir.convert %[[V_75]] : (i32) -> i8
- ! CHECK: fir.store %[[V_76]] to %[[V_74]] : !fir.ref<i8>
+ ! CHECK: %[[VAL_84:.*]] = fir.coordinate_of %[[VAL_72]], %[[VAL_80]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[VAL_85:.*]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
+ ! CHECK: %[[VAL_86:.*]] = fir.convert %[[VAL_85]] : (i32) -> i8
+ ! CHECK: fir.store %[[VAL_86]] to %[[VAL_84]] : !fir.ref<i8>
call ieee_get_rounding_mode(round)
print*, 'rounding_mode [up ] : ', mode_name(round)
- ! CHECK: %[[V_93:[0-9]+]] = fir.convert %[[V_60]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>) -> !fir.ref<i32>
- ! CHECK: %[[V_94:[0-9]+]] = fir.call @fegetmode(%[[V_93]]) fastmath<contract> : (!fir.ref<i32>) -> i32
+ ! CHECK: %[[VAL_103:.*]] = fir.convert %[[VAL_70]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_modes_type{_QM__fortran_ieee_exceptionsTieee_modes_type.__data:!fir.array<2xi32>}>>) -> !fir.ref<i32>
+ ! CHECK: %[[VAL_104:.*]] = fir.call @fegetmode(%[[VAL_103]]) fastmath<contract> : (!fir.ref<i32>) -> i32
call ieee_get_modes(modes)
- ! CHECK: %[[V_95:[0-9]+]] = fir.address_of(@_QQro._QMieee_arithmeticTieee_round_type.1) : !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>
- ! CHECK: %[[V_96:[0-9]+]] = fir.declare %[[V_95]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QMieee_arithmeticTieee_round_type.1"} : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>
- ! CHECK: %[[V_97:[0-9]+]] = fir.coordinate_of %[[V_96]], %[[V_70]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_98:[0-9]+]] = fir.load %[[V_97]] : !fir.ref<i8>
- ! CHECK: %[[V_99:[0-9]+]] = fir.convert %[[V_98]] : (i8) -> i32
- ! CHECK: fir.call @llvm.set.rounding(%[[V_99]]) fastmath<contract> : (i32) -> ()
+ ! CHECK: %[[VAL_105:.*]] = fir.address_of(@_QQro._QM__fortran_builtinsT__builtin_ieee_round_type.1) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>
+ ! CHECK: %[[VAL_106:.*]] = fir.declare %[[VAL_105]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_round_type.1"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>
+ ! CHECK: %[[VAL_107:.*]] = fir.coordinate_of %[[VAL_106]], %[[VAL_80]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[VAL_108:.*]] = fir.load %[[VAL_107]] : !fir.ref<i8>
+ ! CHECK: %[[VAL_109:.*]] = fir.convert %[[VAL_108]] : (i8) -> i32
+ ! CHECK: fir.call @llvm.set.rounding(%[[VAL_109]]) fastmath<contract> : (i32) -> ()
call ieee_set_rounding_mode(ieee_to_zero)
- ! CHECK: %[[V_100:[0-9]+]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
- ! CHECK: %[[V_101:[0-9]+]] = fir.convert %[[V_100]] : (i32) -> i8
- ! CHECK: fir.store %[[V_101]] to %[[V_74]] : !fir.ref<i8>
+ ! CHECK: %[[VAL_110:.*]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
+ ! CHECK: %[[VAL_111:.*]] = fir.convert %[[VAL_110]] : (i32) -> i8
+ ! CHECK: fir.store %[[VAL_111]] to %[[VAL_84]] : !fir.ref<i8>
call ieee_get_rounding_mode(round)
print*, 'rounding_mode [to_zero] : ', mode_name(round)
- ! CHECK: %[[V_116:[0-9]+]] = fir.call @fesetmode(%[[V_93]]) fastmath<contract> : (!fir.ref<i32>) -> i32
+ ! CHECK: %[[VAL_126:.*]] = fir.call @fesetmode(%[[VAL_103]]) fastmath<contract> : (!fir.ref<i32>) -> i32
call ieee_set_modes(modes)
- ! CHECK: %[[V_117:[0-9]+]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
- ! CHECK: %[[V_118:[0-9]+]] = fir.convert %[[V_117]] : (i32) -> i8
- ! CHECK: fir.store %[[V_118]] to %[[V_74]] : !fir.ref<i8>
+ ! CHECK: %[[VAL_127:.*]] = fir.call @llvm.get.rounding() fastmath<contract> : () -> i32
+ ! CHECK: %[[VAL_128:.*]] = fir.convert %[[VAL_127]] : (i32) -> i8
+ ! CHECK: fir.store %[[VAL_128]] to %[[VAL_84]] : !fir.ref<i8>
call ieee_get_rounding_mode(round)
print*, 'rounding_mode [up ] : ', mode_name(round)
diff --git a/flang/test/Lower/Intrinsics/ieee_festatus.f90 b/flang/test/Lower/Intrinsics/ieee_festatus.f90
index 0fbaf2f4d00c..66b1472101ef 100644
--- a/flang/test/Lower/Intrinsics/ieee_festatus.f90
+++ b/flang/test/Lower/Intrinsics/ieee_festatus.f90
@@ -4,12 +4,12 @@
program s
use ieee_arithmetic
- ! CHECK: %[[V_0:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_all) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_0:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_all) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_1:[0-9]+]] = fir.shape %c5{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[V_2:[0-9]+]] = fir.declare %[[V_0]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_all"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_53:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_usual) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_2:[0-9]+]] = fir.declare %[[V_0]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_all"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_53:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_usual) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_54:[0-9]+]] = fir.shape %c3{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[V_55:[0-9]+]] = fir.declare %[[V_53]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_usual"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_55:[0-9]+]] = fir.declare %[[V_53]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_usual"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
use ieee_exceptions
! CHECK: %[[V_56:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_ieee_exceptionsTieee_status_type{_QM__fortran_ieee_exceptionsTieee_status_type.__data:!fir.array<8xi32>}> {bindc_name = "status", uniq_name = "_QFEstatus"}
@@ -20,12 +20,12 @@ program s
! CHECK: %[[V_59:[0-9]+]] = fir.declare %[[V_58]](%[[V_1]]) {uniq_name = "_QFEv"} : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.logical<4>>>
logical :: v(size(ieee_all))
- ! CHECK: %[[V_60:[0-9]+]] = fir.address_of(@_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.0) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_61:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_60:[0-9]+]] = fir.address_of(@_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.0) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_61:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_61]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_96:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_97:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_96]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_61]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_96:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_97:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_96]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_98:[0-9]+]] = fir.load %[[V_97]] : !fir.ref<i8>
! CHECK: %[[V_99:[0-9]+]] = fir.convert %[[V_98]] : (i8) -> i32
! CHECK: %[[V_100:[0-9]+]] = fir.call @_FortranAMapException(%[[V_99]]) fastmath<contract> : (i32) -> i32
@@ -37,12 +37,12 @@ program s
! CHECK: }
call ieee_set_halting_mode(ieee_all, .true.)
- ! CHECK: %[[V_62:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_62:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_62]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_62]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_96:[0-9]+]] = fir.array_coor %[[V_59]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_99:[0-9]+]] = fir.load %[[V_98]] : !fir.ref<i8>
! CHECK: %[[V_100:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_101:[0-9]+]] = fir.convert %[[V_99]] : (i8) -> i32
@@ -60,12 +60,12 @@ program s
! CHECK: %[[V_76:[0-9]+]] = fir.call @fegetenv(%[[V_75]]) fastmath<contract> : (!fir.ref<i32>) -> i32
call ieee_get_status(status)
- ! CHECK: %[[V_77:[0-9]+]] = fir.address_of(@_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.1) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_78:[0-9]+]] = fir.declare %[[V_77]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.1"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_77:[0-9]+]] = fir.address_of(@_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.1) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_78:[0-9]+]] = fir.declare %[[V_77]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.1"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_78]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_96:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_97:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_96]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_78]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_96:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_97:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_96]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_98:[0-9]+]] = fir.load %[[V_97]] : !fir.ref<i8>
! CHECK: %[[V_99:[0-9]+]] = fir.convert %[[V_98]] : (i8) -> i32
! CHECK: %[[V_100:[0-9]+]] = fir.call @_FortranAMapException(%[[V_99]]) fastmath<contract> : (i32) -> i32
@@ -77,12 +77,12 @@ program s
! CHECK: }
call ieee_set_halting_mode(ieee_usual, .false.)
- ! CHECK: %[[V_79:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_79:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_79]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_79]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_96:[0-9]+]] = fir.array_coor %[[V_59]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_99:[0-9]+]] = fir.load %[[V_98]] : !fir.ref<i8>
! CHECK: %[[V_100:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_101:[0-9]+]] = fir.convert %[[V_99]] : (i8) -> i32
@@ -97,14 +97,14 @@ program s
print*, 'halting_mode [F F F T T] :', v
! CHECK: %[[V_87:[0-9]+]] = fir.call @fesetenv(%[[V_75]]) fastmath<contract> : (!fir.ref<i32>) -> i32
- ! CHECK: %[[V_88:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_88:[0-9]+]] = fir.declare %[[V_60]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
call ieee_set_status(status)
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_88]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.array_coor %[[V_88]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_96:[0-9]+]] = fir.array_coor %[[V_59]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_97:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_98:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_97]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_99:[0-9]+]] = fir.load %[[V_98]] : !fir.ref<i8>
! CHECK: %[[V_100:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_101:[0-9]+]] = fir.convert %[[V_99]] : (i8) -> i32
diff --git a/flang/test/Lower/Intrinsics/ieee_flag.f90 b/flang/test/Lower/Intrinsics/ieee_flag.f90
index 424f8d5b2953..862cfbd8b287 100644
--- a/flang/test/Lower/Intrinsics/ieee_flag.f90
+++ b/flang/test/Lower/Intrinsics/ieee_flag.f90
@@ -2,12 +2,12 @@
! CHECK-LABEL: c.func @_QQmain
- ! CHECK: %[[V_0:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_all) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_0:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_all) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_1:[0-9]+]] = fir.shape %c5{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[V_2:[0-9]+]] = fir.declare %[[V_0]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_all"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_53:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_usual) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_2:[0-9]+]] = fir.declare %[[V_0]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_all"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_53:[0-9]+]] = fir.address_of(@_QM__fortran_ieee_exceptionsECieee_usual) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_54:[0-9]+]] = fir.shape %c3{{.*}} : (index) -> !fir.shape<1>
- ! CHECK: %[[V_55:[0-9]+]] = fir.declare %[[V_53]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_usual"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_55:[0-9]+]] = fir.declare %[[V_53]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QM__fortran_ieee_exceptionsECieee_usual"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
use ieee_arithmetic
! CHECK: %[[V_56:[0-9]+]] = fir.alloca !fir.logical<4> {bindc_name = "v", uniq_name = "_QFEv"}
@@ -26,25 +26,15 @@
print*, 'Flag'
! CHECK: %[[V_74:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
- ! CHECK: %[[V_80:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0) : !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_81:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_82:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_83:[0-9]+]] = fir.coordinate_of %[[V_81]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_84:[0-9]+]] = fir.load %[[V_83]] : !fir.ref<i8>
- ! CHECK: %[[V_85:[0-9]+]] = arith.andi %[[V_84]], %c61{{.*}} : i8
- ! CHECK: %[[V_86:[0-9]+]] = arith.cmpi ne, %[[V_85]], %c0{{.*}} : i8
- ! CHECK: %[[V_87:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_74]], %[[V_86]]) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
- ! CHECK: %[[V_88:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_89:[0-9]+]] = fir.coordinate_of %[[V_88]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_90:[0-9]+]] = fir.load %[[V_89]] : !fir.ref<i8>
- ! CHECK: %[[V_91:[0-9]+]] = arith.andi %[[V_90]], %c61{{.*}} : i8
- ! CHECK: %[[V_92:[0-9]+]] = arith.cmpi ne, %[[V_91]], %c0{{.*}} : i8
- ! CHECK: %[[V_93:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_74]], %[[V_92]]) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
+ ! CHECK: %[[V_87:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_74]], %true) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
+ ! CHECK: %[[V_93:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_74]], %true) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
print*, 'support invalid: ', &
ieee_support_flag(ieee_invalid), ieee_support_flag(ieee_invalid, x)
- ! CHECK: %[[V_95:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_96:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_80:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_95:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_82:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_96:[0-9]+]] = fir.coordinate_of %[[V_95]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_97:[0-9]+]] = fir.load %[[V_96]] : !fir.ref<i8>
! CHECK: %[[V_98:[0-9]+]] = fir.convert %[[V_97]] : (i8) -> i32
! CHECK: %[[V_99:[0-9]+]] = fir.call @_FortranAMapException(%[[V_98]]) fastmath<contract> : (i32) -> i32
@@ -55,8 +45,8 @@
! CHECK: }
call ieee_set_flag(ieee_invalid, .false.)
- ! CHECK: %[[V_100:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_101:[0-9]+]] = fir.coordinate_of %[[V_100]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_100:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_101:[0-9]+]] = fir.coordinate_of %[[V_100]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_102:[0-9]+]] = fir.load %[[V_101]] : !fir.ref<i8>
! CHECK: %[[V_103:[0-9]+]] = fir.convert %[[V_102]] : (i8) -> i32
! CHECK: %[[V_104:[0-9]+]] = fir.call @_FortranAMapException(%[[V_103]]) fastmath<contract> : (i32) -> i32
@@ -69,8 +59,8 @@
! CHECK: %[[V_108:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, 'invalid[F]: ', v
- ! CHECK: %[[V_118:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_119:[0-9]+]] = fir.coordinate_of %[[V_118]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_118:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_119:[0-9]+]] = fir.coordinate_of %[[V_118]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_120:[0-9]+]] = fir.load %[[V_119]] : !fir.ref<i8>
! CHECK: %[[V_121:[0-9]+]] = fir.convert %[[V_120]] : (i8) -> i32
! CHECK: %[[V_122:[0-9]+]] = fir.call @_FortranAMapException(%[[V_121]]) fastmath<contract> : (i32) -> i32
@@ -81,8 +71,8 @@
! CHECK: }
call ieee_set_flag(ieee_invalid, .true.)
- ! CHECK: %[[V_123:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_124:[0-9]+]] = fir.coordinate_of %[[V_123]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_123:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_124:[0-9]+]] = fir.coordinate_of %[[V_123]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_125:[0-9]+]] = fir.load %[[V_124]] : !fir.ref<i8>
! CHECK: %[[V_126:[0-9]+]] = fir.convert %[[V_125]] : (i8) -> i32
! CHECK: %[[V_127:[0-9]+]] = fir.call @_FortranAMapException(%[[V_126]]) fastmath<contract> : (i32) -> i32
@@ -95,11 +85,11 @@
! CHECK: %[[V_131:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, 'invalid[T]: ', v
- ! CHECK: %[[V_140:[0-9]+]] = fir.address_of(@_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.1) : !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_141:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_140:[0-9]+]] = fir.address_of(@_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.1) : !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_141:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_141]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_141]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -111,12 +101,12 @@
! CHECK: }
call ieee_set_flag([ieee_invalid, ieee_overflow], .false.)
- ! CHECK: %[[V_142:[0-9]+]] = fir.address_of(@_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.2) : !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_143:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_142:[0-9]+]] = fir.address_of(@_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.2) : !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_143:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_143]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_143]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_60]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.call @_FortranAMapException(%[[V_314]]) fastmath<contract> : (i32) -> i32
@@ -130,14 +120,14 @@
! CHECK: %[[V_144:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[F], invalid[F]]: ', v2
- ! CHECK: %[[V_154:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_154:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_155:[0-9]+]] = fir.address_of(@_QQro.2xl4.3) : !fir.ref<!fir.array<2x!fir.logical<4>>>
! CHECK: %[[V_156:[0-9]+]] = fir.declare %[[V_155]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2xl4.3"} : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.logical<4>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_154]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_154]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_156]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.load %[[V_313]] : !fir.ref<i8>
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_314]] : (i8) -> i32
! CHECK: %[[V_316:[0-9]+]] = fir.call @_FortranAMapException(%[[V_315]]) fastmath<contract> : (i32) -> i32
@@ -150,11 +140,11 @@
! CHECK: }
call ieee_set_flag([ieee_invalid, ieee_overflow], [.false., .true.])
- ! CHECK: %[[V_157:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_157:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_157]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_157]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_60]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.call @_FortranAMapException(%[[V_314]]) fastmath<contract> : (i32) -> i32
@@ -168,11 +158,11 @@
! CHECK: %[[V_158:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], invalid[F]]: ', v2
- ! CHECK: %[[V_165:[0-9]+]] = fir.address_of(@_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_166:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_165:[0-9]+]] = fir.address_of(@_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4) : !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_166:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_166]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_166]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -184,11 +174,11 @@
! CHECK: }
call ieee_set_flag(ieee_usual, .true.)
- ! CHECK: %[[V_167:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_167:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_167]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_167]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_64]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.call @_FortranAMapException(%[[V_314]]) fastmath<contract> : (i32) -> i32
@@ -202,14 +192,14 @@
! CHECK: %[[V_168:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], divide_by_zero[T], invalid[T]]: ', v_usual
- ! CHECK: %[[V_178:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_178:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_179:[0-9]+]] = fir.address_of(@_QQro.3xl4.5) : !fir.ref<!fir.array<3x!fir.logical<4>>>
! CHECK: %[[V_180:[0-9]+]] = fir.declare %[[V_179]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3xl4.5"} : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.logical<4>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_178]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_178]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_180]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.load %[[V_313]] : !fir.ref<i8>
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_314]] : (i8) -> i32
! CHECK: %[[V_316:[0-9]+]] = fir.call @_FortranAMapException(%[[V_315]]) fastmath<contract> : (i32) -> i32
@@ -222,11 +212,11 @@
! CHECK: }
call ieee_set_flag(ieee_usual, [.true., .false., .true.])
- ! CHECK: %[[V_181:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_181:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_181]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_181]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_64]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.call @_FortranAMapException(%[[V_314]]) fastmath<contract> : (i32) -> i32
@@ -240,11 +230,11 @@
! CHECK: %[[V_182:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], divide_by_zero[F], invalid[T]]: ', v_usual
- ! CHECK: %[[V_189:[0-9]+]] = fir.address_of(@_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.6) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
- ! CHECK: %[[V_190:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_189:[0-9]+]] = fir.address_of(@_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.6) : !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_190:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_190]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_190]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -256,11 +246,11 @@
! CHECK: }
call ieee_set_flag(ieee_all, .false.)
- ! CHECK: %[[V_191:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_191:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_191]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_191]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_62]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.call @_FortranAMapException(%[[V_314]]) fastmath<contract> : (i32) -> i32
@@ -281,16 +271,11 @@
print*, 'Halting'
! CHECK: %[[V_211:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
- ! CHECK: %[[V_215:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_216:[0-9]+]] = fir.coordinate_of %[[V_215]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_217:[0-9]+]] = fir.load %[[V_216]] : !fir.ref<i8>
- ! CHECK: %[[V_218:[0-9]+]] = arith.andi %[[V_217]], %c61{{.*}} : i8
- ! CHECK: %[[V_219:[0-9]+]] = arith.cmpi ne, %[[V_218]], %c0{{.*}} : i8
- ! CHECK: %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]], %[[V_219]]) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
+ ! CHECK: %[[V_220:[0-9]+]] = fir.call @_FortranAioOutputLogical(%[[V_211]], %true) fastmath<contract> : (!fir.ref<i8>, i1) -> i1
print*, 'support invalid: ', ieee_support_halting(ieee_invalid)
- ! CHECK: %[[V_222:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_223:[0-9]+]] = fir.coordinate_of %[[V_222]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_222:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_223:[0-9]+]] = fir.coordinate_of %[[V_222]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_224:[0-9]+]] = fir.load %[[V_223]] : !fir.ref<i8>
! CHECK: %[[V_225:[0-9]+]] = fir.convert %[[V_224]] : (i8) -> i32
! CHECK: %[[V_226:[0-9]+]] = fir.call @_FortranAMapException(%[[V_225]]) fastmath<contract> : (i32) -> i32
@@ -301,8 +286,8 @@
! CHECK: }
call ieee_set_halting_mode(ieee_invalid, .false.)
- ! CHECK: %[[V_227:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_228:[0-9]+]] = fir.coordinate_of %[[V_227]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_227:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_228:[0-9]+]] = fir.coordinate_of %[[V_227]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_229:[0-9]+]] = fir.load %[[V_228]] : !fir.ref<i8>
! CHECK: %[[V_230:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_231:[0-9]+]] = fir.convert %[[V_229]] : (i8) -> i32
@@ -316,8 +301,8 @@
! CHECK: %[[V_236:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, 'invalid[F]: ', v
- ! CHECK: %[[V_244:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_245:[0-9]+]] = fir.coordinate_of %[[V_244]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_244:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_245:[0-9]+]] = fir.coordinate_of %[[V_244]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_246:[0-9]+]] = fir.load %[[V_245]] : !fir.ref<i8>
! CHECK: %[[V_247:[0-9]+]] = fir.convert %[[V_246]] : (i8) -> i32
! CHECK: %[[V_248:[0-9]+]] = fir.call @_FortranAMapException(%[[V_247]]) fastmath<contract> : (i32) -> i32
@@ -328,8 +313,8 @@
! CHECK: }
call ieee_set_halting_mode(ieee_invalid, .true.)
- ! CHECK: %[[V_249:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_250:[0-9]+]] = fir.coordinate_of %[[V_249]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_249:[0-9]+]] = fir.declare %[[V_80]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_250:[0-9]+]] = fir.coordinate_of %[[V_249]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_251:[0-9]+]] = fir.load %[[V_250]] : !fir.ref<i8>
! CHECK: %[[V_252:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_253:[0-9]+]] = fir.convert %[[V_251]] : (i8) -> i32
@@ -343,10 +328,10 @@
! CHECK: %[[V_258:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, 'invalid[T]: ', v
- ! CHECK: %[[V_266:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_266:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_266]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_266]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -358,11 +343,11 @@
! CHECK: }
call ieee_set_halting_mode([ieee_invalid, ieee_overflow], .false.)
- ! CHECK: %[[V_267:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_267:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_267]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_267]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_60]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
@@ -377,13 +362,13 @@
! CHECK: %[[V_268:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[F], invalid[F]]: ', v2
- ! CHECK: %[[V_274:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_274:[0-9]+]] = fir.declare %[[V_140]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.1"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_275:[0-9]+]] = fir.declare %[[V_155]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2xl4.3"} : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.logical<4>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_274]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_274]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_275]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.load %[[V_313]] : !fir.ref<i8>
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_314]] : (i8) -> i32
! CHECK: %[[V_316:[0-9]+]] = fir.call @_FortranAMapException(%[[V_315]]) fastmath<contract> : (i32) -> i32
@@ -396,11 +381,11 @@
! CHECK: }
call ieee_set_halting_mode([ieee_invalid, ieee_overflow], [.false., .true.])
- ! CHECK: %[[V_276:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_ieee_exceptionsTieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_276:[0-9]+]] = fir.declare %[[V_142]](%[[V_59]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.2x_QM__fortran_builtinsT__builtin_ieee_flag_type.2"} : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c2{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_276]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_276]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_60]](%[[V_59]]) %arg0 : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
@@ -415,10 +400,10 @@
! CHECK: %[[V_277:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], invalid[F]]: ', v2
- ! CHECK: %[[V_283:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_283:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_283]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_283]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -430,11 +415,11 @@
! CHECK: }
call ieee_set_halting_mode(ieee_usual, .true.)
- ! CHECK: %[[V_284:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_284:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_284]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_284]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_64]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
@@ -449,13 +434,13 @@
! CHECK: %[[V_285:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], divide_by_zero[T], invalid[T]]: ', v_usual
- ! CHECK: %[[V_291:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_291:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: %[[V_292:[0-9]+]] = fir.declare %[[V_179]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3xl4.5"} : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.logical<4>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_291]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_291]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_292]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_313:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.load %[[V_313]] : !fir.ref<i8>
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_314]] : (i8) -> i32
! CHECK: %[[V_316:[0-9]+]] = fir.call @_FortranAMapException(%[[V_315]]) fastmath<contract> : (i32) -> i32
@@ -468,11 +453,11 @@
! CHECK: }
call ieee_set_halting_mode(ieee_usual, [.true., .false., .true.])
- ! CHECK: %[[V_293:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_ieee_exceptionsTieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_293:[0-9]+]] = fir.declare %[[V_165]](%[[V_54]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3x_QM__fortran_builtinsT__builtin_ieee_flag_type.4"} : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c3{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_293]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_293]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_64]](%[[V_54]]) %arg0 : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
@@ -487,10 +472,10 @@
! CHECK: %[[V_294:[0-9]+]] = fir.call @_FortranAioBeginExternalListOutput
print*, '[overflow[T], divide_by_zero[F], invalid[T]]: ', v_usual
- ! CHECK: %[[V_300:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_300:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_300]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_300]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_311:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_312:[0-9]+]] = fir.load %[[V_311]] : !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.convert %[[V_312]] : (i8) -> i32
! CHECK: %[[V_314:[0-9]+]] = fir.call @_FortranAMapException(%[[V_313]]) fastmath<contract> : (i32) -> i32
@@ -502,11 +487,11 @@
! CHECK: }
call ieee_set_halting_mode(ieee_all, .true.)
- ! CHECK: %[[V_301:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_ieee_exceptionsTieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>
+ ! CHECK: %[[V_301:[0-9]+]] = fir.declare %[[V_189]](%[[V_1]]) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.5x_QM__fortran_builtinsT__builtin_ieee_flag_type.6"} : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>
! CHECK: fir.do_loop %arg0 = %c1{{.*}} to %c5{{.*}} step %c1{{.*}} {
- ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_301]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_310:[0-9]+]] = fir.array_coor %[[V_301]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>>, !fir.shape<1>, index) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
! CHECK: %[[V_311:[0-9]+]] = fir.array_coor %[[V_62]](%[[V_1]]) %arg0 : (!fir.ref<!fir.array<5x!fir.logical<4>>>, !fir.shape<1>, index) -> !fir.ref<!fir.logical<4>>
- ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_312:[0-9]+]] = fir.coordinate_of %[[V_310]], %[[V_82]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_313:[0-9]+]] = fir.load %[[V_312]] : !fir.ref<i8>
! CHECK: %[[V_314:[0-9]+]] = fir.call @fegetexcept() fastmath<contract> : () -> i32
! CHECK: %[[V_315:[0-9]+]] = fir.convert %[[V_313]] : (i8) -> i32
diff --git a/flang/test/Lower/Intrinsics/ieee_logb.f90 b/flang/test/Lower/Intrinsics/ieee_logb.f90
index 4195ac7af245..bbc65e68e0b4 100644
--- a/flang/test/Lower/Intrinsics/ieee_logb.f90
+++ b/flang/test/Lower/Intrinsics/ieee_logb.f90
@@ -13,10 +13,10 @@ subroutine out(x)
real(k) :: x, r
logical :: L
- ! CHECK: %[[V_65:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0) : !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_66:[0-9]+]] = fir.declare %[[V_65]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_67:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_68:[0-9]+]] = fir.coordinate_of %[[V_66]], %[[V_67]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_65:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_66:[0-9]+]] = fir.declare %[[V_65]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_67:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_68:[0-9]+]] = fir.coordinate_of %[[V_66]], %[[V_67]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_69:[0-9]+]] = fir.load %[[V_68]] : !fir.ref<i8>
! CHECK: %[[V_70:[0-9]+]] = fir.convert %[[V_69]] : (i8) -> i32
! CHECK: %[[V_71:[0-9]+]] = fir.call @_FortranAMapException(%[[V_70]]) fastmath<contract> : (i32) -> i32
@@ -52,8 +52,8 @@ subroutine out(x)
! CHECK: fir.store %[[V_75]] to %[[V_63]] : !fir.ref<f64>
r = ieee_logb(x)
- ! CHECK: %[[V_76:[0-9]+]] = fir.declare %[[V_65]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_77:[0-9]+]] = fir.coordinate_of %[[V_76]], %[[V_67]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_76:[0-9]+]] = fir.declare %[[V_65]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.0"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_77:[0-9]+]] = fir.coordinate_of %[[V_76]], %[[V_67]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_78:[0-9]+]] = fir.load %[[V_77]] : !fir.ref<i8>
! CHECK: %[[V_79:[0-9]+]] = fir.convert %[[V_78]] : (i8) -> i32
! CHECK: %[[V_80:[0-9]+]] = fir.call @_FortranAMapException(%[[V_79]]) fastmath<contract> : (i32) -> i32
diff --git a/flang/test/Lower/Intrinsics/ieee_max_min.f90 b/flang/test/Lower/Intrinsics/ieee_max_min.f90
index aecfaf0a7245..69ae05b8f2f8 100644
--- a/flang/test/Lower/Intrinsics/ieee_max_min.f90
+++ b/flang/test/Lower/Intrinsics/ieee_max_min.f90
@@ -67,10 +67,10 @@ program p
a = x(i)
b = x(j)
- ! CHECK: %[[V_201:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10) : !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_202:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_203:[0-9]+]] = fir.field_index _QM__fortran_ieee_exceptionsTieee_flag_type.flag, !fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>
- ! CHECK: %[[V_204:[0-9]+]] = fir.coordinate_of %[[V_202]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_201:[0-9]+]] = fir.address_of(@_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10) : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_202:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_203:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_flag_type.flag, !fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>
+ ! CHECK: %[[V_204:[0-9]+]] = fir.coordinate_of %[[V_202]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_205:[0-9]+]] = fir.load %[[V_204]] : !fir.ref<i8>
! CHECK: %[[V_206:[0-9]+]] = fir.convert %[[V_205]] : (i8) -> i32
! CHECK: %[[V_207:[0-9]+]] = fir.call @_FortranAMapException(%[[V_206]]) fastmath<contract> : (i32) -> i32
@@ -112,8 +112,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_211]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_212:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_213:[0-9]+]] = fir.coordinate_of %[[V_212]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_212:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_213:[0-9]+]] = fir.coordinate_of %[[V_212]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_214:[0-9]+]] = fir.load %[[V_213]] : !fir.ref<i8>
! CHECK: %[[V_215:[0-9]+]] = fir.convert %[[V_214]] : (i8) -> i32
! CHECK: %[[V_216:[0-9]+]] = fir.call @_FortranAMapException(%[[V_215]]) fastmath<contract> : (i32) -> i32
@@ -126,8 +126,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'max ', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_268:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_269:[0-9]+]] = fir.coordinate_of %[[V_268]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_268:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_269:[0-9]+]] = fir.coordinate_of %[[V_268]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_270:[0-9]+]] = fir.load %[[V_269]] : !fir.ref<i8>
! CHECK: %[[V_271:[0-9]+]] = fir.convert %[[V_270]] : (i8) -> i32
! CHECK: %[[V_272:[0-9]+]] = fir.call @_FortranAMapException(%[[V_271]]) fastmath<contract> : (i32) -> i32
@@ -171,8 +171,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_278]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_279:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_280:[0-9]+]] = fir.coordinate_of %[[V_279]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_279:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_280:[0-9]+]] = fir.coordinate_of %[[V_279]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_281:[0-9]+]] = fir.load %[[V_280]] : !fir.ref<i8>
! CHECK: %[[V_282:[0-9]+]] = fir.convert %[[V_281]] : (i8) -> i32
! CHECK: %[[V_283:[0-9]+]] = fir.call @_FortranAMapException(%[[V_282]]) fastmath<contract> : (i32) -> i32
@@ -185,8 +185,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'mag ', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_329:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_330:[0-9]+]] = fir.coordinate_of %[[V_329]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_329:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_330:[0-9]+]] = fir.coordinate_of %[[V_329]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_331:[0-9]+]] = fir.load %[[V_330]] : !fir.ref<i8>
! CHECK: %[[V_332:[0-9]+]] = fir.convert %[[V_331]] : (i8) -> i32
! CHECK: %[[V_333:[0-9]+]] = fir.call @_FortranAMapException(%[[V_332]]) fastmath<contract> : (i32) -> i32
@@ -232,8 +232,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_337]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_338:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_339:[0-9]+]] = fir.coordinate_of %[[V_338]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_338:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_339:[0-9]+]] = fir.coordinate_of %[[V_338]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_340:[0-9]+]] = fir.load %[[V_339]] : !fir.ref<i8>
! CHECK: %[[V_341:[0-9]+]] = fir.convert %[[V_340]] : (i8) -> i32
! CHECK: %[[V_342:[0-9]+]] = fir.call @_FortranAMapException(%[[V_341]]) fastmath<contract> : (i32) -> i32
@@ -246,8 +246,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'max_num', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_388:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_389:[0-9]+]] = fir.coordinate_of %[[V_388]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_388:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_389:[0-9]+]] = fir.coordinate_of %[[V_388]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_390:[0-9]+]] = fir.load %[[V_389]] : !fir.ref<i8>
! CHECK: %[[V_391:[0-9]+]] = fir.convert %[[V_390]] : (i8) -> i32
! CHECK: %[[V_392:[0-9]+]] = fir.call @_FortranAMapException(%[[V_391]]) fastmath<contract> : (i32) -> i32
@@ -295,8 +295,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_398]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_399:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_400:[0-9]+]] = fir.coordinate_of %[[V_399]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_399:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_400:[0-9]+]] = fir.coordinate_of %[[V_399]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_401:[0-9]+]] = fir.load %[[V_400]] : !fir.ref<i8>
! CHECK: %[[V_402:[0-9]+]] = fir.convert %[[V_401]] : (i8) -> i32
! CHECK: %[[V_403:[0-9]+]] = fir.call @_FortranAMapException(%[[V_402]]) fastmath<contract> : (i32) -> i32
@@ -309,8 +309,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'mag_num', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_449:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_450:[0-9]+]] = fir.coordinate_of %[[V_449]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_449:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_450:[0-9]+]] = fir.coordinate_of %[[V_449]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_451:[0-9]+]] = fir.load %[[V_450]] : !fir.ref<i8>
! CHECK: %[[V_452:[0-9]+]] = fir.convert %[[V_451]] : (i8) -> i32
! CHECK: %[[V_453:[0-9]+]] = fir.call @_FortranAMapException(%[[V_452]]) fastmath<contract> : (i32) -> i32
@@ -352,8 +352,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_457]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_458:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_459:[0-9]+]] = fir.coordinate_of %[[V_458]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_458:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_459:[0-9]+]] = fir.coordinate_of %[[V_458]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_460:[0-9]+]] = fir.load %[[V_459]] : !fir.ref<i8>
! CHECK: %[[V_461:[0-9]+]] = fir.convert %[[V_460]] : (i8) -> i32
! CHECK: %[[V_462:[0-9]+]] = fir.call @_FortranAMapException(%[[V_461]]) fastmath<contract> : (i32) -> i32
@@ -366,8 +366,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'min ', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_508:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_509:[0-9]+]] = fir.coordinate_of %[[V_508]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_508:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_509:[0-9]+]] = fir.coordinate_of %[[V_508]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_510:[0-9]+]] = fir.load %[[V_509]] : !fir.ref<i8>
! CHECK: %[[V_511:[0-9]+]] = fir.convert %[[V_510]] : (i8) -> i32
! CHECK: %[[V_512:[0-9]+]] = fir.call @_FortranAMapException(%[[V_511]]) fastmath<contract> : (i32) -> i32
@@ -411,8 +411,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_518]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_519:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_520:[0-9]+]] = fir.coordinate_of %[[V_519]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_519:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_520:[0-9]+]] = fir.coordinate_of %[[V_519]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_521:[0-9]+]] = fir.load %[[V_520]] : !fir.ref<i8>
! CHECK: %[[V_522:[0-9]+]] = fir.convert %[[V_521]] : (i8) -> i32
! CHECK: %[[V_523:[0-9]+]] = fir.call @_FortranAMapException(%[[V_522]]) fastmath<contract> : (i32) -> i32
@@ -425,8 +425,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'mig ', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_569:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_570:[0-9]+]] = fir.coordinate_of %[[V_569]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_569:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_570:[0-9]+]] = fir.coordinate_of %[[V_569]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_571:[0-9]+]] = fir.load %[[V_570]] : !fir.ref<i8>
! CHECK: %[[V_572:[0-9]+]] = fir.convert %[[V_571]] : (i8) -> i32
! CHECK: %[[V_573:[0-9]+]] = fir.call @_FortranAMapException(%[[V_572]]) fastmath<contract> : (i32) -> i32
@@ -472,8 +472,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_577]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_578:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_579:[0-9]+]] = fir.coordinate_of %[[V_578]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_578:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_579:[0-9]+]] = fir.coordinate_of %[[V_578]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_580:[0-9]+]] = fir.load %[[V_579]] : !fir.ref<i8>
! CHECK: %[[V_581:[0-9]+]] = fir.convert %[[V_580]] : (i8) -> i32
! CHECK: %[[V_582:[0-9]+]] = fir.call @_FortranAMapException(%[[V_581]]) fastmath<contract> : (i32) -> i32
@@ -486,8 +486,8 @@ program p
call ieee_get_flag(ieee_invalid, flag_value)
write(*, 4) 'min_num', a, a, b, b, r, flag_value, trim(tag(r))
- ! CHECK: %[[V_628:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_629:[0-9]+]] = fir.coordinate_of %[[V_628]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_628:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_629:[0-9]+]] = fir.coordinate_of %[[V_628]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_630:[0-9]+]] = fir.load %[[V_629]] : !fir.ref<i8>
! CHECK: %[[V_631:[0-9]+]] = fir.convert %[[V_630]] : (i8) -> i32
! CHECK: %[[V_632:[0-9]+]] = fir.call @_FortranAMapException(%[[V_631]]) fastmath<contract> : (i32) -> i32
@@ -535,8 +535,8 @@ program p
! CHECK: fir.result %[[V_693]] : f32
! CHECK: }
! CHECK: fir.store %[[V_638]] to %[[V_83]] : !fir.ref<f32>
- ! CHECK: %[[V_639:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_ieee_exceptionsTieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>
- ! CHECK: %[[V_640:[0-9]+]] = fir.coordinate_of %[[V_639]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_ieee_exceptionsTieee_flag_type{_QM__fortran_ieee_exceptionsTieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_639:[0-9]+]] = fir.declare %[[V_201]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QM__fortran_builtinsT__builtin_ieee_flag_type.10"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>) -> !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>
+ ! CHECK: %[[V_640:[0-9]+]] = fir.coordinate_of %[[V_639]], %[[V_203]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_flag_type{_QM__fortran_builtinsT__builtin_ieee_flag_type.flag:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_641:[0-9]+]] = fir.load %[[V_640]] : !fir.ref<i8>
! CHECK: %[[V_642:[0-9]+]] = fir.convert %[[V_641]] : (i8) -> i32
! CHECK: %[[V_643:[0-9]+]] = fir.call @_FortranAMapException(%[[V_642]]) fastmath<contract> : (i32) -> i32
diff --git a/flang/test/Lower/Intrinsics/ieee_operator_eq.f90 b/flang/test/Lower/Intrinsics/ieee_operator_eq.f90
index 1a655ef47ec9..d2067602babb 100644
--- a/flang/test/Lower/Intrinsics/ieee_operator_eq.f90
+++ b/flang/test/Lower/Intrinsics/ieee_operator_eq.f90
@@ -4,10 +4,10 @@
subroutine s(r1,r2)
use ieee_arithmetic, only: ieee_round_type, operator(==)
type(ieee_round_type) :: r1, r2
- ! CHECK: %[[V_3:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_4:[0-9]+]] = fir.coordinate_of %arg0, %[[V_3]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_5:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_6:[0-9]+]] = fir.coordinate_of %arg1, %[[V_5]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_3:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_4:[0-9]+]] = fir.coordinate_of %arg0, %[[V_3]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_5:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_6:[0-9]+]] = fir.coordinate_of %arg1, %[[V_5]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_7:[0-9]+]] = fir.load %[[V_4]] : !fir.ref<i8>
! CHECK: %[[V_8:[0-9]+]] = fir.load %[[V_6]] : !fir.ref<i8>
! CHECK: %[[V_9:[0-9]+]] = arith.cmpi eq, %[[V_7]], %[[V_8]] : i8
@@ -26,26 +26,26 @@ end
end
end interface
- ! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_2:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_3:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_9:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_10:[0-9]+]] = fir.coordinate_of %[[V_3]], %[[V_9]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_1:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_2:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_3:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_9:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_10:[0-9]+]] = fir.coordinate_of %[[V_3]], %[[V_9]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: fir.store %c0{{.*}} to %[[V_10]] : !fir.ref<i8>
- ! CHECK: %[[V_16:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_17:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_16]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_16:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_17:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_16]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: fir.store %c1{{.*}} to %[[V_17]] : !fir.ref<i8>
- ! CHECK: fir.call @_QPs(%[[V_3]], %[[V_2]]) {{.*}} : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>) -> ()
+ ! CHECK: fir.call @_QPs(%[[V_3]], %[[V_2]]) {{.*}} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>) -> ()
call s(ieee_to_zero, ieee_nearest)
- ! CHECK: %[[V_23:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_24:[0-9]+]] = fir.coordinate_of %[[V_1]], %[[V_23]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_23:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_24:[0-9]+]] = fir.coordinate_of %[[V_1]], %[[V_23]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: fir.store %c1{{.*}} to %[[V_24]] : !fir.ref<i8>
- ! CHECK: %[[V_30:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_31:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_30]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_30:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_31:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_30]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: fir.store %c1{{.*}} to %[[V_31]] : !fir.ref<i8>
- ! CHECK: fir.call @_QPs(%[[V_1]], %[[V_0]]) {{.*}} : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>) -> ()
+ ! CHECK: fir.call @_QPs(%[[V_1]], %[[V_0]]) {{.*}} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>) -> ()
call s(ieee_nearest, ieee_nearest)
end
diff --git a/flang/test/Lower/Intrinsics/ieee_rounding.f90 b/flang/test/Lower/Intrinsics/ieee_rounding.f90
index 6b2427faf320..be99ffba6000 100644
--- a/flang/test/Lower/Intrinsics/ieee_rounding.f90
+++ b/flang/test/Lower/Intrinsics/ieee_rounding.f90
@@ -3,44 +3,32 @@
! CHECK-LABEL: c.func @_QQmain
program r
use ieee_arithmetic
- ! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK-DAG: %[[V_1:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK-DAG: %[[V_2:[0-9]+]] = fir.alloca !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}> {bindc_name = "round_value", uniq_name = "_QFEround_value"}
+ ! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK-DAG: %[[V_2:[0-9]+]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}> {bindc_name = "round_value", uniq_name = "_QFEround_value"}
type(ieee_round_type) :: round_value
- ! CHECK: %[[V_13:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_14:[0-9]+]] = fir.coordinate_of %[[V_1]], %[[V_13]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: fir.store %c3{{.*}} to %[[V_14]] : !fir.ref<i8>
- ! CHECK: %[[V_15:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_16:[0-9]+]] = fir.coordinate_of %[[V_1]], %[[V_15]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
- ! CHECK: %[[V_17:[0-9]+]] = fir.load %[[V_16]] : !fir.ref<i8>
- ! CHECK: %[[V_18:[0-9]+]] = arith.cmpi sge, %[[V_17]], %c0{{.*}} : i8
- ! CHECK: %[[V_19:[0-9]+]] = arith.cmpi sle, %[[V_17]], %c3{{.*}} : i8
- ! CHECK: %[[V_20:[0-9]+]] = arith.andi %[[V_18]], %[[V_19]] : i1
- ! CHECK: %[[V_21:[0-9]+]] = fir.convert %[[V_20]] : (i1) -> !fir.logical<4>
- ! CHECK: %[[V_22:[0-9]+]] = fir.convert %[[V_21]] : (!fir.logical<4>) -> i1
- ! CHECK: fir.if %[[V_22]] {
+ ! CHECK: fir.if %true {
if (ieee_support_rounding(ieee_down)) then
- ! CHECK: %[[V_23:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_24:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_23]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_23:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_24:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_23]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_25:[0-9]+]] = fir.call @llvm.get.rounding() {{.*}} : () -> i32
! CHECK: %[[V_26:[0-9]+]] = fir.convert %[[V_25]] : (i32) -> i8
! CHECK: fir.store %[[V_26]] to %[[V_24]] : !fir.ref<i8>
call ieee_get_rounding_mode(round_value)
- ! CHECK: %[[V_32:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_33:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_32]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_32:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_33:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_32]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: fir.store %c3{{.*}} to %[[V_33]] : !fir.ref<i8>
- ! CHECK: %[[V_34:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_35:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_34]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_34:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_35:[0-9]+]] = fir.coordinate_of %[[V_0]], %[[V_34]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_36:[0-9]+]] = fir.load %[[V_35]] : !fir.ref<i8>
! CHECK: %[[V_37:[0-9]+]] = fir.convert %[[V_36]] : (i8) -> i32
! CHECK: fir.call @llvm.set.rounding(%[[V_37]]) {{.*}} : (i32) -> ()
call ieee_set_rounding_mode(ieee_down)
print*, 'ok'
- ! CHECK: %[[V_46:[0-9]+]] = fir.field_index _QMieee_arithmeticTieee_round_type.mode, !fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>
- ! CHECK: %[[V_47:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_46]] : (!fir.ref<!fir.type<_QMieee_arithmeticTieee_round_type{_QMieee_arithmeticTieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
+ ! CHECK: %[[V_46:[0-9]+]] = fir.field_index _QM__fortran_builtinsT__builtin_ieee_round_type.mode, !fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>
+ ! CHECK: %[[V_47:[0-9]+]] = fir.coordinate_of %[[V_2]], %[[V_46]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_ieee_round_type{_QM__fortran_builtinsT__builtin_ieee_round_type.mode:i8}>>, !fir.field) -> !fir.ref<i8>
! CHECK: %[[V_48:[0-9]+]] = fir.load %[[V_47]] : !fir.ref<i8>
! CHECK: %[[V_49:[0-9]+]] = fir.convert %[[V_48]] : (i8) -> i32
! CHECK: fir.call @llvm.set.rounding(%[[V_49]]) {{.*}} : (i32) -> ()
diff --git a/flang/test/Lower/Intrinsics/reduce.f90 b/flang/test/Lower/Intrinsics/reduce.f90
new file mode 100644
index 000000000000..8d7ec89d2747
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/reduce.f90
@@ -0,0 +1,877 @@
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+
+module reduce_mod
+
+type :: t1
+ integer :: a
+end type
+
+ abstract interface
+ pure function red_int1_interface(a, b)
+ integer(1), intent(in) :: a, b
+ integer(1) :: red_int1_interface
+ end function
+ pure function red_int1_interface_value(a, b)
+ integer(1), value, intent(in) :: a, b
+ integer(1) :: red_int1_interface_value
+ end function
+ end interface
+
+contains
+
+pure function red_int1(a,b)
+ integer(1), intent(in) :: a, b
+ integer(1) :: red_int1
+ red_int1 = a + b
+end function
+
+pure function red_int1_value(a,b)
+ integer(1), value, intent(in) :: a, b
+ integer(1) :: red_int1_value
+ red_int1_value = a + b
+end function
+
+subroutine integer1(a, id, d1, d2)
+ integer(1), intent(in) :: a(:)
+ integer(1) :: res, id
+ procedure(red_int1_interface), pointer :: fptr
+ procedure(red_int1_interface_value), pointer :: fptr_value
+ procedure(red_int1_interface) :: d1
+ procedure(red_int1_interface_value) :: d2
+
+ res = reduce(a, red_int1)
+
+ res = reduce(a, red_int1, identity=id)
+
+ res = reduce(a, red_int1, identity=id, ordered = .true.)
+
+ res = reduce(a, red_int1, [.true., .true., .false.])
+
+ res = reduce(a, red_int1_value)
+
+ fptr => red_int1
+ res = reduce(a, fptr)
+
+ fptr_value => red_int1_value
+ res = reduce(a, fptr_value)
+
+ !res = reduce(a, d1)
+ !res = reduce(a, d2)
+end subroutine
+
+! CHECK-LABEL: func.func @_QMreduce_modPinteger1(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?xi8>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<i8> {fir.bindc_name = "id"}
+! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMreduce_modFinteger1Ea"} : (!fir.box<!fir.array<?xi8>>, !fir.dscope) -> (!fir.box<!fir.array<?xi8>>, !fir.box<!fir.array<?xi8>>)
+! CHECK: %[[ID:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{.*}} {uniq_name = "_QMreduce_modFinteger1Eid"} : (!fir.ref<i8>, !fir.dscope) -> (!fir.ref<i8>, !fir.ref<i8>)
+! CHECK: %[[ALLOC_RES:.*]] = fir.alloca i8 {bindc_name = "res", uniq_name = "_QMreduce_modFinteger1Eres"}
+! CHECK: %[[RES:.*]]:2 = hlfir.declare %[[ALLOC_RES]] {uniq_name = "_QMreduce_modFinteger1Eres"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>)
+! CHECK: %[[ADDR_OP:.*]] = fir.address_of(@_QMreduce_modPred_int1) : (!fir.ref<i8>, !fir.ref<i8>) -> i8
+! CHECK: %[[BOX_PROC:.*]] = fir.emboxproc %[[ADDR_OP]] : ((!fir.ref<i8>, !fir.ref<i8>) -> i8) -> !fir.boxproc<() -> ()>
+! CHECK: %[[MASK:.*]] = fir.absent !fir.box<i1>
+! CHECK: %[[IDENTITY:.*]] = fir.absent !fir.ref<i8>
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_PROC]] : (!fir.boxproc<() -> ()>) -> ((!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>)
+! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]]#1 : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
+! CHECK: %[[MASK_NONE:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
+! CHECK: %[[REDUCE_RES:.*]] = fir.call @_FortranAReduceInteger1Ref(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[IDENTITY]], %false) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
+! CHECK: hlfir.assign %[[REDUCE_RES]] to %[[RES]]#0 : i8, !fir.ref<i8>
+! CHECK: %[[ADDR_OP:.*]] = fir.address_of(@_QMreduce_modPred_int1) : (!fir.ref<i8>, !fir.ref<i8>) -> i8
+! CHECK: %[[BOX_PROC:.*]] = fir.emboxproc %[[ADDR_OP]] : ((!fir.ref<i8>, !fir.ref<i8>) -> i8) -> !fir.boxproc<() -> ()>
+! CHECK: %[[MASK:.*]] = fir.absent !fir.box<i1>
+! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_PROC]] : (!fir.boxproc<() -> ()>) -> ((!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>)
+! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]]#1 : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
+! CHECK: %[[MASK_NONE:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
+! CHECK: %{{.*}} = fir.call @_FortranAReduceInteger1Ref(%[[A_NONE]], %[[BOX_ADDR]], %{{.*}}, %{{.*}}, %c1{{.*}}, %[[MASK_NONE]], %[[ID]]#1, %false{{.*}}) fastmath<contract> : (!fir.box<none>, (!fir.ref<i8>, !fir.ref<i8>) -> !fir.ref<i8>, !fir.ref<i8>, i32, i32, !fir.box<none>, !fir.ref<i8>, i1) -> i8
+! CHECK: fir.call @_FortranAReduceInteger1Ref(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}#1, %true)
+! CHECK: %[[MASK:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro.3xl4.0"} : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.ref<!fir.array<3x!fir.logical<4>>>)
+! CHECK: %[[SHAPE_C3:.*]] = fir.shape %c3{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[BOXED_MASK:.*]] = fir.embox %[[MASK]]#1(%[[SHAPE_C3]]) : (!fir.ref<!fir.array<3x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<3x!fir.logical<4>>>
+! CHECK: %[[CONV_MASK:.*]] = fir.convert %[[BOXED_MASK]] : (!fir.box<!fir.array<3x!fir.logical<4>>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranAReduceInteger1Ref(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[CONV_MASK]], %{{.*}}, %false{{.*}})
+! CHECK: fir.call @_FortranAReduceInteger1Value
+! CHECK: fir.call @_FortranAReduceInteger1Ref
+! CHECK: fir.call @_FortranAReduceInteger1Value
+! TODO fir.call @_FortranAReduceInteger1Ref
+! TODO fir.call @_FortranAReduceInteger1Value
+
+pure function red_int2(a,b)
+ integer(2), intent(in) :: a, b
+ integer(2) :: red_int2
+ red_int2 = a + b
+end function
+
+pure function red_int2_value(a,b)
+ integer(2), value, intent(in) :: a, b
+ integer(2) :: red_int2_value
+ red_int2_value = a + b
+end function
+
+subroutine integer2(a)
+ integer(2), intent(in) :: a(:)
+ integer(2) :: res
+ res = reduce(a, red_int2)
+ res = reduce(a, red_int2_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger2Ref
+! CHECK: fir.call @_FortranAReduceInteger2Value
+
+pure function red_int4(a,b)
+ integer(4), intent(in) :: a, b
+ integer(4) :: red_int4
+ red_int4 = a + b
+end function
+
+pure function red_int4_value(a,b)
+ integer(4), value, intent(in) :: a, b
+ integer(4) :: red_int4_value
+ red_int4_value = a + b
+end function
+
+subroutine integer4(a)
+ integer(4), intent(in) :: a(:)
+ integer(4) :: res
+ res = reduce(a, red_int4)
+ res = reduce(a, red_int4_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger4Ref
+! CHECK: fir.call @_FortranAReduceInteger4Value
+
+pure function red_int8(a,b)
+ integer(8), intent(in) :: a, b
+ integer(8) :: red_int8
+ red_int8 = a + b
+end function
+
+pure function red_int8_value(a,b)
+ integer(8), value, intent(in) :: a, b
+ integer(8) :: red_int8_value
+ red_int8_value = a + b
+end function
+
+subroutine integer8(a)
+ integer(8), intent(in) :: a(:)
+ integer(8) :: res
+ res = reduce(a, red_int8)
+ res = reduce(a, red_int8_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger8Ref
+! CHECK: fir.call @_FortranAReduceInteger8Value
+
+pure function red_int16(a,b)
+ integer(16), intent(in) :: a, b
+ integer(16) :: red_int16
+ red_int16 = a + b
+end function
+
+pure function red_int16_value(a,b)
+ integer(16), value, intent(in) :: a, b
+ integer(16) :: red_int16_value
+ red_int16_value = a + b
+end function
+
+subroutine integer16(a)
+ integer(16), intent(in) :: a(:)
+ integer(16) :: res
+ res = reduce(a, red_int16)
+ res = reduce(a, red_int16_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger16Ref
+! CHECK: fir.call @_FortranAReduceInteger16Value
+
+pure function red_real2(a,b)
+ real(2), intent(in) :: a, b
+ real(2) :: red_real2
+ red_real2 = a + b
+end function
+
+pure function red_real2_value(a,b)
+ real(2), value, intent(in) :: a, b
+ real(2) :: red_real2_value
+ red_real2_value = a + b
+end function
+
+subroutine real2(a)
+ real(2), intent(in) :: a(:)
+ real(2) :: res
+ res = reduce(a, red_real2)
+ res = reduce(a, red_real2_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal2Ref
+! CHECK: fir.call @_FortranAReduceReal2Value
+
+pure function red_real3(a,b)
+ real(3), intent(in) :: a, b
+ real(3) :: red_real3
+ red_real3 = a + b
+end function
+
+pure function red_real3_value(a,b)
+ real(3), value, intent(in) :: a, b
+ real(3) :: red_real3_value
+ red_real3_value = a + b
+end function
+
+subroutine real3(a)
+ real(3), intent(in) :: a(:)
+ real(3) :: res
+ res = reduce(a, red_real3)
+ res = reduce(a, red_real3_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal3Ref
+! CHECK: fir.call @_FortranAReduceReal3Value
+
+pure function red_real4(a,b)
+ real(4), intent(in) :: a, b
+ real(4) :: red_real4
+ red_real4 = a + b
+end function
+
+pure function red_real4_value(a,b)
+ real(4), value, intent(in) :: a, b
+ real(4) :: red_real4_value
+ red_real4_value = a + b
+end function
+
+subroutine real4(a)
+ real(4), intent(in) :: a(:)
+ real(4) :: res
+ res = reduce(a, red_real4)
+ res = reduce(a, red_real4_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal4Ref
+! CHECK: fir.call @_FortranAReduceReal4Value
+
+pure function red_real8(a,b)
+ real(8), intent(in) :: a, b
+ real(8) :: red_real8
+ red_real8 = a + b
+end function
+
+pure function red_real8_value(a,b)
+ real(8), value, intent(in) :: a, b
+ real(8) :: red_real8_value
+ red_real8_value = a + b
+end function
+
+subroutine real8(a)
+ real(8), intent(in) :: a(:)
+ real(8) :: res
+ res = reduce(a, red_real8)
+ res = reduce(a, red_real8_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal8Ref
+! CHECK: fir.call @_FortranAReduceReal8Value
+
+pure function red_real10(a,b)
+ real(10), intent(in) :: a, b
+ real(10) :: red_real10
+ red_real10 = a + b
+end function
+
+pure function red_real10_value(a,b)
+ real(10), value, intent(in) :: a, b
+ real(10) :: red_real10_value
+ red_real10_value = a + b
+end function
+
+subroutine real10(a)
+ real(10), intent(in) :: a(:)
+ real(10) :: res
+ res = reduce(a, red_real10)
+ res = reduce(a, red_real10_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal10Ref
+! CHECK: fir.call @_FortranAReduceReal10Value
+
+pure function red_real16(a,b)
+ real(16), intent(in) :: a, b
+ real(16) :: red_real16
+ red_real16 = a + b
+end function
+
+pure function red_real16_value(a,b)
+ real(16), value, intent(in) :: a, b
+ real(16) :: red_real16_value
+ red_real16_value = a + b
+end function
+
+subroutine real16(a)
+ real(16), intent(in) :: a(:)
+ real(16) :: res
+ res = reduce(a, red_real16)
+ res = reduce(a, red_real16_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal16Ref
+! CHECK: fir.call @_FortranAReduceReal16Value
+
+pure function red_complex2(a,b)
+ complex(2), intent(in) :: a, b
+ complex(2) :: red_complex2
+ red_complex2 = a + b
+end function
+
+pure function red_complex2_value(a,b)
+ complex(2), value, intent(in) :: a, b
+ complex(2) :: red_complex2_value
+ red_complex2_value = a + b
+end function
+
+subroutine complex2(a)
+ complex(2), intent(in) :: a(:)
+ complex(2) :: res
+ res = reduce(a, red_complex2)
+ res = reduce(a, red_complex2_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex2Ref
+! CHECK: fir.call @_FortranACppReduceComplex2Value
+
+pure function red_complex3(a,b)
+ complex(3), intent(in) :: a, b
+ complex(3) :: red_complex3
+ red_complex3 = a + b
+end function
+
+pure function red_complex3_value(a,b)
+ complex(3), value, intent(in) :: a, b
+ complex(3) :: red_complex3_value
+ red_complex3_value = a + b
+end function
+
+subroutine complex3(a)
+ complex(3), intent(in) :: a(:)
+ complex(3) :: res
+ res = reduce(a, red_complex3)
+ res = reduce(a, red_complex3_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex3Ref
+! CHECK: fir.call @_FortranACppReduceComplex3Value
+
+pure function red_complex4(a,b)
+ complex(4), intent(in) :: a, b
+ complex(4) :: red_complex4
+ red_complex4 = a + b
+end function
+
+pure function red_complex4_value(a,b)
+ complex(4), value, intent(in) :: a, b
+ complex(4) :: red_complex4_value
+ red_complex4_value = a + b
+end function
+
+subroutine complex4(a)
+ complex(4), intent(in) :: a(:)
+ complex(4) :: res
+ res = reduce(a, red_complex4)
+ res = reduce(a, red_complex4_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex4Ref
+! CHECK: fir.call @_FortranACppReduceComplex4Value
+
+pure function red_complex8(a,b)
+ complex(8), intent(in) :: a, b
+ complex(8) :: red_complex8
+ red_complex8 = a + b
+end function
+
+pure function red_complex8_value(a,b)
+ complex(8), value, intent(in) :: a, b
+ complex(8) :: red_complex8_value
+ red_complex8_value = a + b
+end function
+
+subroutine complex8(a)
+ complex(8), intent(in) :: a(:)
+ complex(8) :: res
+ res = reduce(a, red_complex8)
+ res = reduce(a, red_complex8_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex8Ref
+! CHECK: fir.call @_FortranACppReduceComplex8Value
+
+pure function red_complex10(a,b)
+ complex(10), intent(in) :: a, b
+ complex(10) :: red_complex10
+ red_complex10 = a + b
+end function
+
+pure function red_complex10_value(a,b)
+ complex(10), value, intent(in) :: a, b
+ complex(10) :: red_complex10_value
+ red_complex10_value = a + b
+end function
+
+subroutine complex10(a)
+ complex(10), intent(in) :: a(:)
+ complex(10) :: res
+ res = reduce(a, red_complex10)
+ res = reduce(a, red_complex10_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex10Ref
+! CHECK: fir.call @_FortranACppReduceComplex10Value
+
+pure function red_complex16(a,b)
+ complex(16), intent(in) :: a, b
+ complex(16) :: red_complex16
+ red_complex16 = a + b
+end function
+
+pure function red_complex16_value(a,b)
+ complex(16), value, intent(in) :: a, b
+ complex(16) :: red_complex16_value
+ red_complex16_value = a + b
+end function
+
+subroutine complex16(a)
+ complex(16), intent(in) :: a(:)
+ complex(16) :: res
+ res = reduce(a, red_complex16)
+ res = reduce(a, red_complex16_value)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex16Ref
+! CHECK: fir.call @_FortranACppReduceComplex16Value
+
+pure function red_log1(a,b)
+ logical(1), intent(in) :: a, b
+ logical(1) :: red_log1
+ red_log1 = a .and. b
+end function
+
+pure function red_log1_value(a,b)
+ logical(1), value, intent(in) :: a, b
+ logical(1) :: red_log1_value
+ red_log1_value = a .and. b
+end function
+
+subroutine log1(a)
+ logical(1), intent(in) :: a(:)
+ logical(1) :: res
+ res = reduce(a, red_log1)
+ res = reduce(a, red_log1_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical1Ref
+! CHECK: fir.call @_FortranAReduceLogical1Value
+
+pure function red_log2(a,b)
+ logical(2), intent(in) :: a, b
+ logical(2) :: red_log2
+ red_log2 = a .and. b
+end function
+
+pure function red_log2_value(a,b)
+ logical(2), value, intent(in) :: a, b
+ logical(2) :: red_log2_value
+ red_log2_value = a .and. b
+end function
+
+subroutine log2(a)
+ logical(2), intent(in) :: a(:)
+ logical(2) :: res
+ res = reduce(a, red_log2)
+ res = reduce(a, red_log2_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical2Ref
+! CHECK: fir.call @_FortranAReduceLogical2Value
+
+pure function red_log4(a,b)
+ logical(4), intent(in) :: a, b
+ logical(4) :: red_log4
+ red_log4 = a .and. b
+end function
+
+pure function red_log4_value(a,b)
+ logical(4), value, intent(in) :: a, b
+ logical(4) :: red_log4_value
+ red_log4_value = a .and. b
+end function
+
+subroutine log4(a)
+ logical(4), intent(in) :: a(:)
+ logical(4) :: res
+ res = reduce(a, red_log4)
+ res = reduce(a, red_log4_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical4Ref
+! CHECK: fir.call @_FortranAReduceLogical4Value
+
+pure function red_log8(a,b)
+ logical(8), intent(in) :: a, b
+ logical(8) :: red_log8
+ red_log8 = a .and. b
+end function
+
+pure function red_log8_value(a,b)
+ logical(8), value, intent(in) :: a, b
+ logical(8) :: red_log8_value
+ red_log8_value = a .and. b
+end function
+
+subroutine log8(a)
+ logical(8), intent(in) :: a(:)
+ logical(8) :: res
+ res = reduce(a, red_log8)
+ res = reduce(a, red_log8_value)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical8Ref
+! CHECK: fir.call @_FortranAReduceLogical8Value
+
+pure function red_char1(a,b)
+ character(1), intent(in) :: a, b
+ character(1) :: red_char1
+ red_char1 = a // b
+end function
+
+subroutine char1(a)
+ character(1), intent(in) :: a(:)
+ character(1) :: res
+ res = reduce(a, red_char1)
+end subroutine
+
+! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<1> {bindc_name = ".chrtmp"}
+! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
+! CHECK: fir.call @_FortranAReduceChar1(%[[RESULT]], {{.*}})
+
+pure function red_char2(a,b)
+ character(kind=2, len=10), intent(in) :: a, b
+ character(kind=2, len=10) :: red_char2
+ red_char2 = a // b
+end function
+
+subroutine char2(a)
+ character(kind=2, len=10), intent(in) :: a(:)
+ character(kind=2, len=10) :: res
+ res = reduce(a, red_char2)
+end subroutine
+
+! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<2,10> {bindc_name = ".chrtmp"}
+! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<2,10>>) -> !fir.ref<i16>
+! CHECK: fir.call @_FortranAReduceChar2(%[[RESULT]], {{.*}})
+
+pure function red_char4(a,b)
+ character(kind=4), intent(in) :: a, b
+ character(kind=4) :: red_char4
+ red_char4 = a // b
+end function
+
+subroutine char4(a)
+ character(kind=4), intent(in) :: a(:)
+ character(kind=4) :: res
+ res = reduce(a, red_char4)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceChar4
+
+pure function red_type(a,b)
+ type(t1), intent(in) :: a, b
+ type(t1) :: red_type
+ red_type%a = a%a + b%a
+end function
+
+subroutine testtype(a)
+ type(t1), intent(in) :: a(:)
+ type(t1) :: res
+ res = reduce(a, red_type)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceDerivedType
+
+subroutine integer1dim(a, id)
+ integer(1), intent(in) :: a(:,:)
+ integer(1), allocatable :: res(:)
+
+ res = reduce(a, red_int1, 2)
+ res = reduce(a, red_int1_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger1DimRef
+! CHECK: fir.call @_FortranAReduceInteger1DimValue
+
+subroutine integer2dim(a, id)
+ integer(2), intent(in) :: a(:,:)
+ integer(2), allocatable :: res(:)
+
+ res = reduce(a, red_int2, 2)
+ res = reduce(a, red_int2_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger2DimRef
+! CHECK: fir.call @_FortranAReduceInteger2DimValue
+
+subroutine integer4dim(a, id)
+ integer(4), intent(in) :: a(:,:)
+ integer(4), allocatable :: res(:)
+
+ res = reduce(a, red_int4, 2)
+ res = reduce(a, red_int4_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger4DimRef
+! CHECK: fir.call @_FortranAReduceInteger4DimValue
+
+subroutine integer8dim(a, id)
+ integer(8), intent(in) :: a(:,:)
+ integer(8), allocatable :: res(:)
+
+ res = reduce(a, red_int8, 2)
+ res = reduce(a, red_int8_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger8DimRef
+! CHECK: fir.call @_FortranAReduceInteger8DimValue
+
+subroutine integer16dim(a, id)
+ integer(16), intent(in) :: a(:,:)
+ integer(16), allocatable :: res(:)
+
+ res = reduce(a, red_int16, 2)
+ res = reduce(a, red_int16_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceInteger16DimRef
+! CHECK: fir.call @_FortranAReduceInteger16DimValue
+
+subroutine real2dim(a, id)
+ real(2), intent(in) :: a(:,:)
+ real(2), allocatable :: res(:)
+
+ res = reduce(a, red_real2, 2)
+ res = reduce(a, red_real2_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal2DimRef
+! CHECK: fir.call @_FortranAReduceReal2DimValue
+
+subroutine real3dim(a, id)
+ real(3), intent(in) :: a(:,:)
+ real(3), allocatable :: res(:)
+
+ res = reduce(a, red_real3, 2)
+ res = reduce(a, red_real3_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal3DimRef
+! CHECK: fir.call @_FortranAReduceReal3DimValue
+
+subroutine real4dim(a, id)
+ real(4), intent(in) :: a(:,:)
+ real(4), allocatable :: res(:)
+
+ res = reduce(a, red_real4, 2)
+ res = reduce(a, red_real4_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal4DimRef
+! CHECK: fir.call @_FortranAReduceReal4DimValue
+
+subroutine real8dim(a, id)
+ real(8), intent(in) :: a(:,:)
+ real(8), allocatable :: res(:)
+
+ res = reduce(a, red_real8, 2)
+ res = reduce(a, red_real8_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal8DimRef
+! CHECK: fir.call @_FortranAReduceReal8DimValue
+
+subroutine real10dim(a, id)
+ real(10), intent(in) :: a(:,:)
+ real(10), allocatable :: res(:)
+
+ res = reduce(a, red_real10, 2)
+ res = reduce(a, red_real10_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal10DimRef
+! CHECK: fir.call @_FortranAReduceReal10DimValue
+
+subroutine real16dim(a, id)
+ real(16), intent(in) :: a(:,:)
+ real(16), allocatable :: res(:)
+
+ res = reduce(a, red_real16, 2)
+ res = reduce(a, red_real16_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceReal16DimRef
+! CHECK: fir.call @_FortranAReduceReal16DimValue
+
+subroutine complex2dim(a, id)
+ complex(2), intent(in) :: a(:,:)
+ complex(2), allocatable :: res(:)
+
+ res = reduce(a, red_complex2, 2)
+ res = reduce(a, red_complex2_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex2DimRef
+! CHECK: fir.call @_FortranACppReduceComplex2DimValue
+
+subroutine complex3dim(a, id)
+ complex(3), intent(in) :: a(:,:)
+ complex(3), allocatable :: res(:)
+
+ res = reduce(a, red_complex3, 2)
+ res = reduce(a, red_complex3_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex3DimRef
+! CHECK: fir.call @_FortranACppReduceComplex3DimValue
+
+subroutine complex4dim(a, id)
+ complex(4), intent(in) :: a(:,:)
+ complex(4), allocatable :: res(:)
+
+ res = reduce(a, red_complex4, 2)
+ res = reduce(a, red_complex4_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex4DimRef
+! CHECK: fir.call @_FortranACppReduceComplex4DimValue
+
+subroutine complex8dim(a, id)
+ complex(8), intent(in) :: a(:,:)
+ complex(8), allocatable :: res(:)
+
+ res = reduce(a, red_complex8, 2)
+ res = reduce(a, red_complex8_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex8DimRef
+! CHECK: fir.call @_FortranACppReduceComplex8DimValue
+
+subroutine complex10dim(a, id)
+ complex(10), intent(in) :: a(:,:)
+ complex(10), allocatable :: res(:)
+
+ res = reduce(a, red_complex10, 2)
+ res = reduce(a, red_complex10_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex10DimRef
+! CHECK: fir.call @_FortranACppReduceComplex10DimValue
+
+subroutine complex16dim(a, id)
+ complex(16), intent(in) :: a(:,:)
+ complex(16), allocatable :: res(:)
+
+ res = reduce(a, red_complex16, 2)
+ res = reduce(a, red_complex16_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranACppReduceComplex16DimRef
+! CHECK: fir.call @_FortranACppReduceComplex16DimValue
+
+subroutine logical1dim(a, id)
+ logical(1), intent(in) :: a(:,:)
+ logical(1), allocatable :: res(:)
+
+ res = reduce(a, red_log1, 2)
+ res = reduce(a, red_log1_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical1DimRef
+! CHECK: fir.call @_FortranAReduceLogical1DimValue
+
+subroutine logical2dim(a, id)
+ logical(2), intent(in) :: a(:,:)
+ logical(2), allocatable :: res(:)
+
+ res = reduce(a, red_log2, 2)
+ res = reduce(a, red_log2_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical2DimRef
+! CHECK: fir.call @_FortranAReduceLogical2DimValue
+
+subroutine logical4dim(a, id)
+ logical(4), intent(in) :: a(:,:)
+ logical(4), allocatable :: res(:)
+
+ res = reduce(a, red_log4, 2)
+ res = reduce(a, red_log4_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical4DimRef
+! CHECK: fir.call @_FortranAReduceLogical4DimValue
+
+subroutine logical8dim(a, id)
+ logical(8), intent(in) :: a(:,:)
+ logical(8), allocatable :: res(:)
+
+ res = reduce(a, red_log8, 2)
+ res = reduce(a, red_log8_value, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceLogical8DimRef
+! CHECK: fir.call @_FortranAReduceLogical8DimValue
+
+subroutine testtypeDim(a)
+ type(t1), intent(in) :: a(:,:)
+ type(t1), allocatable :: res(:)
+ res = reduce(a, red_type, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceDerivedTypeDim
+
+subroutine char1dim(a)
+ character(1), intent(in) :: a(:, :)
+ character(1), allocatable :: res(:)
+ res = reduce(a, red_char1, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceCharacter1Dim
+
+subroutine char2dim(a)
+ character(kind=2, len=10), intent(in) :: a(:, :)
+ character(kind=2, len=10), allocatable :: res(:)
+ res = reduce(a, red_char2, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceCharacter2Dim
+
+subroutine char4dim(a)
+ character(kind=4), intent(in) :: a(:, :)
+ character(kind=4), allocatable :: res(:)
+ res = reduce(a, red_char4, 2)
+end subroutine
+
+! CHECK: fir.call @_FortranAReduceCharacter4Dim
+
+pure function red_char_dyn(a, b)
+ character(*), intent(In) :: a, b
+ character(max(len(a),len(b))) :: red_char_dyn
+ red_char_dyn = max(a, b)
+end function
+
+subroutine charDyn()
+ character(5) :: res
+ character(:), allocatable :: a(:)
+ allocate(character(10)::a(10))
+ res = reduce(a, red_char_dyn)
+end subroutine
+
+! CHECK: %[[BOX_ELESIZE:.*]] = fir.box_elesize %{{.*}} : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> index
+! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<1,?>(%[[BOX_ELESIZE]] : index) {bindc_name = ".chrtmp"}
+! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
+! CHECK: fir.call @_FortranAReduceChar1(%[[RESULT]], {{.*}})
+
+end module
diff --git a/flang/test/Lower/Intrinsics/ubound01.f90 b/flang/test/Lower/Intrinsics/ubound01.f90
index df51d79eb6af..e933075cc0bf 100644
--- a/flang/test/Lower/Intrinsics/ubound01.f90
+++ b/flang/test/Lower/Intrinsics/ubound01.f90
@@ -20,4 +20,4 @@ end
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>>
! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]](%{{.*}}) : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
+! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr<i8>, !fir.box<none>, i32, !fir.ref<i8>, i32) -> none
diff --git a/flang/test/Lower/OpenMP/Todo/loop-directive.f90 b/flang/test/Lower/OpenMP/Todo/loop-directive.f90
new file mode 100644
index 000000000000..f1aea70458aa
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/loop-directive.f90
@@ -0,0 +1,15 @@
+! This test checks lowering of OpenMP loop Directive.
+
+! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: Unhandled directive loop
+subroutine test_loop()
+ integer :: i, j = 1
+ !$omp loop
+ do i=1,10
+ j = j + 1
+ end do
+ !$omp end loop
+end subroutine
+
diff --git a/flang/test/Lower/OpenMP/Todo/reduction-array-intrinsic.f90 b/flang/test/Lower/OpenMP/Todo/reduction-array-intrinsic.f90
deleted file mode 100644
index 49c899238d2a..000000000000
--- a/flang/test/Lower/OpenMP/Todo/reduction-array-intrinsic.f90
+++ /dev/null
@@ -1,11 +0,0 @@
-! RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
-
-! CHECK: not yet implemented: Reduction of some types is not supported for intrinsics
-subroutine max_array_reduction(l, r)
- integer :: l(:), r(:)
-
- !$omp parallel reduction(max:l)
- l = max(l, r)
- !$omp end parallel
-end subroutine
diff --git a/flang/test/Lower/OpenMP/Todo/reduction-derived-type-field.f90 b/flang/test/Lower/OpenMP/Todo/reduction-derived-type-field.f90
index 8bded2fdb746..051f529c8131 100644
--- a/flang/test/Lower/OpenMP/Todo/reduction-derived-type-field.f90
+++ b/flang/test/Lower/OpenMP/Todo/reduction-derived-type-field.f90
@@ -1,7 +1,8 @@
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-! CHECK: not yet implemented: Reduction of some types is not supported
+! There's no definition of '+' for type(t)
+! CHECK: The type of 'mt' is incompatible with the reduction operator.
subroutine reduction_allocatable
type t
integer :: x
diff --git a/flang/test/Lower/OpenMP/common-block-map.f90 b/flang/test/Lower/OpenMP/common-block-map.f90
new file mode 100644
index 000000000000..5033129683a8
--- /dev/null
+++ b/flang/test/Lower/OpenMP/common-block-map.f90
@@ -0,0 +1,83 @@
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+!CHECK: fir.global common @var_common_(dense<0> : vector<8xi8>) {{.*}} : !fir.array<8xi8>
+!CHECK: fir.global common @var_common_link_(dense<0> : vector<8xi8>) {{{.*}} omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<8xi8>
+
+!CHECK-LABEL: func.func @_QPmap_full_block
+!CHECK: %[[CB_ADDR:.*]] = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
+!CHECK: %[[MAP:.*]] = omp.map.info var_ptr(%[[CB_ADDR]] : !fir.ref<!fir.array<8xi8>>, !fir.array<8xi8>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.array<8xi8>> {name = "var_common"}
+!CHECK: omp.target map_entries(%[[MAP]] -> %[[MAP_ARG:.*]] : !fir.ref<!fir.array<8xi8>>) {
+!CHECK: ^bb0(%[[MAP_ARG]]: !fir.ref<!fir.array<8xi8>>):
+!CHECK: %[[CONV:.*]] = fir.convert %[[MAP_ARG]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX:.*]] = arith.constant 0 : index
+!CHECK: %[[COORD:.*]] = fir.coordinate_of %[[CONV]], %[[INDEX]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV2:.*]] = fir.convert %[[COORD]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[CB_MEMBER_1:.*]]:2 = hlfir.declare %[[CONV2]] {uniq_name = "_QFmap_full_blockEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[CONV3:.*]] = fir.convert %[[MAP_ARG]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX2:.*]] = arith.constant 4 : index
+!CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[CONV3]], %[[INDEX2]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV4:.*]] = fir.convert %[[COORD2]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[CB_MEMBER_2:.*]]:2 = hlfir.declare %[[CONV4]] {uniq_name = "_QFmap_full_blockEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+subroutine map_full_block
+ implicit none
+ common /var_common/ var1, var2
+ integer :: var1, var2
+!$omp target map(tofrom: /var_common/)
+ var1 = var1 + 20
+ var2 = var2 + 30
+!$omp end target
+end
+
+!CHECK-LABEL: @_QPmap_mix_of_members
+!CHECK: %[[COMMON_BLOCK:.*]] = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
+!CHECK: %[[CB_CONV:.*]] = fir.convert %[[COMMON_BLOCK]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX:.*]] = arith.constant 0 : index
+!CHECK: %[[COORD:.*]] = fir.coordinate_of %[[CB_CONV]], %[[INDEX]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV:.*]] = fir.convert %[[COORD]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[CB_MEMBER_1:.*]]:2 = hlfir.declare %[[CONV]] {uniq_name = "_QFmap_mix_of_membersEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[CB_CONV:.*]] = fir.convert %[[COMMON_BLOCK]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX:.*]] = arith.constant 4 : index
+!CHECK: %[[COORD:.*]] = fir.coordinate_of %[[CB_CONV]], %[[INDEX]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV:.*]] = fir.convert %[[COORD]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[CB_MEMBER_2:.*]]:2 = hlfir.declare %[[CONV]] {uniq_name = "_QFmap_mix_of_membersEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[MAP_EXP:.*]] = omp.map.info var_ptr(%[[CB_MEMBER_2]]#0 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var2"}
+!CHECK: %[[MAP_IMP:.*]] = omp.map.info var_ptr(%[[CB_MEMBER_1]]#1 : !fir.ref<i32>, i32) map_clauses(implicit, exit_release_or_enter_alloc) capture(ByCopy) -> !fir.ref<i32> {name = "var1"}
+!CHECK: omp.target map_entries(%[[MAP_EXP]] -> %[[ARG_EXP:.*]], %[[MAP_IMP]] -> %[[ARG_IMP:.*]] : !fir.ref<i32>, !fir.ref<i32>) {
+!CHECK: ^bb0(%[[ARG_EXP]]: !fir.ref<i32>, %[[ARG_IMP]]: !fir.ref<i32>):
+!CHECK: %[[EXP_MEMBER:.*]]:2 = hlfir.declare %[[ARG_EXP]] {uniq_name = "_QFmap_mix_of_membersEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[IMP_MEMBER:.*]]:2 = hlfir.declare %[[ARG_IMP]] {uniq_name = "_QFmap_mix_of_membersEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+subroutine map_mix_of_members
+ implicit none
+ common /var_common/ var1, var2
+ integer :: var1, var2
+
+!$omp target map(tofrom: var2)
+ var2 = var1
+!$omp end target
+end
+
+!CHECK-LABEL: @_QQmain
+!CHECK: %[[DECL_TAR_CB:.*]] = fir.address_of(@var_common_link_) : !fir.ref<!fir.array<8xi8>>
+!CHECK: %[[MAP_DECL_TAR_CB:.*]] = omp.map.info var_ptr(%[[DECL_TAR_CB]] : !fir.ref<!fir.array<8xi8>>, !fir.array<8xi8>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.array<8xi8>> {name = "var_common_link"}
+!CHECK: omp.target map_entries(%[[MAP_DECL_TAR_CB]] -> %[[MAP_DECL_TAR_ARG:.*]] : !fir.ref<!fir.array<8xi8>>) {
+!CHECK: ^bb0(%[[MAP_DECL_TAR_ARG]]: !fir.ref<!fir.array<8xi8>>):
+!CHECK: %[[CONV:.*]] = fir.convert %[[MAP_DECL_TAR_ARG]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX:.*]] = arith.constant 0 : index
+!CHECK: %[[COORD:.*]] = fir.coordinate_of %[[CONV]], %[[INDEX]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV:.*]] = fir.convert %[[COORD]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[MEMBER_ONE:.*]]:2 = hlfir.declare %[[CONV]] {uniq_name = "_QFElink1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK: %[[CONV:.*]] = fir.convert %[[MAP_DECL_TAR_ARG]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
+!CHECK: %[[INDEX:.*]] = arith.constant 4 : index
+!CHECK: %[[COORD:.*]] = fir.coordinate_of %[[CONV]], %[[INDEX]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+!CHECK: %[[CONV:.*]] = fir.convert %[[COORD]] : (!fir.ref<i8>) -> !fir.ref<i32>
+!CHECK: %[[MEMBER_TWO:.*]]:2 = hlfir.declare %[[CONV]] {uniq_name = "_QFElink2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+program main
+ implicit none
+ common /var_common_link/ link1, link2
+ integer :: link1, link2
+ !$omp declare target link(/var_common_link/)
+
+!$omp target map(tofrom: /var_common_link/)
+ link1 = link2 + 20
+!$omp end target
+end program
diff --git a/flang/test/Lower/OpenMP/copyprivate2.f90 b/flang/test/Lower/OpenMP/copyprivate2.f90
new file mode 100644
index 000000000000..f10d509d805e
--- /dev/null
+++ b/flang/test/Lower/OpenMP/copyprivate2.f90
@@ -0,0 +1,56 @@
+! Test lowering of COPYPRIVATE with allocatable/pointer variables.
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+!CHECK-LABEL: func private @_copy_box_ptr_i32(
+!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>,
+!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>) {
+!CHECK-NEXT: %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<pointer>,
+!CHECK-SAME: uniq_name = "_copy_box_ptr_i32_dst"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-NEXT: %[[SRC:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs<pointer>,
+!CHECK-SAME: uniq_name = "_copy_box_ptr_i32_src"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-NEXT: %[[SRC_VAL:.*]] = fir.load %[[SRC]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-NEXT: fir.store %[[SRC_VAL]] to %[[DST]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-NEXT: return
+!CHECK-NEXT: }
+
+!CHECK-LABEL: func private @_copy_box_heap_Uxi32(
+!CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
+!CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {
+!CHECK-NEXT: %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<allocatable>,
+!CHECK-SAME: uniq_name = "_copy_box_heap_Uxi32_dst"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+!CHECK-NEXT: %[[SRC:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs<allocatable>,
+!CHECK-SAME: uniq_name = "_copy_box_heap_Uxi32_src"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+!CHECK-NEXT: %[[DST_BOX:.*]] = fir.load %[[DST]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+!CHECK: fir.if %{{.*}} {
+!CHECK-NEXT: %[[SRC_BOX:.*]] = fir.load %[[SRC]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+!CHECK-NEXT: hlfir.assign %[[SRC_BOX]] to %[[DST_BOX]] temporary_lhs : !fir.box<!fir.heap<!fir.array<?xi32>>>,
+!CHECK-SAME: !fir.box<!fir.heap<!fir.array<?xi32>>>
+!CHECK-NEXT: }
+!CHECK-NEXT: return
+!CHECK-NEXT: }
+
+!CHECK-LABEL: func @_QPtest_alloc_ptr
+!CHECK: omp.parallel {
+!CHECK: %[[A:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>,
+!CHECK-SAME: uniq_name = "_QFtest_alloc_ptrEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+!CHECK: %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>,
+!CHECK-SAME: uniq_name = "_QFtest_alloc_ptrEp"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK: omp.single copyprivate(
+!CHECK-SAME: %[[A]]#0 -> @_copy_box_heap_Uxi32 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
+!CHECK-SAME: %[[P]]#0 -> @_copy_box_ptr_i32 : !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHEK: }
+subroutine test_alloc_ptr()
+ integer, allocatable :: a(:)
+ integer, pointer :: p
+
+ !$omp parallel private(a, p)
+ !$omp single
+ !$omp end single copyprivate(a, p)
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
index 3d2c4067dab7..0d138321445c 100644
--- a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
+++ b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
@@ -154,7 +154,7 @@ END
!! -----
! DEVICE-LABEL: func.func @_QPrecursive_declare_target
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
!$omp declare target to(RECURSIVE_DECLARE_TARGET) device_type(nohost)
INTEGER :: INCREMENT, K
@@ -166,7 +166,7 @@ RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
END FUNCTION RECURSIVE_DECLARE_TARGET
! DEVICE-LABEL: func.func @_QPrecursive_declare_target_enter
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET_ENTER(INCREMENT) RESULT(K)
!$omp declare target enter(RECURSIVE_DECLARE_TARGET_ENTER) device_type(nohost)
INTEGER :: INCREMENT, K
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
index ed718a485e3d..0ca2bcbd66a9 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
@@ -105,7 +105,7 @@ end function target_function_test_host
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target enter(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
@@ -174,7 +174,7 @@ program mb
end program
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
index df81c43a2fe6..ffca5c3ff250 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
@@ -131,7 +131,7 @@ end function target_function_test_host
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target to(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
@@ -200,7 +200,7 @@ program mb
end program
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
index 7d1ae06c8056..9b85a32036ca 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
@@ -67,7 +67,7 @@ end function target_function_test_device
!! -----
! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_recursive(increment) result(k)
integer :: increment, k
if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/distribute.f90 b/flang/test/Lower/OpenMP/distribute.f90
new file mode 100644
index 000000000000..a4a753dddbac
--- /dev/null
+++ b/flang/test/Lower/OpenMP/distribute.f90
@@ -0,0 +1,114 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPdistribute_simple
+subroutine distribute_simple()
+ ! CHECK: omp.teams
+ !$omp teams
+
+ ! CHECK: omp.distribute {
+ !$omp distribute
+
+ ! CHECK-NEXT: omp.loop_nest
+ do i = 1, 10
+ call foo()
+ ! CHECK: omp.yield
+ end do
+
+ !$omp end distribute
+
+ ! CHECK: omp.terminator
+ !$omp end teams
+end subroutine distribute_simple
+
+!===============================================================================
+! `dist_schedule` clause
+!===============================================================================
+
+! CHECK-LABEL: func @_QPdistribute_dist_schedule
+! CHECK-SAME: %[[X_ARG:.*]]: !fir.ref<i32>
+subroutine distribute_dist_schedule(x)
+ ! CHECK: %[[X_REF:.*]]:2 = hlfir.declare %[[X_ARG]]
+ integer, intent(in) :: x
+
+ ! CHECK: omp.teams
+ !$omp teams
+
+ ! STATIC SCHEDULE, CONSTANT CHUNK SIZE
+
+ ! CHECK: %[[CONST_CHUNK_SIZE:.*]] = arith.constant 5 : i32
+ ! CHECK: omp.distribute
+ ! CHECK-SAME: dist_schedule_static
+ ! CHECK-SAME: chunk_size(%[[CONST_CHUNK_SIZE]] : i32)
+ !$omp distribute dist_schedule(static, 5)
+
+ ! CHECK-NEXT: omp.loop_nest
+ do i = 1, 10
+ call foo()
+ ! CHECK: omp.yield
+ end do
+
+ !$omp end distribute
+
+ ! STATIC SCHEDULE, VARIABLE CHUNK SIZE
+
+ ! CHECK: %[[X:.*]] = fir.load %[[X_REF]]#0
+ ! CHECK: omp.distribute
+ ! CHECK-SAME: dist_schedule_static
+ ! CHECK-SAME: chunk_size(%[[X]] : i32)
+ !$omp distribute dist_schedule(static, x)
+
+ ! CHECK-NEXT: omp.loop_nest
+ do i = 1, 10
+ call foo()
+ ! CHECK: omp.yield
+ end do
+
+ !$omp end distribute
+
+ ! STATIC SCHEDULE, NO CHUNK SIZE
+
+ ! CHECK: omp.distribute
+ ! CHECK-SAME: dist_schedule_static
+ ! CHECK-NOT: chunk_size
+ !$omp distribute dist_schedule(static)
+
+ ! CHECK-NEXT: omp.loop_nest
+ do i = 1, 10
+ call foo()
+ ! CHECK: omp.yield
+ end do
+
+ !$omp end distribute
+
+ ! CHECK: omp.terminator
+ !$omp end teams
+end subroutine distribute_dist_schedule
+
+!===============================================================================
+! `allocate` clause
+!===============================================================================
+
+! CHECK-LABEL: func @_QPdistribute_allocate
+subroutine distribute_allocate()
+ use omp_lib
+ integer :: x
+ ! CHECK: omp.teams
+ !$omp teams
+
+ ! CHECK: omp.distribute
+ ! CHECK-SAME: allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>)
+ !$omp distribute allocate(omp_high_bw_mem_alloc: x) private(x)
+
+ ! CHECK-NEXT: omp.loop_nest
+ do i = 1, 10
+ x = i
+ ! CHECK: omp.yield
+ end do
+
+ !$omp end distribute
+
+ ! CHECK: omp.terminator
+ !$omp end teams
+end subroutine distribute_allocate
diff --git a/flang/test/Lower/OpenMP/function-filtering-2.f90 b/flang/test/Lower/OpenMP/function-filtering-2.f90
index e1d0f72b9f52..f367069efb3d 100644
--- a/flang/test/Lower/OpenMP/function-filtering-2.f90
+++ b/flang/test/Lower/OpenMP/function-filtering-2.f90
@@ -1,6 +1,6 @@
-! RUN: %flang_fc1 -fopenmp -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefix=LLVM %s
+! RUN: %flang_fc1 -fopenmp -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes=LLVM,LLVM-HOST %s
! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck --check-prefix=MLIR %s
-! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefix=LLVM %s
+! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes=LLVM,LLVM-DEVICE %s
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-hlfir %s -o - | FileCheck --check-prefix=MLIR %s
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
@@ -38,7 +38,7 @@ end subroutine no_declaretarget
! MLIR-ALL: return
! LLVM-HOST: define {{.*}} @{{.*}}main{{.*}}(
-! LLVM-HOST-NOT: {{.*}} @{{.*}}__omp_offloading{{.*}}main_{{.*}}(
+! LLVM-HOST: {{.*}} @{{.*}}__omp_offloading{{.*}}main_{{.*}}(
! LLVM-DEVICE-NOT: {{.*}} @{{.*}}main{{.*}}(
! LLVM-DEVICE: define {{.*}} @{{.*}}__omp_offloading{{.*}}main_{{.*}}(
program main
diff --git a/flang/test/Lower/OpenMP/if-clause.f90 b/flang/test/Lower/OpenMP/if-clause.f90
index 7c15c275d8cc..2c9a66e7bc11 100644
--- a/flang/test/Lower/OpenMP/if-clause.f90
+++ b/flang/test/Lower/OpenMP/if-clause.f90
@@ -14,15 +14,12 @@ program main
! - DISTRIBUTE SIMD
! - PARALLEL SECTIONS
! - PARALLEL WORKSHARE
- ! - TARGET PARALLEL
- ! - TARGET TEAMS DISTRIBUTE
! - TARGET TEAMS DISTRIBUTE PARALLEL DO
! - TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TARGET TEAMS DISTRIBUTE SIMD
! - TARGET UPDATE
! - TASKLOOP
! - TASKLOOP SIMD
- ! - TEAMS DISTRIBUTE
! - TEAMS DISTRIBUTE PARALLEL DO
! - TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TEAMS DISTRIBUTE SIMD
@@ -33,18 +30,25 @@ program main
! CHECK: omp.wsloop
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp do simd
do i = 1, 10
end do
!$omp end do simd
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp do simd if(.true.)
do i = 1, 10
end do
!$omp end do simd
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp do simd if(simd: .true.)
do i = 1, 10
end do
@@ -78,6 +82,10 @@ program main
! CHECK: omp.parallel
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do
do i = 1, 10
end do
@@ -85,6 +93,10 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do if(.true.)
do i = 1, 10
end do
@@ -92,6 +104,10 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do if(parallel: .true.)
do i = 1, 10
end do
@@ -106,6 +122,7 @@ program main
! CHECK: omp.wsloop
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd
do i = 1, 10
end do
@@ -114,6 +131,9 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd if(.true.)
do i = 1, 10
end do
@@ -122,6 +142,9 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd if(parallel: .true.) if(simd: .false.)
do i = 1, 10
end do
@@ -132,6 +155,7 @@ program main
! CHECK: omp.wsloop
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd if(parallel: .true.)
do i = 1, 10
end do
@@ -141,6 +165,9 @@ program main
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd if(simd: .true.)
do i = 1, 10
end do
@@ -152,6 +179,7 @@ program main
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp simd
do i = 1, 10
end do
@@ -159,6 +187,7 @@ program main
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
+ ! CHECK-NEXT: omp.loop_nest
!$omp simd if(.true.)
do i = 1, 10
end do
@@ -166,6 +195,7 @@ program main
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
+ ! CHECK-NEXT: omp.loop_nest
!$omp simd if(simd: .true.)
do i = 1, 10
end do
@@ -250,6 +280,10 @@ program main
! CHECK: omp.parallel
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do
do i = 1, 10
end do
@@ -259,6 +293,10 @@ program main
! CHECK-SAME: if({{.*}})
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do if(.true.)
do i = 1, 10
end do
@@ -268,6 +306,10 @@ program main
! CHECK-SAME: if({{.*}})
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do if(target: .true.) if(parallel: .false.)
do i = 1, 10
end do
@@ -278,6 +320,10 @@ program main
! CHECK: omp.parallel
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do if(target: .true.)
do i = 1, 10
end do
@@ -288,6 +334,10 @@ program main
! CHECK-SAME: {
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do if(parallel: .true.)
do i = 1, 10
end do
@@ -305,6 +355,7 @@ program main
! CHECK: omp.wsloop
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd
do i = 1, 10
end do
@@ -315,6 +366,9 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd if(.true.)
do i = 1, 10
end do
@@ -325,6 +379,9 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd if(target: .true.) if(parallel: .false.) &
!$omp& if(simd: .true.)
do i = 1, 10
@@ -339,6 +396,7 @@ program main
! CHECK: omp.wsloop
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd if(target: .true.)
do i = 1, 10
end do
@@ -350,12 +408,62 @@ program main
! CHECK: omp.parallel
! CHECK-SAME: if({{.*}})
! CHECK: omp.wsloop
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd if(parallel: .true.) if(simd: .false.)
do i = 1, 10
end do
!$omp end target parallel do simd
! ----------------------------------------------------------------------------
+ ! TARGET PARALLEL
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ !$omp target parallel
+ i = 1
+ !$omp end target parallel
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ !$omp target parallel if(.true.)
+ i = 1
+ !$omp end target parallel
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ !$omp target parallel if(target: .true.) if(parallel: .false.)
+ i = 1
+ !$omp end target parallel
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.parallel
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ !$omp target parallel if(target: .true.)
+ i = 1
+ !$omp end target parallel
+
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.parallel
+ ! CHECK-SAME: if({{.*}})
+ !$omp target parallel if(parallel: .true.)
+ i = 1
+ !$omp end target parallel
+
+ ! ----------------------------------------------------------------------------
! TARGET SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.target
@@ -364,6 +472,7 @@ program main
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd
do i = 1, 10
end do
@@ -373,6 +482,7 @@ program main
! CHECK-SAME: if({{.*}})
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd if(.true.)
do i = 1, 10
end do
@@ -382,6 +492,7 @@ program main
! CHECK-SAME: if({{.*}})
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd if(target: .true.) if(simd: .false.)
do i = 1, 10
end do
@@ -392,6 +503,7 @@ program main
! CHECK: omp.simd
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd if(target: .true.)
do i = 1, 10
end do
@@ -402,19 +514,91 @@ program main
! CHECK-SAME: {
! CHECK: omp.simd
! CHECK-SAME: if({{.*}})
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd if(simd: .true.)
do i = 1, 10
end do
!$omp end target simd
! ----------------------------------------------------------------------------
- ! TARGET TEAMS
+ ! TARGET TEAMS DISTRIBUTE
! ----------------------------------------------------------------------------
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute if(target: .true.) if(teams: .false.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! CHECK: omp.target
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
! CHECK: omp.target
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.target
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.teams
! CHECK-NOT: if({{.*}})
! CHECK-SAME: {
!$omp target teams
@@ -475,6 +659,43 @@ program main
!$omp end task
! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE
+ ! ----------------------------------------------------------------------------
+ ! CHECK: omp.teams
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ ! CHECK: omp.teams
+ ! CHECK-SAME: if({{.*}})
+ ! CHECK: omp.distribute
+ ! CHECK-NOT: if({{.*}})
+ ! CHECK-SAME: {
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ ! ----------------------------------------------------------------------------
! TEAMS
! ----------------------------------------------------------------------------
! CHECK: omp.teams
diff --git a/flang/test/Lower/OpenMP/loop-combined.f90 b/flang/test/Lower/OpenMP/loop-compound.f90
index 298634b3f6f8..5012008b0767 100644
--- a/flang/test/Lower/OpenMP/loop-combined.f90
+++ b/flang/test/Lower/OpenMP/loop-compound.f90
@@ -1,4 +1,5 @@
-! This test checks lowering of OpenMP combined loop constructs.
+! This test checks lowering of OpenMP compound (combined and composite) loop
+! constructs.
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
@@ -6,24 +7,23 @@
program main
integer :: i
- ! TODO When DISTRIBUTE, TASKLOOP and TEAMS are supported add:
+ ! TODO When composite constructs are supported add:
! - DISTRIBUTE PARALLEL DO SIMD
! - DISTRIBUTE PARALLEL DO
! - DISTRIBUTE SIMD
! - TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TARGET TEAMS DISTRIBUTE PARALLEL DO
! - TARGET TEAMS DISTRIBUTE SIMD
- ! - TARGET TEAMS DISTRIBUTE
! - TASKLOOP SIMD
! - TEAMS DISTRIBUTE PARALLEL DO SIMD
! - TEAMS DISTRIBUTE PARALLEL DO
! - TEAMS DISTRIBUTE SIMD
- ! - TEAMS DISTRIBUTE
! ----------------------------------------------------------------------------
! DO SIMD
! ----------------------------------------------------------------------------
! CHECK: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
!$omp do simd
do i = 1, 10
end do
@@ -34,6 +34,7 @@ program main
! ----------------------------------------------------------------------------
! CHECK: omp.parallel
! CHECK: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do simd
do i = 1, 10
end do
@@ -44,6 +45,7 @@ program main
! ----------------------------------------------------------------------------
! CHECK: omp.parallel
! CHECK: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
!$omp parallel do
do i = 1, 10
end do
@@ -55,6 +57,7 @@ program main
! CHECK: omp.target
! CHECK: omp.parallel
! CHECK: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do simd
do i = 1, 10
end do
@@ -66,6 +69,7 @@ program main
! CHECK: omp.target
! CHECK: omp.parallel
! CHECK: omp.wsloop
+ ! CHECK-NEXT: omp.loop_nest
!$omp target parallel do
do i = 1, 10
end do
@@ -76,8 +80,34 @@ program main
! ----------------------------------------------------------------------------
! CHECK: omp.target
! CHECK: omp.simd
+ ! CHECK-NEXT: omp.loop_nest
!$omp target simd
do i = 1, 10
end do
!$omp end target simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK: omp.target
+ ! CHECK: omp.teams
+ ! CHECK: omp.distribute
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp target teams distribute
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK: omp.teams
+ ! CHECK: omp.distribute
+ ! CHECK-NEXT: omp.loop_nest
+ !$omp teams distribute
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
end program main
diff --git a/flang/test/Lower/OpenMP/order-clause.f90 b/flang/test/Lower/OpenMP/order-clause.f90
new file mode 100644
index 000000000000..717d9740c56f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/order-clause.f90
@@ -0,0 +1,76 @@
+! This test checks lowering of OpenMP order clause.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
+
+!CHECK-LABEL: func.func @_QPsimd_order() {
+subroutine simd_order
+ !CHECK: omp.simd order(reproducible:concurrent) {
+ !$omp simd order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.simd order(reproducible:concurrent) {
+ !$omp simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.simd order(unconstrained:concurrent) {
+ !$omp simd order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine simd_order
+
+!CHECK-LABEL: func.func @_QPdo_order() {
+subroutine do_order
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(unconstrained:concurrent) {
+ !$omp do order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine do_order
+
+!CHECK-LABEL: func.func @_QPdo_simd_order() {
+subroutine do_simd_order
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do simd order(concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp do simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+ !CHECK: omp.wsloop order(unconstrained:concurrent) {
+ !$omp do simd order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine do_simd_order
+
+!CHECK-LABEL: func.func @_QPdo_simd_order_parallel() {
+subroutine do_simd_order_parallel
+ !CHECK: omp.parallel {
+ !CHECK: omp.wsloop order(reproducible:concurrent) {
+ !$omp parallel do simd order(reproducible:concurrent)
+ do i = 1, 10
+ end do
+end subroutine do_simd_order_parallel
+
+
+subroutine distribute_order
+ !CHECK: omp.distribute order(reproducible:concurrent) {
+ !$omp teams distribute order(concurrent)
+ do i=1,10
+ end do
+ !CHECK: omp.distribute order(reproducible:concurrent) {
+ !$omp teams distribute order(reproducible:concurrent)
+ do i=1,10
+ end do
+ !CHECK: omp.distribute order(unconstrained:concurrent) {
+ !$omp teams distribute order(unconstrained:concurrent)
+ do i = 1, 10
+ end do
+end subroutine
diff --git a/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90 b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
new file mode 100644
index 000000000000..ea04d3d1dfa6
--- /dev/null
+++ b/flang/test/Lower/OpenMP/parallel-reduction-mixed.f90
@@ -0,0 +1,48 @@
+!! Make sure that mixture of by-ref and by-val reductions work all the way
+!! to LLVM-IR code.
+! RUN: %flang_fc1 -emit-llvm -fopenmp -o - %s 2>&1 | FileCheck %s
+subroutine proc
+ implicit none
+ real(8),allocatable :: F(:)
+ real(8),allocatable :: A(:)
+
+ integer :: I
+
+!$omp parallel private(A) reduction(+:F,I)
+ allocate(A(10))
+!$omp end parallel
+end subroutine proc
+
+!CHECK-LABEL: define void @proc_()
+!CHECK: call void
+!CHECK-SAME: @__kmpc_fork_call(ptr {{.*}}, i32 1, ptr @[[OMP_PAR:.*]], {{.*}})
+
+!CHECK: define internal void @[[OMP_PAR]](ptr {{.*}} %[[TID_ADDR:.*]], ptr noalias
+!CHECK: %[[TID_LOCAL:.*]] = alloca i32
+!CHECK: %[[TID:.*]] = load i32, ptr %[[TID_ADDR]]
+!CHECK: store i32 %[[TID]], ptr %[[TID_LOCAL]]
+!CHECK: %[[I_priv:.*]] = alloca i32
+!CHECK: %[[F_priv:.*]] = alloca ptr
+
+!CHECK: omp.reduction.init:
+!CHECK: store ptr %{{.*}}, ptr %[[F_priv]]
+!CHECK: store i32 0, ptr %[[I_priv]]
+
+!CHECK: omp.par.region8:
+!CHECK-NEXT: call ptr @malloc
+!CHECK-SAME: i64 10
+
+!CHECK: %[[RED_ARR_0:.*]] = getelementptr inbounds [2 x ptr], ptr %red.array, i64 0, i64 0
+!CHECK: store ptr %[[F_priv]], ptr %[[RED_ARR_0:.*]]
+!CHECK: %[[RED_ARR_1:.*]] = getelementptr inbounds [2 x ptr], ptr %red.array, i64 0, i64 1
+!CHECK: store ptr %[[I_priv]], ptr %[[RED_ARR_1]]
+
+!CHECK: omp.par.pre_finalize: ; preds = %reduce.finalize
+!CHECK: %{{.*}} = load ptr, ptr %[[F_priv]]
+!CHECK: br label %omp.reduction.cleanup
+
+!CHECK: omp.reduction.cleanup:
+!CHECK: br i1 %{{.*}}, label %[[OMP_FREE:.*]], label %{{.*}}
+
+!CHECK: [[OMP_FREE]]:
+!CHECK: call void @free
diff --git a/flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90 b/flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90
new file mode 100644
index 000000000000..2c2f60cb72c9
--- /dev/null
+++ b/flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90
@@ -0,0 +1,131 @@
+! RUN: bbc -emit-hlfir -fopenmp -o - %s | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s | FileCheck %s
+
+program reduce
+integer :: i = 0
+integer, dimension(:), pointer :: r
+
+allocate(r(2))
+
+!$omp parallel do reduction(+:r)
+do i=0,10
+ r(1) = i
+ r(2) = -i
+enddo
+!$omp end parallel do
+
+print *,r
+deallocate(r)
+
+end program
+
+! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_box_ptr_Uxi32 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
+! CHECK: fir.if %[[VAL_7]] {
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: } else {
+! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_9]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_10]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_10]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[VAL_13:.*]] = arith.constant true
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_11]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_15]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_17:.*]] = fir.shape_shift %[[VAL_16]]#0, %[[VAL_16]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_18:.*]] = fir.rebox %[[VAL_14]]#0(%[[VAL_17]]) : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_18]] : i32, !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_18]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
+! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
+! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32
+! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } cleanup {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
+! CHECK: fir.if %[[VAL_5]] {
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[VAL_6]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce"} {
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEi) : !fir.ref<i32>
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFEr) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {fortran_attrs = {{.*}}<pointer>, uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+! CHECK: %[[VAL_4:.*]] = arith.constant false
+! CHECK: %[[VAL_5:.*]] = fir.absent !fir.box<none>
+! CHECK: %[[VAL_6:.*]] = fir.address_of(
+! CHECK: %[[VAL_7:.*]] = arith.constant 8 : i32
+! CHECK: %[[VAL_8:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
+! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_8]](%[[VAL_10]]) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_11]] to %[[VAL_3]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_13:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_14:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_12]] : (index) -> i64
+! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_13]] : (i32) -> i64
+! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAPointerSetBounds(%[[VAL_15]], %[[VAL_14]], %[[VAL_16]], %[[VAL_17]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> none
+! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.char<{{.*}}>>) -> !fir.ref<i8>
+! CHECK: %[[VAL_21:.*]] = fir.call @_FortranAPointerAllocate(%[[VAL_19]], %[[VAL_4]], %[[VAL_5]], %[[VAL_20]], %[[VAL_7]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_22:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
+! CHECK: %[[VAL_23:.*]]:2 = hlfir.declare %[[VAL_22]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_24:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_25:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_26:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop reduction(byref @add_reduction_byref_box_ptr_Uxi32 %[[VAL_3]]#0 -> %[[VAL_27:.*]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) {
+! CHECK: omp.loop_nest (%[[VAL_28:.*]]) : i32 = (%[[VAL_24]]) to (%[[VAL_25]]) inclusive step (%[[VAL_26]]) {
+! CHECK: %[[VAL_29:.*]]:2 = hlfir.declare %[[VAL_27]] {fortran_attrs = {{.*}}<pointer>, uniq_name = "_QFEr"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+! CHECK: fir.store %[[VAL_28]] to %[[VAL_23]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_23]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_29]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_32:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_31]] (%[[VAL_32]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[VAL_30]] to %[[VAL_33]] : i32, !fir.ref<i32>
+! CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_23]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_35:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_36:.*]] = arith.subi %[[VAL_35]], %[[VAL_34]] : i32
+! CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_29]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_38:.*]] = arith.constant 2 : index
+! CHECK: %[[VAL_39:.*]] = hlfir.designate %[[VAL_37]] (%[[VAL_38]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[VAL_36]] to %[[VAL_39]] : i32, !fir.ref<i32>
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
diff --git a/flang/test/Lower/OpenMP/reduction-array-intrinsic.f90 b/flang/test/Lower/OpenMP/reduction-array-intrinsic.f90
new file mode 100644
index 000000000000..208cda28a3e5
--- /dev/null
+++ b/flang/test/Lower/OpenMP/reduction-array-intrinsic.f90
@@ -0,0 +1,96 @@
+! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+subroutine max_array_reduction(l, r)
+ integer :: l(:), r(:)
+
+ !$omp parallel reduction(max:l)
+ l = max(l, r)
+ !$omp end parallel
+end subroutine
+
+! CHECK-LABEL: omp.declare_reduction @max_byref_box_Uxi32 : !fir.ref<!fir.box<!fir.array<?xi32>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<?xi32>>>):
+! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_7:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_5]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[VAL_8:.*]] = arith.constant true
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_6]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_10]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_12:.*]] = fir.shape_shift %[[VAL_11]]#0, %[[VAL_11]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_13:.*]] = fir.rebox %[[VAL_9]]#0(%[[VAL_12]]) : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_13]] : i32, !fir.box<!fir.array<?xi32>>
+! CHECK: fir.store %[[VAL_13]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: omp.yield(%[[VAL_3]] : !fir.ref<!fir.box<!fir.array<?xi32>>>)
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<?xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<?xi32>>>):
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
+! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
+! CHECK: %[[VAL_13:.*]] = arith.maxsi %[[VAL_11]], %[[VAL_12]] : i32
+! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.array<?xi32>>>)
+! CHECK-LABEL: } cleanup {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<?xi32>>>):
+! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
+! CHECK: fir.if %[[VAL_5]] {
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[VAL_6]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+
+! CHECK-LABEL: func.func @_QPmax_array_reduction(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "l"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "r"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_2]] {uniq_name = "_QFmax_array_reductionEl"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_2]] {uniq_name = "_QFmax_array_reductionEr"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
+! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
+! CHECK: fir.store %[[VAL_3]]#1 to %[[VAL_5]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: omp.parallel reduction(byref @max_byref_box_Uxi32 %[[VAL_5]] -> %[[VAL_6:.*]] : !fir.ref<!fir.box<!fir.array<?xi32>>>) {
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "_QFmax_array_reductionEl"} : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> (!fir.ref<!fir.box<!fir.array<?xi32>>>, !fir.ref<!fir.box<!fir.array<?xi32>>>)
+! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_9]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_10]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_12:.*]] = hlfir.elemental %[[VAL_11]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+! CHECK: ^bb0(%[[VAL_13:.*]]: index):
+! CHECK: %[[VAL_14:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_14]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_16]] : index
+! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_13]], %[[VAL_17]] : index
+! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_18]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
+! CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref<i32>
+! CHECK: %[[VAL_23:.*]] = arith.cmpi sgt, %[[VAL_20]], %[[VAL_22]] : i32
+! CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[VAL_20]], %[[VAL_22]] : i32
+! CHECK: hlfir.yield_element %[[VAL_24]] : i32
+! CHECK: }
+! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_25]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+! CHECK: hlfir.destroy %[[VAL_12]] : !hlfir.expr<?xi32>
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: return
+! CHECK: }
diff --git a/flang/test/Lower/OpenMP/simd.f90 b/flang/test/Lower/OpenMP/simd.f90
index 223b248b7934..e98136dd57b0 100644
--- a/flang/test/Lower/OpenMP/simd.f90
+++ b/flang/test/Lower/OpenMP/simd.f90
@@ -182,3 +182,44 @@ subroutine simd_with_collapse_clause(n)
end do
!$OMP END SIMD
end subroutine
+
+
+!CHECK: func.func @_QPsimdloop_aligned_cptr(%[[ARG_A:.*]]: !fir.ref
+!CHECK-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr
+!CHECK-SAME: {__address:i64}>> {fir.bindc_name = "a"}) {
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[ARG_A]] dummy_scope %0
+!CHECK-SAME: {uniq_name = "_QFsimdloop_aligned_cptrEa"} :
+!CHECK-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.dscope) ->
+!CHECK-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>,
+!CHECK-SAME: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
+subroutine simdloop_aligned_cptr( A)
+ use iso_c_binding
+ integer :: i
+ type (c_ptr) :: A
+!CHECK: omp.simd aligned(%[[A_DECL]]#1 : !fir.ref
+!CHECK-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>
+!CHECK-SAME: -> 256 : i64)
+ !$OMP SIMD ALIGNED(A:256)
+ do i = 1, 10
+ call c_test_call(A)
+ end do
+ !$OMP END SIMD
+end subroutine
+
+!CHECK-LABEL: func @_QPsimdloop_aligned_allocatable
+subroutine simdloop_aligned_allocatable()
+ integer :: i
+ integer, allocatable :: A(:)
+ allocate(A(10))
+!CHECK: %[[A_PTR:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "a",
+!CHECK-SAME: uniq_name = "_QFsimdloop_aligned_allocatableEa"}
+!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A_PTR]] {fortran_attrs = #fir.var_attrs<allocatable>,
+!CHECK-SAME: uniq_name = "_QFsimdloop_aligned_allocatableEa"} :
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
+!CHECK-SAME: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+!CHECK: omp.simd aligned(%[[A_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> -> 256 : i64)
+ !$OMP SIMD ALIGNED(A:256)
+ do i = 1, 10
+ A(i) = i
+ end do
+end subroutine
diff --git a/flang/test/Lower/OpenMP/simd_aarch64.f90 b/flang/test/Lower/OpenMP/simd_aarch64.f90
new file mode 100644
index 000000000000..735237223bcb
--- /dev/null
+++ b/flang/test/Lower/OpenMP/simd_aarch64.f90
@@ -0,0 +1,16 @@
+! Tests for 2.9.3.1 Simd and target dependent defult alignment for AArch64
+! The default alignment for AARCH64 is 0 so we do not emit aligned clause
+! REQUIRES: aarch64-registered-target
+! RUN: %flang_fc1 -triple aarch64-unknown-linux-gnu -emit-hlfir -fopenmp %s -o - | FileCheck %s
+subroutine simdloop_aligned_cptr(A)
+ use iso_c_binding
+ integer :: i
+ type (c_ptr) :: A
+ !CHECK: omp.simd
+ !CHECK-NOT: aligned(
+ !$OMP SIMD ALIGNED(A)
+ do i = 1, 10
+ call c_test_call(A)
+ end do
+ !$OMP END SIMD
+end subroutine
diff --git a/flang/test/Lower/OpenMP/simd_x86_64.f90 b/flang/test/Lower/OpenMP/simd_x86_64.f90
new file mode 100644
index 000000000000..c8cb7970c322
--- /dev/null
+++ b/flang/test/Lower/OpenMP/simd_x86_64.f90
@@ -0,0 +1,48 @@
+! Tests for 2.9.3.1 Simd and target dependent defult alignment for x86
+! REQUIRES: x86-registered-target
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-hlfir -fopenmp -target-cpu x86-64 %s -o - | FileCheck --check-prefixes=DEFAULT %s
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-hlfir -fopenmp -target-cpu x86-64 -target-feature +avx %s -o - | FileCheck --check-prefixes=AVX %s
+! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-hlfir -fopenmp -target-cpu x86-64 -target-feature +avx512f %s -o - | FileCheck --check-prefixes=AVX512F %s
+!DEFAULT: func.func @_QPsimdloop_aligned_cptr(%[[ARG_A:.*]]: !fir.ref
+!DEFAULT-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr
+!DEFAULT-SAME: {__address:i64}>> {fir.bindc_name = "a"}) {
+!DEFAULT: %[[A_DECL:.*]]:2 = hlfir.declare %[[ARG_A]] dummy_scope %0
+!DEFAULT-SAME: {uniq_name = "_QFsimdloop_aligned_cptrEa"} :
+!DEFAULT-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.dscope) ->
+!DEFAULT-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>,
+!DEFAULT-SAME: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
+!AVX: func.func @_QPsimdloop_aligned_cptr(%[[ARG_A:.*]]: !fir.ref
+!AVX-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr
+!AVX-SAME: {__address:i64}>> {fir.bindc_name = "a"}) {
+!AVX: %[[A_DECL:.*]]:2 = hlfir.declare %[[ARG_A]] dummy_scope %0
+!AVX-SAME: {uniq_name = "_QFsimdloop_aligned_cptrEa"} :
+!AVX-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.dscope) ->
+!AVX-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>,
+!AVX-SAME: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
+!AVX512F: func.func @_QPsimdloop_aligned_cptr(%[[ARG_A:.*]]: !fir.ref
+!AVX512F-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr
+!AVX512F-SAME: {__address:i64}>> {fir.bindc_name = "a"}) {
+!AVX512F: %[[A_DECL:.*]]:2 = hlfir.declare %[[ARG_A]] dummy_scope %0
+!AVX512F-SAME: {uniq_name = "_QFsimdloop_aligned_cptrEa"} :
+!AVX512F-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.dscope) ->
+!AVX512F-SAME: (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>,
+!AVX512F-SAME: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
+subroutine simdloop_aligned_cptr(A)
+ use iso_c_binding
+ integer :: i
+ type (c_ptr) :: A
+ !DEFAULT: omp.simd aligned(%[[A_DECL]]#1 : !fir.ref
+ !DEFAULT-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>
+ !DEFAULT-SAME: -> 128 : i64)
+ !AVX: omp.simd aligned(%[[A_DECL]]#1 : !fir.ref
+ !AVX-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>
+ !AVX-SAME: -> 256 : i64)
+ !AVX512F: omp.simd aligned(%[[A_DECL]]#1 : !fir.ref
+ !AVX512F-SAME: <!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>
+ !AVX512F-SAME: -> 512 : i64)
+ !$OMP SIMD ALIGNED(A)
+ do i = 1, 10
+ call c_test_call(A)
+ end do
+ !$OMP END SIMD
+end subroutine
diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
new file mode 100644
index 000000000000..bc22c8b05b96
--- /dev/null
+++ b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
@@ -0,0 +1,299 @@
+! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+program reduce15
+ integer, parameter :: SIZE = 10
+ integer, dimension(:), allocatable :: arr,maxes,mins
+ integer :: i
+
+ allocate(arr(10))
+ allocate(maxes(10))
+ allocate(mins(10))
+
+ maxes = 5
+ mins = 5
+ do i = 1,SIZE
+ arr(i) = i
+ end do
+
+ !$omp parallel do reduction(max:maxes)
+ do i = 1,SIZE
+ maxes = max(arr, maxes)
+ end do
+ !$omp end parallel do
+
+
+ !$omp parallel do reduction(min:mins)
+ do i = 1,SIZE
+ mins = min(arr, mins)
+ end do
+ !$omp end parallel do
+
+ print *,"max: ", maxes
+ print *,"min: ", mins
+end program
+
+! CHECK-LABEL: omp.declare_reduction @min_byref_box_heap_Uxi32 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = arith.constant 2147483647 : i32
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
+! CHECK: fir.if %[[VAL_7]] {
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: } else {
+! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_9]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_10]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_10]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[VAL_13:.*]] = arith.constant true
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_11]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_15]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_17:.*]] = fir.shape_shift %[[VAL_16]]#0, %[[VAL_16]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_18:.*]] = fir.rebox %[[VAL_14]]#0(%[[VAL_17]]) : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_18]] : i32, !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_18]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
+! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
+! CHECK: %[[VAL_13:.*]] = arith.minsi %[[VAL_11]], %[[VAL_12]] : i32
+! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } cleanup {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
+! CHECK: fir.if %[[VAL_5]] {
+! CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+
+! CHECK-LABEL: omp.declare_reduction @max_byref_box_heap_Uxi32 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = arith.constant -2147483648 : i32
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
+! CHECK: fir.if %[[VAL_7]] {
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: } else {
+! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_9]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_10]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_12:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_10]]#1 {bindc_name = ".tmp", uniq_name = ""}
+! CHECK: %[[VAL_13:.*]] = arith.constant true
+! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_11]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
+! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_15]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_17:.*]] = fir.shape_shift %[[VAL_16]]#0, %[[VAL_16]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_18:.*]] = fir.rebox %[[VAL_14]]#0(%[[VAL_17]]) : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_18]] : i32, !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_18]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
+! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
+! CHECK: %[[VAL_13:.*]] = arith.maxsi %[[VAL_11]], %[[VAL_12]] : i32
+! CHECK: fir.store %[[VAL_13]] to %[[VAL_9]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK-LABEL: } cleanup {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.heap<!fir.array<?xi32>>) -> i64
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
+! CHECK: fir.if %[[VAL_5]] {
+! CHECK: fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce15"} {
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFEarr) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEarr"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QFEmaxes) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmaxes"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFEmins) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmins"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: %[[VAL_8:.*]] = fir.address_of(@_QFECsize) : !fir.ref<i32>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {fortran_attrs = {{.*}}<parameter>, uniq_name = "_QFECsize"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_10:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> index
+! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : index
+! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : index
+! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_14]] {fir.must_be_heap = true, uniq_name = "_QFEarr.alloc"}
+! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_17]] to %[[VAL_1]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_18:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> index
+! CHECK: %[[VAL_20:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_21:.*]] = arith.cmpi sgt, %[[VAL_19]], %[[VAL_20]] : index
+! CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_19]], %[[VAL_20]] : index
+! CHECK: %[[VAL_23:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_22]] {fir.must_be_heap = true, uniq_name = "_QFEmaxes.alloc"}
+! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_22]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_23]](%[[VAL_24]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_25]] to %[[VAL_5]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_26:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i32) -> index
+! CHECK: %[[VAL_28:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_29:.*]] = arith.cmpi sgt, %[[VAL_27]], %[[VAL_28]] : index
+! CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_29]], %[[VAL_27]], %[[VAL_28]] : index
+! CHECK: %[[VAL_31:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_30]] {fir.must_be_heap = true, uniq_name = "_QFEmins.alloc"}
+! CHECK: %[[VAL_32:.*]] = fir.shape %[[VAL_30]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_33:.*]] = fir.embox %[[VAL_31]](%[[VAL_32]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[VAL_33]] to %[[VAL_7]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_34:.*]] = arith.constant 5 : i32
+! CHECK: hlfir.assign %[[VAL_34]] to %[[VAL_5]]#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_35:.*]] = arith.constant 5 : i32
+! CHECK: hlfir.assign %[[VAL_35]] to %[[VAL_7]]#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_36:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : (i32) -> index
+! CHECK: %[[VAL_38:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i32) -> index
+! CHECK: %[[VAL_40:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_37]] : (index) -> i32
+! CHECK: %[[VAL_42:.*]]:2 = fir.do_loop %[[VAL_43:.*]] = %[[VAL_37]] to %[[VAL_39]] step %[[VAL_40]] iter_args(%[[VAL_44:.*]] = %[[VAL_41]]) -> (index, i32) {
+! CHECK: fir.store %[[VAL_44]] to %[[VAL_3]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_45:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_47:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (i32) -> i64
+! CHECK: %[[VAL_49:.*]] = hlfir.designate %[[VAL_46]] (%[[VAL_48]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, i64) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[VAL_45]] to %[[VAL_49]] : i32, !fir.ref<i32>
+! CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_43]], %[[VAL_40]] : index
+! CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_40]] : (index) -> i32
+! CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_52]], %[[VAL_51]] : i32
+! CHECK: fir.result %[[VAL_50]], %[[VAL_53]] : index, i32
+! CHECK: }
+! CHECK: fir.store %[[VAL_54:.*]]#1 to %[[VAL_3]]#1 : !fir.ref<i32>
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_55:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
+! CHECK: %[[VAL_56:.*]]:2 = hlfir.declare %[[VAL_55]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_57:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_58:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_59:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop reduction(byref @max_byref_box_heap_Uxi32 %[[VAL_5]]#0 -> %[[VAL_60:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {
+! CHECK: omp.loop_nest (%[[VAL_61:.*]]) : i32 = (%[[VAL_57]]) to (%[[VAL_58]]) inclusive step (%[[VAL_59]]) {
+! CHECK: %[[VAL_62:.*]]:2 = hlfir.declare %[[VAL_60]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmaxes"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: fir.store %[[VAL_61]] to %[[VAL_56]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_63:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_64:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_65:.*]]:3 = fir.box_dims %[[VAL_63]], %[[VAL_64]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_66:.*]] = fir.shape %[[VAL_65]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_67:.*]] = fir.load %[[VAL_62]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_68:.*]] = hlfir.elemental %[[VAL_66]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+! CHECK: ^bb0(%[[VAL_69:.*]]: index):
+! CHECK: %[[VAL_70:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_71:.*]]:3 = fir.box_dims %[[VAL_63]], %[[VAL_70]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_72:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_73:.*]] = arith.subi %[[VAL_71]]#0, %[[VAL_72]] : index
+! CHECK: %[[VAL_74:.*]] = arith.addi %[[VAL_69]], %[[VAL_73]] : index
+! CHECK: %[[VAL_75:.*]] = hlfir.designate %[[VAL_63]] (%[[VAL_74]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_76:.*]] = fir.load %[[VAL_75]] : !fir.ref<i32>
+! CHECK: %[[VAL_77:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_78:.*]]:3 = fir.box_dims %[[VAL_67]], %[[VAL_77]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_79:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_80:.*]] = arith.subi %[[VAL_78]]#0, %[[VAL_79]] : index
+! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_69]], %[[VAL_80]] : index
+! CHECK: %[[VAL_82:.*]] = hlfir.designate %[[VAL_67]] (%[[VAL_81]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_83:.*]] = fir.load %[[VAL_82]] : !fir.ref<i32>
+! CHECK: %[[VAL_84:.*]] = arith.cmpi sgt, %[[VAL_76]], %[[VAL_83]] : i32
+! CHECK: %[[VAL_85:.*]] = arith.select %[[VAL_84]], %[[VAL_76]], %[[VAL_83]] : i32
+! CHECK: hlfir.yield_element %[[VAL_85]] : i32
+! CHECK: }
+! CHECK: %[[VAL_86:.*]] = fir.load %[[VAL_62]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: hlfir.assign %[[VAL_68]] to %[[VAL_86]] : !hlfir.expr<?xi32>, !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: hlfir.destroy %[[VAL_68]] : !hlfir.expr<?xi32>
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_87:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
+! CHECK: %[[VAL_88:.*]]:2 = hlfir.declare %[[VAL_87]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_89:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_90:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_91:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop reduction(byref @min_byref_box_heap_Uxi32 %[[VAL_7]]#0 -> %[[VAL_92:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {
+! CHECK: omp.loop_nest (%[[VAL_93:.*]]) : i32 = (%[[VAL_89]]) to (%[[VAL_90]]) inclusive step (%[[VAL_91]]) {
+! CHECK: %[[VAL_94:.*]]:2 = hlfir.declare %[[VAL_92]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmins"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: fir.store %[[VAL_93]] to %[[VAL_88]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_95:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_96:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_97:.*]]:3 = fir.box_dims %[[VAL_95]], %[[VAL_96]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_98:.*]] = fir.shape %[[VAL_97]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_99:.*]] = fir.load %[[VAL_94]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[VAL_100:.*]] = hlfir.elemental %[[VAL_98]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+! CHECK: ^bb0(%[[VAL_101:.*]]: index):
+! CHECK: %[[VAL_102:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_103:.*]]:3 = fir.box_dims %[[VAL_95]], %[[VAL_102]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_104:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_105:.*]] = arith.subi %[[VAL_103]]#0, %[[VAL_104]] : index
+! CHECK: %[[VAL_106:.*]] = arith.addi %[[VAL_101]], %[[VAL_105]] : index
+! CHECK: %[[VAL_107:.*]] = hlfir.designate %[[VAL_95]] (%[[VAL_106]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_108:.*]] = fir.load %[[VAL_107]] : !fir.ref<i32>
+! CHECK: %[[VAL_109:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_110:.*]]:3 = fir.box_dims %[[VAL_99]], %[[VAL_109]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_111:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_112:.*]] = arith.subi %[[VAL_110]]#0, %[[VAL_111]] : index
+! CHECK: %[[VAL_113:.*]] = arith.addi %[[VAL_101]], %[[VAL_112]] : index
+! CHECK: %[[VAL_114:.*]] = hlfir.designate %[[VAL_99]] (%[[VAL_113]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_115:.*]] = fir.load %[[VAL_114]] : !fir.ref<i32>
+! CHECK: %[[VAL_116:.*]] = arith.cmpi slt, %[[VAL_108]], %[[VAL_115]] : i32
+! CHECK: %[[VAL_117:.*]] = arith.select %[[VAL_116]], %[[VAL_108]], %[[VAL_115]] : i32
+! CHECK: hlfir.yield_element %[[VAL_117]] : i32
+! CHECK: }
+! CHECK: %[[VAL_118:.*]] = fir.load %[[VAL_94]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: hlfir.assign %[[VAL_100]] to %[[VAL_118]] : !hlfir.expr<?xi32>, !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: hlfir.destroy %[[VAL_100]] : !hlfir.expr<?xi32>
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-pointer.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-pointer.f90
new file mode 100644
index 000000000000..aab6efbcbc5f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/wsloop-reduction-pointer.f90
@@ -0,0 +1,110 @@
+! RUN: bbc -emit-hlfir -fopenmp -o - %s | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s | FileCheck %s
+
+program reduce_pointer
+ integer, pointer :: v
+ integer i
+
+ allocate(v)
+ v = 0
+
+ !$omp parallel do private(i) reduction(+:v)
+ do i = 1, 5
+ v = v + 42
+ end do
+ !$omp end parallel do
+
+ print *,v
+ deallocate(v)
+end program
+
+! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_box_ptr_i32 : !fir.ref<!fir.box<!fir.ptr<i32>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
+! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
+! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ptr<i32>) -> i64
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
+! CHECK: fir.if %[[VAL_7]] {
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: } else {
+! CHECK: %[[VAL_9:.*]] = fir.allocmem i32
+! CHECK: fir.store %[[VAL_1]] to %[[VAL_9]] : !fir.heap<i32>
+! CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_9]] : (!fir.heap<i32>) -> !fir.box<!fir.ptr<i32>>
+! CHECK: fir.store %[[VAL_10]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: }
+! CHECK: omp.yield(%[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<i32>>>)
+! CHECK-LABEL: } combiner {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]] : !fir.ptr<i32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]] : !fir.ptr<i32>
+! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_6]], %[[VAL_7]] : i32
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ptr<i32>
+! CHECK: omp.yield(%[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>)
+! CHECK-LABEL: } cleanup {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
+! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr<i32>) -> i64
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
+! CHECK: fir.if %[[VAL_5]] {
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr<i32>) -> !fir.heap<i32>
+! CHECK: fir.freemem %[[VAL_6]] : !fir.heap<i32>
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+
+! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce_pointer"} {
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "v", uniq_name = "_QFEv"}
+! CHECK: %[[VAL_3:.*]] = fir.zero_bits !fir.ptr<i32>
+! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+! CHECK: fir.store %[[VAL_4]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]] {fortran_attrs = {{.*}}<pointer>, uniq_name = "_QFEv"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+! CHECK: %[[VAL_6:.*]] = arith.constant false
+! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<none>
+! CHECK: %[[VAL_8:.*]] = fir.address_of(
+! CHECK: %[[VAL_9:.*]] = arith.constant 8 : i32
+! CHECK: %[[VAL_10:.*]] = fir.zero_bits !fir.ptr<i32>
+! CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_10]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+! CHECK: fir.store %[[VAL_11]] to %[[VAL_5]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_5]]#1 : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<!fir.char<{{.*}}>>) -> !fir.ref<i8>
+! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAPointerAllocate(%[[VAL_12]], %[[VAL_6]], %[[VAL_7]], %[[VAL_13]], %[[VAL_9]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK: %[[VAL_15:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_17]] : i32, !fir.ptr<i32>
+! CHECK: omp.parallel {
+! CHECK: %[[VAL_18:.*]] = fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFEi"}
+! CHECK: %[[VAL_19:.*]]:2 = hlfir.declare %[[VAL_18]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_20:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_21:.*]] = arith.constant 5 : i32
+! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i32
+! CHECK: omp.wsloop reduction(byref @add_reduction_byref_box_ptr_i32 %[[VAL_5]]#0 -> %[[VAL_23:.*]] : !fir.ref<!fir.box<!fir.ptr<i32>>>) {
+! CHECK: omp.loop_nest (%[[VAL_24:.*]]) : i32 = (%[[VAL_20]]) to (%[[VAL_21]]) inclusive step (%[[VAL_22]]) {
+! CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_23]] {fortran_attrs = {{.*}}<pointer>, uniq_name = "_QFEv"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+! CHECK: fir.store %[[VAL_24]] to %[[VAL_19]]#1 : !fir.ref<i32>
+! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_25]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_27:.*]] = fir.box_addr %[[VAL_26]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_27]] : !fir.ptr<i32>
+! CHECK: %[[VAL_29:.*]] = arith.constant 42 : i32
+! CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_28]], %[[VAL_29]] : i32
+! CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_25]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_31]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: hlfir.assign %[[VAL_30]] to %[[VAL_32]] : i32, !fir.ptr<i32>
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
diff --git a/flang/test/Lower/PowerPC/ppc-mma-assemble-disassemble.f90 b/flang/test/Lower/PowerPC/ppc-mma-assemble-disassemble.f90
index d3872891853d..17603535760b 100644
--- a/flang/test/Lower/PowerPC/ppc-mma-assemble-disassemble.f90
+++ b/flang/test/Lower/PowerPC/ppc-mma-assemble-disassemble.f90
@@ -12,17 +12,18 @@
end subroutine test_assemble_acc_i1
! CHECK-LABEL: @test_assemble_acc_i1
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %4 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %5 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %6 = load <16 x i8>, ptr %2, align 16
-! LLVMIR: %7 = load <16 x i8>, ptr %3, align 16
-! LLVMIR: %8 = load <16 x i8>, ptr %4, align 16
-! LLVMIR: %9 = load <16 x i8>, ptr %5, align 16
-! LLVMIR: %10 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %6, <16 x i8> %7, <16 x i8> %8, <16 x i8> %9)
-! LLVMIR: store <512 x i1> %10, ptr %1, align 64
+
+! LLVMIR: %[[VAL_0:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_1:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_2:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_3:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_4:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_5:.*]] = load <16 x i8>, ptr %[[VAL_3]], align 16
+! LLVMIR: %[[VAL_6:.*]] = load <16 x i8>, ptr %[[VAL_2]], align 16
+! LLVMIR: %[[VAL_7:.*]] = load <16 x i8>, ptr %[[VAL_1]], align 16
+! LLVMIR: %[[VAL_8:.*]] = load <16 x i8>, ptr %[[VAL_0]], align 16
+! LLVMIR: %[[VAL_9:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_5]], <16 x i8> %[[VAL_6]], <16 x i8> %[[VAL_7]], <16 x i8> %[[VAL_8]])
+! LLVMIR: store <512 x i1> %[[VAL_9]], ptr %[[VAL_4]], align 64
subroutine test_assemble_acc_i2()
use, intrinsic :: mma
@@ -33,21 +34,21 @@
end subroutine test_assemble_acc_i2
! CHECK-LABEL: @test_assemble_acc_i2
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %4 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %5 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %6 = load <8 x i16>, ptr %2, align 16
-! LLVMIR: %7 = load <8 x i16>, ptr %3, align 16
-! LLVMIR: %8 = load <8 x i16>, ptr %4, align 16
-! LLVMIR: %9 = load <8 x i16>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <8 x i16> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <8 x i16> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <8 x i16> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <8 x i16> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_10:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_11:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_12:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_13:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_14:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_15:.*]] = load <8 x i16>, ptr %[[VAL_13]], align 16
+! LLVMIR: %[[VAL_16:.*]] = load <8 x i16>, ptr %[[VAL_12]], align 16
+! LLVMIR: %[[VAL_17:.*]] = load <8 x i16>, ptr %[[VAL_11]], align 16
+! LLVMIR: %[[VAL_18:.*]] = load <8 x i16>, ptr %[[VAL_10]], align 16
+! LLVMIR: %[[VAL_19:.*]] = bitcast <8 x i16> %[[VAL_15]] to <16 x i8>
+! LLVMIR: %[[VAL_20:.*]] = bitcast <8 x i16> %[[VAL_16]] to <16 x i8>
+! LLVMIR: %[[VAL_21:.*]] = bitcast <8 x i16> %[[VAL_17]] to <16 x i8>
+! LLVMIR: %[[VAL_22:.*]] = bitcast <8 x i16> %[[VAL_18]] to <16 x i8>
+! LLVMIR: %[[VAL_23:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_19]], <16 x i8> %[[VAL_20]], <16 x i8> %[[VAL_21]], <16 x i8> %[[VAL_22]])
+! LLVMIR: store <512 x i1> %[[VAL_23]], ptr %[[VAL_14]], align 64
subroutine test_assemble_acc_i4()
@@ -59,21 +60,21 @@
end subroutine test_assemble_acc_i4
! CHECK-LABEL: @test_assemble_acc_i4
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %3 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %4 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %5 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %6 = load <4 x i32>, ptr %2, align 16
-! LLVMIR: %7 = load <4 x i32>, ptr %3, align 16
-! LLVMIR: %8 = load <4 x i32>, ptr %4, align 16
-! LLVMIR: %9 = load <4 x i32>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <4 x i32> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <4 x i32> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <4 x i32> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <4 x i32> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_24:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_25:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_26:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_27:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_28:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_29:.*]] = load <4 x i32>, ptr %[[VAL_27]], align 16
+! LLVMIR: %[[VAL_30:.*]] = load <4 x i32>, ptr %[[VAL_26]], align 16
+! LLVMIR: %[[VAL_31:.*]] = load <4 x i32>, ptr %[[VAL_25]], align 16
+! LLVMIR: %[[VAL_32:.*]] = load <4 x i32>, ptr %[[VAL_24]], align 16
+! LLVMIR: %[[VAL_33:.*]] = bitcast <4 x i32> %[[VAL_29]] to <16 x i8>
+! LLVMIR: %[[VAL_34:.*]] = bitcast <4 x i32> %[[VAL_30]] to <16 x i8>
+! LLVMIR: %[[VAL_35:.*]] = bitcast <4 x i32> %[[VAL_31]] to <16 x i8>
+! LLVMIR: %[[VAL_36:.*]] = bitcast <4 x i32> %[[VAL_32]] to <16 x i8>
+! LLVMIR: %[[VAL_37:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_33]], <16 x i8> %[[VAL_34]], <16 x i8> %[[VAL_35]], <16 x i8> %[[VAL_36]])
+! LLVMIR: store <512 x i1> %[[VAL_37]], ptr %[[VAL_28]], align 64
subroutine test_assemble_acc_i8()
use, intrinsic :: mma
@@ -84,21 +85,21 @@
end subroutine test_assemble_acc_i8
! CHECK-LABEL: @test_assemble_acc_i8
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %3 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %4 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %5 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %6 = load <2 x i64>, ptr %2, align 16
-! LLVMIR: %7 = load <2 x i64>, ptr %3, align 16
-! LLVMIR: %8 = load <2 x i64>, ptr %4, align 16
-! LLVMIR: %9 = load <2 x i64>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <2 x i64> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <2 x i64> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <2 x i64> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <2 x i64> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_38:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_39:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_40:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_41:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_42:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_43:.*]] = load <2 x i64>, ptr %[[VAL_41]], align 16
+! LLVMIR: %[[VAL_44:.*]] = load <2 x i64>, ptr %[[VAL_40]], align 16
+! LLVMIR: %[[VAL_45:.*]] = load <2 x i64>, ptr %[[VAL_39]], align 16
+! LLVMIR: %[[VAL_46:.*]] = load <2 x i64>, ptr %[[VAL_38]], align 16
+! LLVMIR: %[[VAL_47:.*]] = bitcast <2 x i64> %[[VAL_43]] to <16 x i8>
+! LLVMIR: %[[VAL_48:.*]] = bitcast <2 x i64> %[[VAL_44]] to <16 x i8>
+! LLVMIR: %[[VAL_49:.*]] = bitcast <2 x i64> %[[VAL_45]] to <16 x i8>
+! LLVMIR: %[[VAL_50:.*]] = bitcast <2 x i64> %[[VAL_46]] to <16 x i8>
+! LLVMIR: %[[VAL_51:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_47]], <16 x i8> %[[VAL_48]], <16 x i8> %[[VAL_49]], <16 x i8> %[[VAL_50]])
+! LLVMIR: store <512 x i1> %[[VAL_51]], ptr %[[VAL_42]], align 64
subroutine test_assemble_acc_u1()
@@ -110,17 +111,17 @@
end subroutine test_assemble_acc_u1
! CHECK-LABEL: @test_assemble_acc_u1
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %4 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %5 = alloca <16 x i8>, i64 1, align 16
-! LLVMIR: %6 = load <16 x i8>, ptr %2, align 16
-! LLVMIR: %7 = load <16 x i8>, ptr %3, align 16
-! LLVMIR: %8 = load <16 x i8>, ptr %4, align 16
-! LLVMIR: %9 = load <16 x i8>, ptr %5, align 16
-! LLVMIR: %10 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %6, <16 x i8> %7, <16 x i8> %8, <16 x i8> %9)
-! LLVMIR: store <512 x i1> %10, ptr %1, align 64
+! LLVMIR: %[[VAL_52:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_53:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_54:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_55:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_56:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_57:.*]] = load <16 x i8>, ptr %[[VAL_55]], align 16
+! LLVMIR: %[[VAL_58:.*]] = load <16 x i8>, ptr %[[VAL_54]], align 16
+! LLVMIR: %[[VAL_59:.*]] = load <16 x i8>, ptr %[[VAL_53]], align 16
+! LLVMIR: %[[VAL_60:.*]] = load <16 x i8>, ptr %[[VAL_52]], align 16
+! LLVMIR: %[[VAL_61:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_57]], <16 x i8> %[[VAL_58]], <16 x i8> %[[VAL_59]], <16 x i8> %[[VAL_60]])
+! LLVMIR: store <512 x i1> %[[VAL_61]], ptr %[[VAL_56]], align 64
subroutine test_assemble_acc_u2()
use, intrinsic :: mma
@@ -131,21 +132,21 @@
end subroutine test_assemble_acc_u2
! CHECK-LABEL: @test_assemble_acc_u2
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %4 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %5 = alloca <8 x i16>, i64 1, align 16
-! LLVMIR: %6 = load <8 x i16>, ptr %2, align 16
-! LLVMIR: %7 = load <8 x i16>, ptr %3, align 16
-! LLVMIR: %8 = load <8 x i16>, ptr %4, align 16
-! LLVMIR: %9 = load <8 x i16>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <8 x i16> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <8 x i16> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <8 x i16> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <8 x i16> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_62:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_63:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_64:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_65:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_66:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_67:.*]] = load <8 x i16>, ptr %[[VAL_65]], align 16
+! LLVMIR: %[[VAL_68:.*]] = load <8 x i16>, ptr %[[VAL_64]], align 16
+! LLVMIR: %[[VAL_69:.*]] = load <8 x i16>, ptr %[[VAL_63]], align 16
+! LLVMIR: %[[VAL_70:.*]] = load <8 x i16>, ptr %[[VAL_62]], align 16
+! LLVMIR: %[[VAL_71:.*]] = bitcast <8 x i16> %[[VAL_67]] to <16 x i8>
+! LLVMIR: %[[VAL_72:.*]] = bitcast <8 x i16> %[[VAL_68]] to <16 x i8>
+! LLVMIR: %[[VAL_73:.*]] = bitcast <8 x i16> %[[VAL_69]] to <16 x i8>
+! LLVMIR: %[[VAL_74:.*]] = bitcast <8 x i16> %[[VAL_70]] to <16 x i8>
+! LLVMIR: %[[VAL_75:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_71]], <16 x i8> %[[VAL_72]], <16 x i8> %[[VAL_73]], <16 x i8> %[[VAL_74]])
+! LLVMIR: store <512 x i1> %[[VAL_75]], ptr %[[VAL_66]], align 64
subroutine test_assemble_acc_u4()
use, intrinsic :: mma
@@ -156,21 +157,21 @@
end subroutine test_assemble_acc_u4
! CHECK-LABEL: @test_assemble_acc_u4
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %3 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %4 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %5 = alloca <4 x i32>, i64 1, align 16
-! LLVMIR: %6 = load <4 x i32>, ptr %2, align 16
-! LLVMIR: %7 = load <4 x i32>, ptr %3, align 16
-! LLVMIR: %8 = load <4 x i32>, ptr %4, align 16
-! LLVMIR: %9 = load <4 x i32>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <4 x i32> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <4 x i32> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <4 x i32> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <4 x i32> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_76:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_77:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_78:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_79:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_80:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_81:.*]] = load <4 x i32>, ptr %[[VAL_79]], align 16
+! LLVMIR: %[[VAL_82:.*]] = load <4 x i32>, ptr %[[VAL_78]], align 16
+! LLVMIR: %[[VAL_83:.*]] = load <4 x i32>, ptr %[[VAL_77]], align 16
+! LLVMIR: %[[VAL_84:.*]] = load <4 x i32>, ptr %[[VAL_76]], align 16
+! LLVMIR: %[[VAL_85:.*]] = bitcast <4 x i32> %[[VAL_81]] to <16 x i8>
+! LLVMIR: %[[VAL_86:.*]] = bitcast <4 x i32> %[[VAL_82]] to <16 x i8>
+! LLVMIR: %[[VAL_87:.*]] = bitcast <4 x i32> %[[VAL_83]] to <16 x i8>
+! LLVMIR: %[[VAL_88:.*]] = bitcast <4 x i32> %[[VAL_84]] to <16 x i8>
+! LLVMIR: %[[VAL_89:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_85]], <16 x i8> %[[VAL_86]], <16 x i8> %[[VAL_87]], <16 x i8> %[[VAL_88]])
+! LLVMIR: store <512 x i1> %[[VAL_89]], ptr %[[VAL_80]], align 64
subroutine test_assemble_acc_u8()
use, intrinsic :: mma
@@ -181,21 +182,21 @@
end subroutine test_assemble_acc_u8
! CHECK-LABEL: @test_assemble_acc_u8
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %3 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %4 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %5 = alloca <2 x i64>, i64 1, align 16
-! LLVMIR: %6 = load <2 x i64>, ptr %2, align 16
-! LLVMIR: %7 = load <2 x i64>, ptr %3, align 16
-! LLVMIR: %8 = load <2 x i64>, ptr %4, align 16
-! LLVMIR: %9 = load <2 x i64>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <2 x i64> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <2 x i64> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <2 x i64> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <2 x i64> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_90:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_91:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_92:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_93:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_94:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_95:.*]] = load <2 x i64>, ptr %[[VAL_93]], align 16
+! LLVMIR: %[[VAL_96:.*]] = load <2 x i64>, ptr %[[VAL_92]], align 16
+! LLVMIR: %[[VAL_97:.*]] = load <2 x i64>, ptr %[[VAL_91]], align 16
+! LLVMIR: %[[VAL_98:.*]] = load <2 x i64>, ptr %[[VAL_90]], align 16
+! LLVMIR: %[[VAL_99:.*]] = bitcast <2 x i64> %[[VAL_95]] to <16 x i8>
+! LLVMIR: %[[VAL_100:.*]] = bitcast <2 x i64> %[[VAL_96]] to <16 x i8>
+! LLVMIR: %[[VAL_101:.*]] = bitcast <2 x i64> %[[VAL_97]] to <16 x i8>
+! LLVMIR: %[[VAL_102:.*]] = bitcast <2 x i64> %[[VAL_98]] to <16 x i8>
+! LLVMIR: %[[VAL_103:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_99]], <16 x i8> %[[VAL_100]], <16 x i8> %[[VAL_101]], <16 x i8> %[[VAL_102]])
+! LLVMIR: store <512 x i1> %[[VAL_103]], ptr %[[VAL_94]], align 64
subroutine test_assemble_acc_r4()
use, intrinsic :: mma
@@ -206,21 +207,21 @@
end subroutine test_assemble_acc_r4
! CHECK-LABEL: @test_assemble_acc_r4
-! LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-! LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-! LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-! LLVMIR: %4 = alloca <4 x float>, i64 1, align 16
-! LLVMIR: %5 = alloca <4 x float>, i64 1, align 16
-! LLVMIR: %6 = load <4 x float>, ptr %2, align 16
-! LLVMIR: %7 = load <4 x float>, ptr %3, align 16
-! LLVMIR: %8 = load <4 x float>, ptr %4, align 16
-! LLVMIR: %9 = load <4 x float>, ptr %5, align 16
-! LLVMIR: %10 = bitcast <4 x float> %6 to <16 x i8>
-! LLVMIR: %11 = bitcast <4 x float> %7 to <16 x i8>
-! LLVMIR: %12 = bitcast <4 x float> %8 to <16 x i8>
-! LLVMIR: %13 = bitcast <4 x float> %9 to <16 x i8>
-! LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-! LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_104:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_105:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_106:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_107:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_108:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_109:.*]] = load <4 x float>, ptr %[[VAL_107]], align 16
+! LLVMIR: %[[VAL_110:.*]] = load <4 x float>, ptr %[[VAL_106]], align 16
+! LLVMIR: %[[VAL_111:.*]] = load <4 x float>, ptr %[[VAL_105]], align 16
+! LLVMIR: %[[VAL_112:.*]] = load <4 x float>, ptr %[[VAL_104]], align 16
+! LLVMIR: %[[VAL_113:.*]] = bitcast <4 x float> %[[VAL_109]] to <16 x i8>
+! LLVMIR: %[[VAL_114:.*]] = bitcast <4 x float> %[[VAL_110]] to <16 x i8>
+! LLVMIR: %[[VAL_115:.*]] = bitcast <4 x float> %[[VAL_111]] to <16 x i8>
+! LLVMIR: %[[VAL_116:.*]] = bitcast <4 x float> %[[VAL_112]] to <16 x i8>
+! LLVMIR: %[[VAL_117:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_113]], <16 x i8> %[[VAL_114]], <16 x i8> %[[VAL_115]], <16 x i8> %[[VAL_116]])
+! LLVMIR: store <512 x i1> %[[VAL_117]], ptr %[[VAL_108]], align 64
subroutine test_assemble_acc_r8()
use, intrinsic :: mma
@@ -231,21 +232,21 @@
end subroutine test_assemble_acc_r8
!CHECK-LABEL: @test_assemble_acc_r8
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %5 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %6 = load <2 x double>, ptr %2, align 16
-!LLVMIR: %7 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %8 = load <2 x double>, ptr %4, align 16
-!LLVMIR: %9 = load <2 x double>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <2 x double> %6 to <16 x i8>
-!LLVMIR: %11 = bitcast <2 x double> %7 to <16 x i8>
-!LLVMIR: %12 = bitcast <2 x double> %8 to <16 x i8>
-!LLVMIR: %13 = bitcast <2 x double> %9 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_118:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_119:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_120:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_121:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_122:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_123:.*]] = load <2 x double>, ptr %[[VAL_121]], align 16
+! LLVMIR: %[[VAL_124:.*]] = load <2 x double>, ptr %[[VAL_120]], align 16
+! LLVMIR: %[[VAL_125:.*]] = load <2 x double>, ptr %[[VAL_119]], align 16
+! LLVMIR: %[[VAL_126:.*]] = load <2 x double>, ptr %[[VAL_118]], align 16
+! LLVMIR: %[[VAL_127:.*]] = bitcast <2 x double> %[[VAL_123]] to <16 x i8>
+! LLVMIR: %[[VAL_128:.*]] = bitcast <2 x double> %[[VAL_124]] to <16 x i8>
+! LLVMIR: %[[VAL_129:.*]] = bitcast <2 x double> %[[VAL_125]] to <16 x i8>
+! LLVMIR: %[[VAL_130:.*]] = bitcast <2 x double> %[[VAL_126]] to <16 x i8>
+! LLVMIR: %[[VAL_131:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_127]], <16 x i8> %[[VAL_128]], <16 x i8> %[[VAL_129]], <16 x i8> %[[VAL_130]])
+! LLVMIR: store <512 x i1> %[[VAL_131]], ptr %[[VAL_122]], align 64
! mma_assemble_pair
@@ -258,13 +259,13 @@
end subroutine test_mma_assemble_pair_i1
!LLVMIR: @test_mma_assemble_pair_i1_
-!LLVMIR: %1 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <16 x i8>, ptr %1, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %6 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <256 x i1> %6, ptr %3, align 32
+! LLVMIR: %[[VAL_132:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_133:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_134:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_135:.*]] = load <16 x i8>, ptr %[[VAL_134]], align 16
+! LLVMIR: %[[VAL_136:.*]] = load <16 x i8>, ptr %[[VAL_133]], align 16
+! LLVMIR: %[[VAL_137:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_135]], <16 x i8> %[[VAL_136]])
+! LLVMIR: store <256 x i1> %[[VAL_137]], ptr %[[VAL_132]], align 32
subroutine test_mma_assemble_pair_i2()
use, intrinsic :: mma
@@ -275,15 +276,15 @@
end subroutine test_mma_assemble_pair_i2
!LLVMIR: @test_mma_assemble_pair_i2_
-!LLVMIR: %1 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <8 x i16>, ptr %1, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_138:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_139:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_140:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_141:.*]] = load <8 x i16>, ptr %[[VAL_140]], align 16
+! LLVMIR: %[[VAL_142:.*]] = load <8 x i16>, ptr %[[VAL_139]], align 16
+! LLVMIR: %[[VAL_143:.*]] = bitcast <8 x i16> %[[VAL_141]] to <16 x i8>
+! LLVMIR: %[[VAL_144:.*]] = bitcast <8 x i16> %[[VAL_142]] to <16 x i8>
+! LLVMIR: %[[VAL_145:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_143]], <16 x i8> %[[VAL_144]])
+! LLVMIR: store <256 x i1> %[[VAL_145]], ptr %[[VAL_138]], align 32
subroutine test_mma_assemble_pair_i4()
use, intrinsic :: mma
@@ -294,15 +295,15 @@
end subroutine test_mma_assemble_pair_i4
!LLVMIR: @test_mma_assemble_pair_i4_
-!LLVMIR: %1 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <4 x i32>, ptr %1, align 16
-!LLVMIR: %5 = load <4 x i32>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <4 x i32> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x i32> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_146:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_147:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_148:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_149:.*]] = load <4 x i32>, ptr %[[VAL_148]], align 16
+! LLVMIR: %[[VAL_150:.*]] = load <4 x i32>, ptr %[[VAL_147]], align 16
+! LLVMIR: %[[VAL_151:.*]] = bitcast <4 x i32> %[[VAL_149]] to <16 x i8>
+! LLVMIR: %[[VAL_152:.*]] = bitcast <4 x i32> %[[VAL_150]] to <16 x i8>
+! LLVMIR: %[[VAL_153:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_151]], <16 x i8> %[[VAL_152]])
+! LLVMIR: store <256 x i1> %[[VAL_153]], ptr %[[VAL_146]], align 32
subroutine test_mma_assemble_pair_i8()
use, intrinsic :: mma
@@ -313,15 +314,15 @@
end subroutine test_mma_assemble_pair_i8
!LLVMIR: @test_mma_assemble_pair_i8_
-!LLVMIR: %1 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <2 x i64>, ptr %1, align 16
-!LLVMIR: %5 = load <2 x i64>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <2 x i64> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <2 x i64> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_154:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_155:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_156:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_157:.*]] = load <2 x i64>, ptr %[[VAL_156]], align 16
+! LLVMIR: %[[VAL_158:.*]] = load <2 x i64>, ptr %[[VAL_155]], align 16
+! LLVMIR: %[[VAL_159:.*]] = bitcast <2 x i64> %[[VAL_157]] to <16 x i8>
+! LLVMIR: %[[VAL_160:.*]] = bitcast <2 x i64> %[[VAL_158]] to <16 x i8>
+! LLVMIR: %[[VAL_161:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_159]], <16 x i8> %[[VAL_160]])
+! LLVMIR: store <256 x i1> %[[VAL_161]], ptr %[[VAL_154]], align 32
subroutine test_mma_assemble_pair_u1()
use, intrinsic :: mma
@@ -332,13 +333,13 @@
end subroutine test_mma_assemble_pair_u1
!LLVMIR: @test_mma_assemble_pair_u1_
-!LLVMIR: %1 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <16 x i8>, ptr %1, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %6 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <256 x i1> %6, ptr %3, align 32
+! LLVMIR: %[[VAL_162:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_163:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_164:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_165:.*]] = load <16 x i8>, ptr %[[VAL_164]], align 16
+! LLVMIR: %[[VAL_166:.*]] = load <16 x i8>, ptr %[[VAL_163]], align 16
+! LLVMIR: %[[VAL_167:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_165]], <16 x i8> %[[VAL_166]])
+! LLVMIR: store <256 x i1> %[[VAL_167]], ptr %[[VAL_162]], align 32
subroutine test_mma_assemble_pair_u2()
use, intrinsic :: mma
@@ -349,15 +350,15 @@
end subroutine test_mma_assemble_pair_u2
!LLVMIR: @test_mma_assemble_pair_u2_
-!LLVMIR: %1 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <8 x i16>, ptr %1, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_168:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_169:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_170:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_171:.*]] = load <8 x i16>, ptr %[[VAL_170]], align 16
+! LLVMIR: %[[VAL_172:.*]] = load <8 x i16>, ptr %[[VAL_169]], align 16
+! LLVMIR: %[[VAL_173:.*]] = bitcast <8 x i16> %[[VAL_171]] to <16 x i8>
+! LLVMIR: %[[VAL_174:.*]] = bitcast <8 x i16> %[[VAL_172]] to <16 x i8>
+! LLVMIR: %[[VAL_175:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_173]], <16 x i8> %[[VAL_174]])
+! LLVMIR: store <256 x i1> %[[VAL_175]], ptr %[[VAL_168]], align 32
subroutine test_mma_assemble_pair_u4()
use, intrinsic :: mma
@@ -368,15 +369,15 @@
end subroutine test_mma_assemble_pair_u4
!LLVMIR: @test_mma_assemble_pair_u4_
-!LLVMIR: %1 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <4 x i32>, ptr %1, align 16
-!LLVMIR: %5 = load <4 x i32>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <4 x i32> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x i32> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_176:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_177:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_178:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_179:.*]] = load <4 x i32>, ptr %[[VAL_178]], align 16
+! LLVMIR: %[[VAL_180:.*]] = load <4 x i32>, ptr %[[VAL_177]], align 16
+! LLVMIR: %[[VAL_181:.*]] = bitcast <4 x i32> %[[VAL_179]] to <16 x i8>
+! LLVMIR: %[[VAL_182:.*]] = bitcast <4 x i32> %[[VAL_180]] to <16 x i8>
+! LLVMIR: %[[VAL_183:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_181]], <16 x i8> %[[VAL_182]])
+! LLVMIR: store <256 x i1> %[[VAL_183]], ptr %[[VAL_176]], align 32
subroutine test_mma_assemble_pair_u8()
use, intrinsic :: mma
@@ -387,15 +388,15 @@
end subroutine test_mma_assemble_pair_u8
!LLVMIR: @test_mma_assemble_pair_u8_
-!LLVMIR: %1 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <2 x i64>, ptr %1, align 16
-!LLVMIR: %5 = load <2 x i64>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <2 x i64> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <2 x i64> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_184:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_185:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_186:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_187:.*]] = load <2 x i64>, ptr %[[VAL_186]], align 16
+! LLVMIR: %[[VAL_188:.*]] = load <2 x i64>, ptr %[[VAL_185]], align 16
+! LLVMIR: %[[VAL_189:.*]] = bitcast <2 x i64> %[[VAL_187]] to <16 x i8>
+! LLVMIR: %[[VAL_190:.*]] = bitcast <2 x i64> %[[VAL_188]] to <16 x i8>
+! LLVMIR: %[[VAL_191:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_189]], <16 x i8> %[[VAL_190]])
+! LLVMIR: store <256 x i1> %[[VAL_191]], ptr %[[VAL_184]], align 32
subroutine test_mma_assemble_pair_r4()
use, intrinsic :: mma
@@ -406,15 +407,15 @@
end subroutine test_mma_assemble_pair_r4
!LLVMIR: @test_mma_assemble_pair_r4_
-!LLVMIR: %1 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <4 x float>, ptr %1, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_192:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_193:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_194:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_195:.*]] = load <4 x float>, ptr %[[VAL_194]], align 16
+! LLVMIR: %[[VAL_196:.*]] = load <4 x float>, ptr %[[VAL_193]], align 16
+! LLVMIR: %[[VAL_197:.*]] = bitcast <4 x float> %[[VAL_195]] to <16 x i8>
+! LLVMIR: %[[VAL_198:.*]] = bitcast <4 x float> %[[VAL_196]] to <16 x i8>
+! LLVMIR: %[[VAL_199:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_197]], <16 x i8> %[[VAL_198]])
+! LLVMIR: store <256 x i1> %[[VAL_199]], ptr %[[VAL_192]], align 32
subroutine test_mma_assemble_pair_r8()
use, intrinsic :: mma
@@ -425,15 +426,15 @@
end subroutine test_mma_assemble_pair_r8
!LLVMIR: @test_mma_assemble_pair_r8_
-!LLVMIR: %1 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %2 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %3 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %4 = load <2 x double>, ptr %1, align 16
-!LLVMIR: %5 = load <2 x double>, ptr %2, align 16
-!LLVMIR: %6 = bitcast <2 x double> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <256 x i1> %8, ptr %3, align 32
+! LLVMIR: %[[VAL_200:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_201:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_202:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_203:.*]] = load <2 x double>, ptr %[[VAL_202]], align 16
+! LLVMIR: %[[VAL_204:.*]] = load <2 x double>, ptr %[[VAL_201]], align 16
+! LLVMIR: %[[VAL_205:.*]] = bitcast <2 x double> %[[VAL_203]] to <16 x i8>
+! LLVMIR: %[[VAL_206:.*]] = bitcast <2 x double> %[[VAL_204]] to <16 x i8>
+! LLVMIR: %[[VAL_207:.*]] = call <256 x i1> @llvm.ppc.vsx.assemble.pair(<16 x i8> %[[VAL_205]], <16 x i8> %[[VAL_206]])
+! LLVMIR: store <256 x i1> %[[VAL_207]], ptr %[[VAL_200]], align 32
! mma_disassemble_acc
@@ -446,17 +447,17 @@
end subroutine test_mma_build_acc_i1
!CHECK-LABEL: @test_mma_build_acc_i1
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %5 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %6 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %7 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %8 = load <16 x i8>, ptr %4, align 16
-!LLVMIR: %9 = load <16 x i8>, ptr %5, align 16
-!LLVMIR: %10 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %9, <16 x i8> %8, <16 x i8> %7, <16 x i8> %6)
-!LLVMIR: store <512 x i1> %10, ptr %1, align 64
+! LLVMIR: %[[VAL_208:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_209:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_210:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_211:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_212:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_213:.*]] = load <16 x i8>, ptr %[[VAL_211]], align 16
+! LLVMIR: %[[VAL_214:.*]] = load <16 x i8>, ptr %[[VAL_210]], align 16
+! LLVMIR: %[[VAL_215:.*]] = load <16 x i8>, ptr %[[VAL_209]], align 16
+! LLVMIR: %[[VAL_216:.*]] = load <16 x i8>, ptr %[[VAL_208]], align 16
+! LLVMIR: %[[VAL_217:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_216]], <16 x i8> %[[VAL_215]], <16 x i8> %[[VAL_214]], <16 x i8> %[[VAL_213]])
+! LLVMIR: store <512 x i1> %[[VAL_217]], ptr %[[VAL_212]], align 64
subroutine test_mma_build_acc_i2()
use, intrinsic :: mma
@@ -467,21 +468,21 @@
end subroutine test_mma_build_acc_i2
!CHECK-LABEL: @test_mma_build_acc_i2
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %5 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %6 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %7 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %8 = load <8 x i16>, ptr %4, align 16
-!LLVMIR: %9 = load <8 x i16>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <8 x i16> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <8 x i16> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <8 x i16> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <8 x i16> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_218:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_219:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_220:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_221:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_222:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_223:.*]] = load <8 x i16>, ptr %[[VAL_221]], align 16
+! LLVMIR: %[[VAL_224:.*]] = load <8 x i16>, ptr %[[VAL_220]], align 16
+! LLVMIR: %[[VAL_225:.*]] = load <8 x i16>, ptr %[[VAL_219]], align 16
+! LLVMIR: %[[VAL_226:.*]] = load <8 x i16>, ptr %[[VAL_218]], align 16
+! LLVMIR: %[[VAL_227:.*]] = bitcast <8 x i16> %[[VAL_226]] to <16 x i8>
+! LLVMIR: %[[VAL_228:.*]] = bitcast <8 x i16> %[[VAL_225]] to <16 x i8>
+! LLVMIR: %[[VAL_229:.*]] = bitcast <8 x i16> %[[VAL_224]] to <16 x i8>
+! LLVMIR: %[[VAL_230:.*]] = bitcast <8 x i16> %[[VAL_223]] to <16 x i8>
+! LLVMIR: %[[VAL_231:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_227]], <16 x i8> %[[VAL_228]], <16 x i8> %[[VAL_229]], <16 x i8> %[[VAL_230]])
+! LLVMIR: store <512 x i1> %[[VAL_231]], ptr %[[VAL_222]], align 64
subroutine test_mma_build_acc_i4()
use, intrinsic :: mma
@@ -492,21 +493,21 @@
end subroutine test_mma_build_acc_i4
!CHECK-LABEL: @test_mma_build_acc_i4
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %4 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %5 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %6 = load <4 x i32>, ptr %2, align 16
-!LLVMIR: %7 = load <4 x i32>, ptr %3, align 16
-!LLVMIR: %8 = load <4 x i32>, ptr %4, align 16
-!LLVMIR: %9 = load <4 x i32>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <4 x i32> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <4 x i32> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <4 x i32> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <4 x i32> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_232:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_233:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_234:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_235:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_236:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_237:.*]] = load <4 x i32>, ptr %[[VAL_235]], align 16
+! LLVMIR: %[[VAL_238:.*]] = load <4 x i32>, ptr %[[VAL_234]], align 16
+! LLVMIR: %[[VAL_239:.*]] = load <4 x i32>, ptr %[[VAL_233]], align 16
+! LLVMIR: %[[VAL_240:.*]] = load <4 x i32>, ptr %[[VAL_232]], align 16
+! LLVMIR: %[[VAL_241:.*]] = bitcast <4 x i32> %[[VAL_240]] to <16 x i8>
+! LLVMIR: %[[VAL_242:.*]] = bitcast <4 x i32> %[[VAL_239]] to <16 x i8>
+! LLVMIR: %[[VAL_243:.*]] = bitcast <4 x i32> %[[VAL_238]] to <16 x i8>
+! LLVMIR: %[[VAL_244:.*]] = bitcast <4 x i32> %[[VAL_237]] to <16 x i8>
+! LLVMIR: %[[VAL_245:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_241]], <16 x i8> %[[VAL_242]], <16 x i8> %[[VAL_243]], <16 x i8> %[[VAL_244]])
+! LLVMIR: store <512 x i1> %[[VAL_245]], ptr %[[VAL_236]], align 64
subroutine test_mma_build_acc_i8()
use, intrinsic :: mma
@@ -517,21 +518,21 @@
end subroutine test_mma_build_acc_i8
!CHECK-LABEL: @test_mma_build_acc_i8
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %3 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %4 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %5 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %6 = load <2 x i64>, ptr %2, align 16
-!LLVMIR: %7 = load <2 x i64>, ptr %3, align 16
-!LLVMIR: %8 = load <2 x i64>, ptr %4, align 16
-!LLVMIR: %9 = load <2 x i64>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <2 x i64> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <2 x i64> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <2 x i64> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <2 x i64> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_246:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_247:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_248:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_249:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_250:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_251:.*]] = load <2 x i64>, ptr %[[VAL_249]], align 16
+! LLVMIR: %[[VAL_252:.*]] = load <2 x i64>, ptr %[[VAL_248]], align 16
+! LLVMIR: %[[VAL_253:.*]] = load <2 x i64>, ptr %[[VAL_247]], align 16
+! LLVMIR: %[[VAL_254:.*]] = load <2 x i64>, ptr %[[VAL_246]], align 16
+! LLVMIR: %[[VAL_255:.*]] = bitcast <2 x i64> %[[VAL_254]] to <16 x i8>
+! LLVMIR: %[[VAL_256:.*]] = bitcast <2 x i64> %[[VAL_253]] to <16 x i8>
+! LLVMIR: %[[VAL_257:.*]] = bitcast <2 x i64> %[[VAL_252]] to <16 x i8>
+! LLVMIR: %[[VAL_258:.*]] = bitcast <2 x i64> %[[VAL_251]] to <16 x i8>
+! LLVMIR: %[[VAL_259:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_255]], <16 x i8> %[[VAL_256]], <16 x i8> %[[VAL_257]], <16 x i8> %[[VAL_258]])
+! LLVMIR: store <512 x i1> %[[VAL_259]], ptr %[[VAL_250]], align 64
subroutine test_mma_build_acc_u1()
use, intrinsic :: mma
@@ -542,17 +543,17 @@
end subroutine test_mma_build_acc_u1
!CHECK-LABEL: @test_mma_build_acc_u1
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %5 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %6 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %7 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %8 = load <16 x i8>, ptr %4, align 16
-!LLVMIR: %9 = load <16 x i8>, ptr %5, align 16
-!LLVMIR: %10 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %9, <16 x i8> %8, <16 x i8> %7, <16 x i8> %6)
-!LLVMIR: store <512 x i1> %10, ptr %1, align 64
+! LLVMIR: %[[VAL_260:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_261:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_262:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_263:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_264:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_265:.*]] = load <16 x i8>, ptr %[[VAL_263]], align 16
+! LLVMIR: %[[VAL_266:.*]] = load <16 x i8>, ptr %[[VAL_262]], align 16
+! LLVMIR: %[[VAL_267:.*]] = load <16 x i8>, ptr %[[VAL_261]], align 16
+! LLVMIR: %[[VAL_268:.*]] = load <16 x i8>, ptr %[[VAL_260]], align 16
+! LLVMIR: %[[VAL_269:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_268]], <16 x i8> %[[VAL_267]], <16 x i8> %[[VAL_266]], <16 x i8> %[[VAL_265]])
+! LLVMIR: store <512 x i1> %[[VAL_269]], ptr %[[VAL_264]], align 64
subroutine test_mma_build_acc_u2()
use, intrinsic :: mma
@@ -563,21 +564,21 @@
end subroutine test_mma_build_acc_u2
!CHECK-LABEL: @test_mma_build_acc_u2
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %5 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %6 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %7 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %8 = load <8 x i16>, ptr %4, align 16
-!LLVMIR: %9 = load <8 x i16>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <8 x i16> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <8 x i16> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <8 x i16> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <8 x i16> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_270:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_271:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_272:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_273:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_274:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_275:.*]] = load <8 x i16>, ptr %[[VAL_273]], align 16
+! LLVMIR: %[[VAL_276:.*]] = load <8 x i16>, ptr %[[VAL_272]], align 16
+! LLVMIR: %[[VAL_277:.*]] = load <8 x i16>, ptr %[[VAL_271]], align 16
+! LLVMIR: %[[VAL_278:.*]] = load <8 x i16>, ptr %[[VAL_270]], align 16
+! LLVMIR: %[[VAL_279:.*]] = bitcast <8 x i16> %[[VAL_278]] to <16 x i8>
+! LLVMIR: %[[VAL_280:.*]] = bitcast <8 x i16> %[[VAL_277]] to <16 x i8>
+! LLVMIR: %[[VAL_281:.*]] = bitcast <8 x i16> %[[VAL_276]] to <16 x i8>
+! LLVMIR: %[[VAL_282:.*]] = bitcast <8 x i16> %[[VAL_275]] to <16 x i8>
+! LLVMIR: %[[VAL_283:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_279]], <16 x i8> %[[VAL_280]], <16 x i8> %[[VAL_281]], <16 x i8> %[[VAL_282]])
+! LLVMIR: store <512 x i1> %[[VAL_283]], ptr %[[VAL_274]], align 64
subroutine test_mma_build_acc_u4()
use, intrinsic :: mma
@@ -588,21 +589,21 @@
end subroutine test_mma_build_acc_u4
!CHECK-LABEL: @test_mma_build_acc_u4
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %4 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %5 = alloca <4 x i32>, i64 1, align 16
-!LLVMIR: %6 = load <4 x i32>, ptr %2, align 16
-!LLVMIR: %7 = load <4 x i32>, ptr %3, align 16
-!LLVMIR: %8 = load <4 x i32>, ptr %4, align 16
-!LLVMIR: %9 = load <4 x i32>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <4 x i32> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <4 x i32> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <4 x i32> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <4 x i32> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_284:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_285:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_286:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_287:.*]] = alloca <4 x i32>, i64 1, align 16
+! LLVMIR: %[[VAL_288:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_289:.*]] = load <4 x i32>, ptr %[[VAL_287]], align 16
+! LLVMIR: %[[VAL_290:.*]] = load <4 x i32>, ptr %[[VAL_286]], align 16
+! LLVMIR: %[[VAL_291:.*]] = load <4 x i32>, ptr %[[VAL_285]], align 16
+! LLVMIR: %[[VAL_292:.*]] = load <4 x i32>, ptr %[[VAL_284]], align 16
+! LLVMIR: %[[VAL_293:.*]] = bitcast <4 x i32> %[[VAL_292]] to <16 x i8>
+! LLVMIR: %[[VAL_294:.*]] = bitcast <4 x i32> %[[VAL_291]] to <16 x i8>
+! LLVMIR: %[[VAL_295:.*]] = bitcast <4 x i32> %[[VAL_290]] to <16 x i8>
+! LLVMIR: %[[VAL_296:.*]] = bitcast <4 x i32> %[[VAL_289]] to <16 x i8>
+! LLVMIR: %[[VAL_297:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_293]], <16 x i8> %[[VAL_294]], <16 x i8> %[[VAL_295]], <16 x i8> %[[VAL_296]])
+! LLVMIR: store <512 x i1> %[[VAL_297]], ptr %[[VAL_288]], align 64
subroutine test_mma_build_acc_u8()
use, intrinsic :: mma
@@ -613,21 +614,21 @@
end subroutine test_mma_build_acc_u8
!CHECK-LABEL: @test_mma_build_acc_u8
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %3 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %4 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %5 = alloca <2 x i64>, i64 1, align 16
-!LLVMIR: %6 = load <2 x i64>, ptr %2, align 16
-!LLVMIR: %7 = load <2 x i64>, ptr %3, align 16
-!LLVMIR: %8 = load <2 x i64>, ptr %4, align 16
-!LLVMIR: %9 = load <2 x i64>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <2 x i64> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <2 x i64> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <2 x i64> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <2 x i64> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_298:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_299:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_300:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_301:.*]] = alloca <2 x i64>, i64 1, align 16
+! LLVMIR: %[[VAL_302:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_303:.*]] = load <2 x i64>, ptr %[[VAL_301]], align 16
+! LLVMIR: %[[VAL_304:.*]] = load <2 x i64>, ptr %[[VAL_300]], align 16
+! LLVMIR: %[[VAL_305:.*]] = load <2 x i64>, ptr %[[VAL_299]], align 16
+! LLVMIR: %[[VAL_306:.*]] = load <2 x i64>, ptr %[[VAL_298]], align 16
+! LLVMIR: %[[VAL_307:.*]] = bitcast <2 x i64> %[[VAL_306]] to <16 x i8>
+! LLVMIR: %[[VAL_308:.*]] = bitcast <2 x i64> %[[VAL_305]] to <16 x i8>
+! LLVMIR: %[[VAL_309:.*]] = bitcast <2 x i64> %[[VAL_304]] to <16 x i8>
+! LLVMIR: %[[VAL_310:.*]] = bitcast <2 x i64> %[[VAL_303]] to <16 x i8>
+! LLVMIR: %[[VAL_311:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_307]], <16 x i8> %[[VAL_308]], <16 x i8> %[[VAL_309]], <16 x i8> %[[VAL_310]])
+! LLVMIR: store <512 x i1> %[[VAL_311]], ptr %[[VAL_302]], align 64
subroutine test_mma_build_acc_r4()
@@ -639,21 +640,21 @@
end subroutine test_mma_build_acc_r4
!CHECK-LABEL: @test_mma_build_acc_r4
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %5 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %6 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %7 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %8 = load <4 x float>, ptr %4, align 16
-!LLVMIR: %9 = load <4 x float>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <4 x float> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <4 x float> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <4 x float> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <4 x float> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_312:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_313:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_314:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_315:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_316:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_317:.*]] = load <4 x float>, ptr %[[VAL_315]], align 16
+! LLVMIR: %[[VAL_318:.*]] = load <4 x float>, ptr %[[VAL_314]], align 16
+! LLVMIR: %[[VAL_319:.*]] = load <4 x float>, ptr %[[VAL_313]], align 16
+! LLVMIR: %[[VAL_320:.*]] = load <4 x float>, ptr %[[VAL_312]], align 16
+! LLVMIR: %[[VAL_321:.*]] = bitcast <4 x float> %[[VAL_320]] to <16 x i8>
+! LLVMIR: %[[VAL_322:.*]] = bitcast <4 x float> %[[VAL_319]] to <16 x i8>
+! LLVMIR: %[[VAL_323:.*]] = bitcast <4 x float> %[[VAL_318]] to <16 x i8>
+! LLVMIR: %[[VAL_324:.*]] = bitcast <4 x float> %[[VAL_317]] to <16 x i8>
+! LLVMIR: %[[VAL_325:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_321]], <16 x i8> %[[VAL_322]], <16 x i8> %[[VAL_323]], <16 x i8> %[[VAL_324]])
+! LLVMIR: store <512 x i1> %[[VAL_325]], ptr %[[VAL_316]], align 64
subroutine test_mma_build_acc_r8()
@@ -665,21 +666,21 @@
end subroutine test_mma_build_acc_r8
!CHECK-LABEL: @test_mma_build_acc_r8
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %5 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %6 = load <2 x double>, ptr %2, align 16
-!LLVMIR: %7 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %8 = load <2 x double>, ptr %4, align 16
-!LLVMIR: %9 = load <2 x double>, ptr %5, align 16
-!LLVMIR: %10 = bitcast <2 x double> %9 to <16 x i8>
-!LLVMIR: %11 = bitcast <2 x double> %8 to <16 x i8>
-!LLVMIR: %12 = bitcast <2 x double> %7 to <16 x i8>
-!LLVMIR: %13 = bitcast <2 x double> %6 to <16 x i8>
-!LLVMIR: %14 = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %10, <16 x i8> %11, <16 x i8> %12, <16 x i8> %13)
-!LLVMIR: store <512 x i1> %14, ptr %1, align 64
+! LLVMIR: %[[VAL_326:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_327:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_328:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_329:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_330:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_331:.*]] = load <2 x double>, ptr %[[VAL_329]], align 16
+! LLVMIR: %[[VAL_332:.*]] = load <2 x double>, ptr %[[VAL_328]], align 16
+! LLVMIR: %[[VAL_333:.*]] = load <2 x double>, ptr %[[VAL_327]], align 16
+! LLVMIR: %[[VAL_334:.*]] = load <2 x double>, ptr %[[VAL_326]], align 16
+! LLVMIR: %[[VAL_335:.*]] = bitcast <2 x double> %[[VAL_334]] to <16 x i8>
+! LLVMIR: %[[VAL_336:.*]] = bitcast <2 x double> %[[VAL_333]] to <16 x i8>
+! LLVMIR: %[[VAL_337:.*]] = bitcast <2 x double> %[[VAL_332]] to <16 x i8>
+! LLVMIR: %[[VAL_338:.*]] = bitcast <2 x double> %[[VAL_331]] to <16 x i8>
+! LLVMIR: %[[VAL_339:.*]] = call <512 x i1> @llvm.ppc.mma.assemble.acc(<16 x i8> %[[VAL_335]], <16 x i8> %[[VAL_336]], <16 x i8> %[[VAL_337]], <16 x i8> %[[VAL_338]])
+! LLVMIR: store <512 x i1> %[[VAL_339]], ptr %[[VAL_330]], align 64
! mma_disassemble_acc
@@ -692,11 +693,11 @@
end subroutine
!CHECK-LABEL: @test_disassemble_acc_
-!LLVMIR: %1 = alloca float, i64 1, align 4
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %4 = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.ppc.mma.disassemble.acc(<512 x i1> %3)
-!LLVMIR: store { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %4, ptr %1, align 16
+! LLVMIR: %[[VAL_340:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_341:.*]] = alloca float, i64 1, align 4
+! LLVMIR: %[[VAL_342:.*]] = load <512 x i1>, ptr %[[VAL_340]], align 64
+! LLVMIR: %[[VAL_343:.*]] = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.ppc.mma.disassemble.acc(<512 x i1> %[[VAL_342]])
+! LLVMIR: store { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %[[VAL_343]], ptr %[[VAL_341]], align 16
! mma_disassemble_pair
@@ -709,8 +710,8 @@
end subroutine
!CHECK-LABEL: @test_disassemble_pair_
-!LLVMIR: %1 = alloca float, i64 1, align 4
-!LLVMIR: %2 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %3 = load <256 x i1>, ptr %2, align 32
-!LLVMIR: %4 = call { <16 x i8>, <16 x i8> } @llvm.ppc.vsx.disassemble.pair(<256 x i1> %3)
-!LLVMIR: store { <16 x i8>, <16 x i8> } %4, ptr %1, align 16
+! LLVMIR: %[[VAL_344:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_345:.*]] = alloca float, i64 1, align 4
+! LLVMIR: %[[VAL_346:.*]] = load <256 x i1>, ptr %[[VAL_344]], align 32
+! LLVMIR: %[[VAL_347:.*]] = call { <16 x i8>, <16 x i8> } @llvm.ppc.vsx.disassemble.pair(<256 x i1> %[[VAL_346]])
+! LLVMIR: store { <16 x i8>, <16 x i8> } %[[VAL_347]], ptr %[[VAL_345]], align 16
diff --git a/flang/test/Lower/PowerPC/ppc-mma-outer-product-1.f90 b/flang/test/Lower/PowerPC/ppc-mma-outer-product-1.f90
index 97bebc7683c0..6ad7958dedb9 100644
--- a/flang/test/Lower/PowerPC/ppc-mma-outer-product-1.f90
+++ b/flang/test/Lower/PowerPC/ppc-mma-outer-product-1.f90
@@ -10,13 +10,13 @@
end subroutine test_pmxvbf16ger2_def
!CHECK-LABEL: @test_pmxvbf16ger2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_0:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_1:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_2:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_3:.*]] = load <16 x i8>, ptr %[[VAL_1]], align 16
+! LLVMIR: %[[VAL_4:.*]] = load <16 x i8>, ptr %[[VAL_0]], align 16
+! LLVMIR: %[[VAL_5:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2(<16 x i8> %[[VAL_3]], <16 x i8> %[[VAL_4]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_5]], ptr %[[VAL_2]], align 64
subroutine test_pmxvbf16ger2_non_def()
@@ -28,13 +28,13 @@
end subroutine test_pmxvbf16ger2_non_def
!CHECK-LABEL: @test_pmxvbf16ger2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_6:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_7:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_8:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_9:.*]] = load <16 x i8>, ptr %[[VAL_7]], align 16
+! LLVMIR: %[[VAL_10:.*]] = load <16 x i8>, ptr %[[VAL_6]], align 16
+! LLVMIR: %[[VAL_11:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2(<16 x i8> %[[VAL_9]], <16 x i8> %[[VAL_10]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_11]], ptr %[[VAL_8]], align 64
subroutine test_pmxvbf16ger2nn_def()
@@ -46,14 +46,14 @@
end subroutine test_pmxvbf16ger2nn_def
!CHECK-LABEL: @test_pmxvbf16ger2nn_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_12:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_13:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_14:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_15:.*]] = load <16 x i8>, ptr %[[VAL_13]], align 16
+! LLVMIR: %[[VAL_16:.*]] = load <16 x i8>, ptr %[[VAL_12]], align 16
+! LLVMIR: %[[VAL_17:.*]] = load <512 x i1>, ptr %[[VAL_14]], align 64
+! LLVMIR: %[[VAL_18:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2nn(<512 x i1> %[[VAL_17]], <16 x i8> %[[VAL_15]], <16 x i8> %[[VAL_16]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_18]], ptr %[[VAL_14]], align 64
subroutine test_pmxvbf16ger2nn_non_def()
use, intrinsic :: mma
@@ -64,14 +64,14 @@
end subroutine test_pmxvbf16ger2nn_non_def
!CHECK-LABEL: @test_pmxvbf16ger2nn_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_19:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_20:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_21:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_22:.*]] = load <16 x i8>, ptr %[[VAL_20]], align 16
+! LLVMIR: %[[VAL_23:.*]] = load <16 x i8>, ptr %[[VAL_19]], align 16
+! LLVMIR: %[[VAL_24:.*]] = load <512 x i1>, ptr %[[VAL_21]], align 64
+! LLVMIR: %[[VAL_25:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2nn(<512 x i1> %[[VAL_24]], <16 x i8> %[[VAL_22]], <16 x i8> %[[VAL_23]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_25]], ptr %[[VAL_21]], align 64
subroutine test_pmxvbf16ger2np_def()
use, intrinsic :: mma
@@ -82,14 +82,14 @@
end subroutine test_pmxvbf16ger2np_def
!CHECK-LABEL: @test_pmxvbf16ger2np_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_26:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_27:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_28:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_29:.*]] = load <16 x i8>, ptr %[[VAL_27]], align 16
+! LLVMIR: %[[VAL_30:.*]] = load <16 x i8>, ptr %[[VAL_26]], align 16
+! LLVMIR: %[[VAL_31:.*]] = load <512 x i1>, ptr %[[VAL_28]], align 64
+! LLVMIR: %[[VAL_32:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2np(<512 x i1> %[[VAL_31]], <16 x i8> %[[VAL_29]], <16 x i8> %[[VAL_30]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_32]], ptr %[[VAL_28]], align 64
subroutine test_pmxvbf16ger2np_non_def()
use, intrinsic :: mma
@@ -100,14 +100,14 @@
end subroutine test_pmxvbf16ger2np_non_def
!CHECK-LABEL: @test_pmxvbf16ger2np_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_33:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_34:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_35:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_36:.*]] = load <16 x i8>, ptr %[[VAL_34]], align 16
+! LLVMIR: %[[VAL_37:.*]] = load <16 x i8>, ptr %[[VAL_33]], align 16
+! LLVMIR: %[[VAL_38:.*]] = load <512 x i1>, ptr %[[VAL_35]], align 64
+! LLVMIR: %[[VAL_39:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2np(<512 x i1> %[[VAL_38]], <16 x i8> %[[VAL_36]], <16 x i8> %[[VAL_37]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_39]], ptr %[[VAL_35]], align 64
subroutine test_pmxvbf16ger2pn_def()
use, intrinsic :: mma
@@ -118,14 +118,14 @@
end subroutine test_pmxvbf16ger2pn_def
!CHECK-LABEL: @test_pmxvbf16ger2pn_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_40:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_41:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_42:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_43:.*]] = load <16 x i8>, ptr %[[VAL_41]], align 16
+! LLVMIR: %[[VAL_44:.*]] = load <16 x i8>, ptr %[[VAL_40]], align 16
+! LLVMIR: %[[VAL_45:.*]] = load <512 x i1>, ptr %[[VAL_42]], align 64
+! LLVMIR: %[[VAL_46:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pn(<512 x i1> %[[VAL_45]], <16 x i8> %[[VAL_43]], <16 x i8> %[[VAL_44]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_46]], ptr %[[VAL_42]], align 64
subroutine test_pmxvbf16ger2pn_non_def()
use, intrinsic :: mma
@@ -136,14 +136,14 @@
end subroutine test_pmxvbf16ger2pn_non_def
!CHECK-LABEL: @test_pmxvbf16ger2pn_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_47:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_48:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_49:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_50:.*]] = load <16 x i8>, ptr %[[VAL_48]], align 16
+! LLVMIR: %[[VAL_51:.*]] = load <16 x i8>, ptr %[[VAL_47]], align 16
+! LLVMIR: %[[VAL_52:.*]] = load <512 x i1>, ptr %[[VAL_49]], align 64
+! LLVMIR: %[[VAL_53:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pn(<512 x i1> %[[VAL_52]], <16 x i8> %[[VAL_50]], <16 x i8> %[[VAL_51]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_53]], ptr %[[VAL_49]], align 64
subroutine test_pmxvbf16ger2pp_def()
use, intrinsic :: mma
@@ -154,14 +154,14 @@
end subroutine test_pmxvbf16ger2pp_def
!CHECK-LABEL: @test_pmxvbf16ger2pp_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_54:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_55:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_56:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_57:.*]] = load <16 x i8>, ptr %[[VAL_55]], align 16
+! LLVMIR: %[[VAL_58:.*]] = load <16 x i8>, ptr %[[VAL_54]], align 16
+! LLVMIR: %[[VAL_59:.*]] = load <512 x i1>, ptr %[[VAL_56]], align 64
+! LLVMIR: %[[VAL_60:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pp(<512 x i1> %[[VAL_59]], <16 x i8> %[[VAL_57]], <16 x i8> %[[VAL_58]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_60]], ptr %[[VAL_56]], align 64
subroutine test_pmxvbf16ger2pp_non_def()
use, intrinsic :: mma
@@ -172,14 +172,14 @@
end subroutine test_pmxvbf16ger2pp_non_def
!CHECK-LABEL: @test_pmxvbf16ger2pp_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_61:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_62:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_63:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_64:.*]] = load <16 x i8>, ptr %[[VAL_62]], align 16
+! LLVMIR: %[[VAL_65:.*]] = load <16 x i8>, ptr %[[VAL_61]], align 16
+! LLVMIR: %[[VAL_66:.*]] = load <512 x i1>, ptr %[[VAL_63]], align 64
+! LLVMIR: %[[VAL_67:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvbf16ger2pp(<512 x i1> %[[VAL_66]], <16 x i8> %[[VAL_64]], <16 x i8> %[[VAL_65]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_67]], ptr %[[VAL_63]], align 64
subroutine test_pmxvf16ger2_def()
use, intrinsic :: mma
@@ -190,13 +190,13 @@
end subroutine test_pmxvf16ger2_def
!CHECK-LABEL: @test_pmxvf16ger2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_68:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_69:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_70:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_71:.*]] = load <16 x i8>, ptr %[[VAL_69]], align 16
+! LLVMIR: %[[VAL_72:.*]] = load <16 x i8>, ptr %[[VAL_68]], align 16
+! LLVMIR: %[[VAL_73:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2(<16 x i8> %[[VAL_71]], <16 x i8> %[[VAL_72]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_73]], ptr %[[VAL_70]], align 64
subroutine test_pmxvf16ger2_non_def()
use, intrinsic :: mma
@@ -207,13 +207,13 @@
end subroutine test_pmxvf16ger2_non_def
!CHECK-LABEL: @test_pmxvf16ger2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_74:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_75:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_76:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_77:.*]] = load <16 x i8>, ptr %[[VAL_75]], align 16
+! LLVMIR: %[[VAL_78:.*]] = load <16 x i8>, ptr %[[VAL_74]], align 16
+! LLVMIR: %[[VAL_79:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2(<16 x i8> %[[VAL_77]], <16 x i8> %[[VAL_78]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_79]], ptr %[[VAL_76]], align 64
subroutine test_pmxvf16ger2nn_def()
use, intrinsic :: mma
@@ -224,14 +224,14 @@
end subroutine test_pmxvf16ger2nn_def
!CHECK-LABEL: @test_pmxvf16ger2nn_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_80:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_81:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_82:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_83:.*]] = load <16 x i8>, ptr %[[VAL_81]], align 16
+! LLVMIR: %[[VAL_84:.*]] = load <16 x i8>, ptr %[[VAL_80]], align 16
+! LLVMIR: %[[VAL_85:.*]] = load <512 x i1>, ptr %[[VAL_82]], align 64
+! LLVMIR: %[[VAL_86:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2nn(<512 x i1> %[[VAL_85]], <16 x i8> %[[VAL_83]], <16 x i8> %[[VAL_84]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_86]], ptr %[[VAL_82]], align 64
subroutine test_pmxvf16ger2nn_non_def()
use, intrinsic :: mma
@@ -242,14 +242,14 @@
end subroutine test_pmxvf16ger2nn_non_def
!CHECK-LABEL: @test_pmxvf16ger2nn_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_87:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_88:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_89:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_90:.*]] = load <16 x i8>, ptr %[[VAL_88]], align 16
+! LLVMIR: %[[VAL_91:.*]] = load <16 x i8>, ptr %[[VAL_87]], align 16
+! LLVMIR: %[[VAL_92:.*]] = load <512 x i1>, ptr %[[VAL_89]], align 64
+! LLVMIR: %[[VAL_93:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2nn(<512 x i1> %[[VAL_92]], <16 x i8> %[[VAL_90]], <16 x i8> %[[VAL_91]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_93]], ptr %[[VAL_89]], align 64
subroutine test_pmxvf16ger2np_def()
use, intrinsic :: mma
@@ -260,14 +260,14 @@
end subroutine test_pmxvf16ger2np_def
!CHECK-LABEL: @test_pmxvf16ger2np_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_94:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_95:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_96:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_97:.*]] = load <16 x i8>, ptr %[[VAL_95]], align 16
+! LLVMIR: %[[VAL_98:.*]] = load <16 x i8>, ptr %[[VAL_94]], align 16
+! LLVMIR: %[[VAL_99:.*]] = load <512 x i1>, ptr %[[VAL_96]], align 64
+! LLVMIR: %[[VAL_100:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2np(<512 x i1> %[[VAL_99]], <16 x i8> %[[VAL_97]], <16 x i8> %[[VAL_98]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_100]], ptr %[[VAL_96]], align 64
subroutine test_pmxvf16ger2np_non_def()
use, intrinsic :: mma
@@ -278,14 +278,14 @@
end subroutine test_pmxvf16ger2np_non_def
!CHECK-LABEL: @test_pmxvf16ger2np_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_101:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_102:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_103:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_104:.*]] = load <16 x i8>, ptr %[[VAL_102]], align 16
+! LLVMIR: %[[VAL_105:.*]] = load <16 x i8>, ptr %[[VAL_101]], align 16
+! LLVMIR: %[[VAL_106:.*]] = load <512 x i1>, ptr %[[VAL_103]], align 64
+! LLVMIR: %[[VAL_107:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2np(<512 x i1> %[[VAL_106]], <16 x i8> %[[VAL_104]], <16 x i8> %[[VAL_105]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_107]], ptr %[[VAL_103]], align 64
subroutine test_pmxvf16ger2pn_def()
use, intrinsic :: mma
@@ -296,14 +296,14 @@
end subroutine test_pmxvf16ger2pn_def
!CHECK-LABEL: @test_pmxvf16ger2pn_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_108:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_109:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_110:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_111:.*]] = load <16 x i8>, ptr %[[VAL_109]], align 16
+! LLVMIR: %[[VAL_112:.*]] = load <16 x i8>, ptr %[[VAL_108]], align 16
+! LLVMIR: %[[VAL_113:.*]] = load <512 x i1>, ptr %[[VAL_110]], align 64
+! LLVMIR: %[[VAL_114:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pn(<512 x i1> %[[VAL_113]], <16 x i8> %[[VAL_111]], <16 x i8> %[[VAL_112]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_114]], ptr %[[VAL_110]], align 64
subroutine test_pmxvf16ger2pn_non_def()
use, intrinsic :: mma
@@ -314,14 +314,14 @@
end subroutine test_pmxvf16ger2pn_non_def
!CHECK-LABEL: @test_pmxvf16ger2pn_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_115:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_116:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_117:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_118:.*]] = load <16 x i8>, ptr %[[VAL_116]], align 16
+! LLVMIR: %[[VAL_119:.*]] = load <16 x i8>, ptr %[[VAL_115]], align 16
+! LLVMIR: %[[VAL_120:.*]] = load <512 x i1>, ptr %[[VAL_117]], align 64
+! LLVMIR: %[[VAL_121:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pn(<512 x i1> %[[VAL_120]], <16 x i8> %[[VAL_118]], <16 x i8> %[[VAL_119]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_121]], ptr %[[VAL_117]], align 64
subroutine test_pmxvf16ger2pp_def()
use, intrinsic :: mma
@@ -332,14 +332,14 @@
end subroutine test_pmxvf16ger2pp_def
!CHECK-LABEL: @test_pmxvf16ger2pp_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_122:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_123:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_124:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_125:.*]] = load <16 x i8>, ptr %[[VAL_123]], align 16
+! LLVMIR: %[[VAL_126:.*]] = load <16 x i8>, ptr %[[VAL_122]], align 16
+! LLVMIR: %[[VAL_127:.*]] = load <512 x i1>, ptr %[[VAL_124]], align 64
+! LLVMIR: %[[VAL_128:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pp(<512 x i1> %[[VAL_127]], <16 x i8> %[[VAL_125]], <16 x i8> %[[VAL_126]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_128]], ptr %[[VAL_124]], align 64
subroutine test_pmxvf16ger2pp_non_def()
use, intrinsic :: mma
@@ -350,14 +350,14 @@
end subroutine test_pmxvf16ger2pp_non_def
!CHECK-LABEL: @test_pmxvf16ger2pp_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_129:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_130:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_131:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_132:.*]] = load <16 x i8>, ptr %[[VAL_130]], align 16
+! LLVMIR: %[[VAL_133:.*]] = load <16 x i8>, ptr %[[VAL_129]], align 16
+! LLVMIR: %[[VAL_134:.*]] = load <512 x i1>, ptr %[[VAL_131]], align 64
+! LLVMIR: %[[VAL_135:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf16ger2pp(<512 x i1> %[[VAL_134]], <16 x i8> %[[VAL_132]], <16 x i8> %[[VAL_133]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_135]], ptr %[[VAL_131]], align 64
subroutine test_pmxvf32ger_u1_def()
use, intrinsic :: mma
@@ -368,13 +368,13 @@
end subroutine test_pmxvf32ger_u1_def
!CHECK-LABEL: @test_pmxvf32ger_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_136:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_137:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_138:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_139:.*]] = load <16 x i8>, ptr %[[VAL_137]], align 16
+! LLVMIR: %[[VAL_140:.*]] = load <16 x i8>, ptr %[[VAL_136]], align 16
+! LLVMIR: %[[VAL_141:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %[[VAL_139]], <16 x i8> %[[VAL_140]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_141]], ptr %[[VAL_138]], align 64
subroutine test_pmxvf32ger_u1_non_def()
use, intrinsic :: mma
@@ -385,13 +385,13 @@
end subroutine test_pmxvf32ger_u1_non_def
!CHECK-LABEL: @test_pmxvf32ger_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_142:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_143:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_144:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_145:.*]] = load <16 x i8>, ptr %[[VAL_143]], align 16
+! LLVMIR: %[[VAL_146:.*]] = load <16 x i8>, ptr %[[VAL_142]], align 16
+! LLVMIR: %[[VAL_147:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %[[VAL_145]], <16 x i8> %[[VAL_146]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_147]], ptr %[[VAL_144]], align 64
subroutine test_pmxvf32ger_r4_def()
use, intrinsic :: mma
@@ -402,15 +402,15 @@
end subroutine test_pmxvf32ger_r4_def
!CHECK-LABEL: @test_pmxvf32ger_r4_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %6, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_148:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_149:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_150:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_151:.*]] = load <4 x float>, ptr %[[VAL_149]], align 16
+! LLVMIR: %[[VAL_152:.*]] = load <4 x float>, ptr %[[VAL_148]], align 16
+! LLVMIR: %[[VAL_153:.*]] = bitcast <4 x float> %[[VAL_151]] to <16 x i8>
+! LLVMIR: %[[VAL_154:.*]] = bitcast <4 x float> %[[VAL_152]] to <16 x i8>
+! LLVMIR: %[[VAL_155:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %[[VAL_153]], <16 x i8> %[[VAL_154]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_155]], ptr %[[VAL_150]], align 64
subroutine test_pmxvf32ger_r4_non_def()
use, intrinsic :: mma
@@ -421,15 +421,15 @@
end subroutine test_pmxvf32ger_r4_non_def
!CHECK-LABEL: @test_pmxvf32ger_r4_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %6, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_156:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_157:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_158:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_159:.*]] = load <4 x float>, ptr %[[VAL_157]], align 16
+! LLVMIR: %[[VAL_160:.*]] = load <4 x float>, ptr %[[VAL_156]], align 16
+! LLVMIR: %[[VAL_161:.*]] = bitcast <4 x float> %[[VAL_159]] to <16 x i8>
+! LLVMIR: %[[VAL_162:.*]] = bitcast <4 x float> %[[VAL_160]] to <16 x i8>
+! LLVMIR: %[[VAL_163:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32ger(<16 x i8> %[[VAL_161]], <16 x i8> %[[VAL_162]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_163]], ptr %[[VAL_158]], align 64
subroutine test_pmxvf32gernn_u1_def()
use, intrinsic :: mma
@@ -440,14 +440,14 @@
end subroutine test_pmxvf32gernn_u1_def
!CHECK-LABEL: @test_pmxvf32gernn_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_164:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_165:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_166:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_167:.*]] = load <16 x i8>, ptr %[[VAL_165]], align 16
+! LLVMIR: %[[VAL_168:.*]] = load <16 x i8>, ptr %[[VAL_164]], align 16
+! LLVMIR: %[[VAL_169:.*]] = load <512 x i1>, ptr %[[VAL_166]], align 64
+! LLVMIR: %[[VAL_170:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %[[VAL_169]], <16 x i8> %[[VAL_167]], <16 x i8> %[[VAL_168]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_170]], ptr %[[VAL_166]], align 64
subroutine test_pmxvf32gernn_u1_non_def()
use, intrinsic :: mma
@@ -458,14 +458,14 @@
end subroutine test_pmxvf32gernn_u1_non_def
!CHECK-LABEL: @test_pmxvf32gernn_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_171:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_172:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_173:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_174:.*]] = load <16 x i8>, ptr %[[VAL_172]], align 16
+! LLVMIR: %[[VAL_175:.*]] = load <16 x i8>, ptr %[[VAL_171]], align 16
+! LLVMIR: %[[VAL_176:.*]] = load <512 x i1>, ptr %[[VAL_173]], align 64
+! LLVMIR: %[[VAL_177:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %[[VAL_176]], <16 x i8> %[[VAL_174]], <16 x i8> %[[VAL_175]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_177]], ptr %[[VAL_173]], align 64
subroutine test_pmxvf32gernn_r4_def()
use, intrinsic :: mma
@@ -476,16 +476,16 @@
end subroutine test_pmxvf32gernn_r4_def
!CHECK-LABEL: @test_pmxvf32gernn_r4_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_178:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_179:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_180:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_181:.*]] = load <4 x float>, ptr %[[VAL_179]], align 16
+! LLVMIR: %[[VAL_182:.*]] = load <4 x float>, ptr %[[VAL_178]], align 16
+! LLVMIR: %[[VAL_183:.*]] = load <512 x i1>, ptr %[[VAL_180]], align 64
+! LLVMIR: %[[VAL_184:.*]] = bitcast <4 x float> %[[VAL_181]] to <16 x i8>
+! LLVMIR: %[[VAL_185:.*]] = bitcast <4 x float> %[[VAL_182]] to <16 x i8>
+! LLVMIR: %[[VAL_186:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %[[VAL_183]], <16 x i8> %[[VAL_184]], <16 x i8> %[[VAL_185]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_186]], ptr %[[VAL_180]], align 64
subroutine test_pmxvf32gernn_r4_non_def()
use, intrinsic :: mma
@@ -496,16 +496,16 @@
end subroutine test_pmxvf32gernn_r4_non_def
!CHECK-LABEL: @test_pmxvf32gernn_r4_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_187:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_188:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_189:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_190:.*]] = load <4 x float>, ptr %[[VAL_188]], align 16
+! LLVMIR: %[[VAL_191:.*]] = load <4 x float>, ptr %[[VAL_187]], align 16
+! LLVMIR: %[[VAL_192:.*]] = load <512 x i1>, ptr %[[VAL_189]], align 64
+! LLVMIR: %[[VAL_193:.*]] = bitcast <4 x float> %[[VAL_190]] to <16 x i8>
+! LLVMIR: %[[VAL_194:.*]] = bitcast <4 x float> %[[VAL_191]] to <16 x i8>
+! LLVMIR: %[[VAL_195:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernn(<512 x i1> %[[VAL_192]], <16 x i8> %[[VAL_193]], <16 x i8> %[[VAL_194]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_195]], ptr %[[VAL_189]], align 64
subroutine test_pmxvf32gernp_u1_def()
use, intrinsic :: mma
@@ -516,14 +516,14 @@
end subroutine test_pmxvf32gernp_u1_def
!CHECK-LABEL: @test_pmxvf32gernp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_196:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_197:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_198:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_199:.*]] = load <16 x i8>, ptr %[[VAL_197]], align 16
+! LLVMIR: %[[VAL_200:.*]] = load <16 x i8>, ptr %[[VAL_196]], align 16
+! LLVMIR: %[[VAL_201:.*]] = load <512 x i1>, ptr %[[VAL_198]], align 64
+! LLVMIR: %[[VAL_202:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %[[VAL_201]], <16 x i8> %[[VAL_199]], <16 x i8> %[[VAL_200]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_202]], ptr %[[VAL_198]], align 64
subroutine test_pmxvf32gernp_u1_non_def()
use, intrinsic :: mma
@@ -534,14 +534,14 @@
end subroutine test_pmxvf32gernp_u1_non_def
!CHECK-LABEL: @test_pmxvf32gernp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_203:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_204:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_205:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_206:.*]] = load <16 x i8>, ptr %[[VAL_204]], align 16
+! LLVMIR: %[[VAL_207:.*]] = load <16 x i8>, ptr %[[VAL_203]], align 16
+! LLVMIR: %[[VAL_208:.*]] = load <512 x i1>, ptr %[[VAL_205]], align 64
+! LLVMIR: %[[VAL_209:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %[[VAL_208]], <16 x i8> %[[VAL_206]], <16 x i8> %[[VAL_207]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_209]], ptr %[[VAL_205]], align 64
subroutine test_pmxvf32gernp_r4_def()
use, intrinsic :: mma
@@ -552,16 +552,16 @@
end subroutine test_pmxvf32gernp_r4_def
!CHECK-LABEL: @test_pmxvf32gernp_r4_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_210:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_211:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_212:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_213:.*]] = load <4 x float>, ptr %[[VAL_211]], align 16
+! LLVMIR: %[[VAL_214:.*]] = load <4 x float>, ptr %[[VAL_210]], align 16
+! LLVMIR: %[[VAL_215:.*]] = load <512 x i1>, ptr %[[VAL_212]], align 64
+! LLVMIR: %[[VAL_216:.*]] = bitcast <4 x float> %[[VAL_213]] to <16 x i8>
+! LLVMIR: %[[VAL_217:.*]] = bitcast <4 x float> %[[VAL_214]] to <16 x i8>
+! LLVMIR: %[[VAL_218:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %[[VAL_215]], <16 x i8> %[[VAL_216]], <16 x i8> %[[VAL_217]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_218]], ptr %[[VAL_212]], align 64
subroutine test_pmxvf32gernp_r4_non_def()
use, intrinsic :: mma
@@ -572,16 +572,16 @@
end subroutine test_pmxvf32gernp_r4_non_def
!CHECK-LABEL: @test_pmxvf32gernp_r4_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_219:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_220:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_221:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_222:.*]] = load <4 x float>, ptr %[[VAL_220]], align 16
+! LLVMIR: %[[VAL_223:.*]] = load <4 x float>, ptr %[[VAL_219]], align 16
+! LLVMIR: %[[VAL_224:.*]] = load <512 x i1>, ptr %[[VAL_221]], align 64
+! LLVMIR: %[[VAL_225:.*]] = bitcast <4 x float> %[[VAL_222]] to <16 x i8>
+! LLVMIR: %[[VAL_226:.*]] = bitcast <4 x float> %[[VAL_223]] to <16 x i8>
+! LLVMIR: %[[VAL_227:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gernp(<512 x i1> %[[VAL_224]], <16 x i8> %[[VAL_225]], <16 x i8> %[[VAL_226]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_227]], ptr %[[VAL_221]], align 64
subroutine test_pmxvf32gerpn_u1_def()
use, intrinsic :: mma
@@ -592,14 +592,14 @@
end subroutine test_pmxvf32gerpn_u1_def
!CHECK-LABEL: @test_pmxvf32gerpn_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_228:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_229:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_230:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_231:.*]] = load <16 x i8>, ptr %[[VAL_229]], align 16
+! LLVMIR: %[[VAL_232:.*]] = load <16 x i8>, ptr %[[VAL_228]], align 16
+! LLVMIR: %[[VAL_233:.*]] = load <512 x i1>, ptr %[[VAL_230]], align 64
+! LLVMIR: %[[VAL_234:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %[[VAL_233]], <16 x i8> %[[VAL_231]], <16 x i8> %[[VAL_232]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_234]], ptr %[[VAL_230]], align 64
subroutine test_pmxvf32gerpn_u1_non_def()
use, intrinsic :: mma
@@ -610,14 +610,14 @@
end subroutine test_pmxvf32gerpn_u1_non_def
!CHECK-LABEL: @test_pmxvf32gerpn_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_235:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_236:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_237:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_238:.*]] = load <16 x i8>, ptr %[[VAL_236]], align 16
+! LLVMIR: %[[VAL_239:.*]] = load <16 x i8>, ptr %[[VAL_235]], align 16
+! LLVMIR: %[[VAL_240:.*]] = load <512 x i1>, ptr %[[VAL_237]], align 64
+! LLVMIR: %[[VAL_241:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %[[VAL_240]], <16 x i8> %[[VAL_238]], <16 x i8> %[[VAL_239]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_241]], ptr %[[VAL_237]], align 64
subroutine test_pmxvf32gerpn_r4_def()
use, intrinsic :: mma
@@ -628,16 +628,16 @@
end subroutine test_pmxvf32gerpn_r4_def
!CHECK-LABEL: @test_pmxvf32gerpn_r4_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_242:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_243:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_244:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_245:.*]] = load <4 x float>, ptr %[[VAL_243]], align 16
+! LLVMIR: %[[VAL_246:.*]] = load <4 x float>, ptr %[[VAL_242]], align 16
+! LLVMIR: %[[VAL_247:.*]] = load <512 x i1>, ptr %[[VAL_244]], align 64
+! LLVMIR: %[[VAL_248:.*]] = bitcast <4 x float> %[[VAL_245]] to <16 x i8>
+! LLVMIR: %[[VAL_249:.*]] = bitcast <4 x float> %[[VAL_246]] to <16 x i8>
+! LLVMIR: %[[VAL_250:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %[[VAL_247]], <16 x i8> %[[VAL_248]], <16 x i8> %[[VAL_249]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_250]], ptr %[[VAL_244]], align 64
subroutine test_pmxvf32gerpn_r4_non_def()
use, intrinsic :: mma
@@ -648,16 +648,16 @@
end subroutine test_pmxvf32gerpn_r4_non_def
!CHECK-LABEL: @test_pmxvf32gerpn_r4_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_251:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_252:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_253:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_254:.*]] = load <4 x float>, ptr %[[VAL_252]], align 16
+! LLVMIR: %[[VAL_255:.*]] = load <4 x float>, ptr %[[VAL_251]], align 16
+! LLVMIR: %[[VAL_256:.*]] = load <512 x i1>, ptr %[[VAL_253]], align 64
+! LLVMIR: %[[VAL_257:.*]] = bitcast <4 x float> %[[VAL_254]] to <16 x i8>
+! LLVMIR: %[[VAL_258:.*]] = bitcast <4 x float> %[[VAL_255]] to <16 x i8>
+! LLVMIR: %[[VAL_259:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpn(<512 x i1> %[[VAL_256]], <16 x i8> %[[VAL_257]], <16 x i8> %[[VAL_258]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_259]], ptr %[[VAL_253]], align 64
subroutine test_pmxvf32gerpp_u1_def()
use, intrinsic :: mma
@@ -668,14 +668,14 @@
end subroutine test_pmxvf32gerpp_u1_def
!CHECK-LABEL: @test_pmxvf32gerpp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_260:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_261:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_262:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_263:.*]] = load <16 x i8>, ptr %[[VAL_261]], align 16
+! LLVMIR: %[[VAL_264:.*]] = load <16 x i8>, ptr %[[VAL_260]], align 16
+! LLVMIR: %[[VAL_265:.*]] = load <512 x i1>, ptr %[[VAL_262]], align 64
+! LLVMIR: %[[VAL_266:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %[[VAL_265]], <16 x i8> %[[VAL_263]], <16 x i8> %[[VAL_264]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_266]], ptr %[[VAL_262]], align 64
subroutine test_pmxvf32gerpp_u1_non_def()
use, intrinsic :: mma
@@ -686,14 +686,14 @@
end subroutine test_pmxvf32gerpp_u1_non_def
!CHECK-LABEL: @test_pmxvf32gerpp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_267:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_268:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_269:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_270:.*]] = load <16 x i8>, ptr %[[VAL_268]], align 16
+! LLVMIR: %[[VAL_271:.*]] = load <16 x i8>, ptr %[[VAL_267]], align 16
+! LLVMIR: %[[VAL_272:.*]] = load <512 x i1>, ptr %[[VAL_269]], align 64
+! LLVMIR: %[[VAL_273:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %[[VAL_272]], <16 x i8> %[[VAL_270]], <16 x i8> %[[VAL_271]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_273]], ptr %[[VAL_269]], align 64
subroutine test_pmxvf32gerpp_r4_def()
use, intrinsic :: mma
@@ -704,16 +704,16 @@
end subroutine test_pmxvf32gerpp_r4_def
!CHECK-LABEL: @test_pmxvf32gerpp_r4_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_274:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_275:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_276:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_277:.*]] = load <4 x float>, ptr %[[VAL_275]], align 16
+! LLVMIR: %[[VAL_278:.*]] = load <4 x float>, ptr %[[VAL_274]], align 16
+! LLVMIR: %[[VAL_279:.*]] = load <512 x i1>, ptr %[[VAL_276]], align 64
+! LLVMIR: %[[VAL_280:.*]] = bitcast <4 x float> %[[VAL_277]] to <16 x i8>
+! LLVMIR: %[[VAL_281:.*]] = bitcast <4 x float> %[[VAL_278]] to <16 x i8>
+! LLVMIR: %[[VAL_282:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %[[VAL_279]], <16 x i8> %[[VAL_280]], <16 x i8> %[[VAL_281]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_282]], ptr %[[VAL_276]], align 64
subroutine test_pmxvf32gerpp_r4_non_def()
use, intrinsic :: mma
@@ -724,16 +724,16 @@
end subroutine test_pmxvf32gerpp_r4_non_def
!CHECK-LABEL: @test_pmxvf32gerpp_r4_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_283:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_284:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_285:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_286:.*]] = load <4 x float>, ptr %[[VAL_284]], align 16
+! LLVMIR: %[[VAL_287:.*]] = load <4 x float>, ptr %[[VAL_283]], align 16
+! LLVMIR: %[[VAL_288:.*]] = load <512 x i1>, ptr %[[VAL_285]], align 64
+! LLVMIR: %[[VAL_289:.*]] = bitcast <4 x float> %[[VAL_286]] to <16 x i8>
+! LLVMIR: %[[VAL_290:.*]] = bitcast <4 x float> %[[VAL_287]] to <16 x i8>
+! LLVMIR: %[[VAL_291:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf32gerpp(<512 x i1> %[[VAL_288]], <16 x i8> %[[VAL_289]], <16 x i8> %[[VAL_290]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_291]], ptr %[[VAL_285]], align 64
subroutine test_pmxvf64ger_u1_def()
use, intrinsic :: mma
@@ -745,13 +745,13 @@
end subroutine test_pmxvf64ger_u1_def
!CHECK-LABEL: @test_pmxvf64ger_u1_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %2, align 64
+! LLVMIR: %[[VAL_292:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_293:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_294:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_295:.*]] = load <256 x i1>, ptr %[[VAL_294]], align 32
+! LLVMIR: %[[VAL_296:.*]] = load <16 x i8>, ptr %[[VAL_292]], align 16
+! LLVMIR: %[[VAL_297:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %[[VAL_295]], <16 x i8> %[[VAL_296]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_297]], ptr %[[VAL_293]], align 64
subroutine test_pmxvf64ger_u1_non_def()
use, intrinsic :: mma
@@ -763,13 +763,13 @@
end subroutine test_pmxvf64ger_u1_non_def
!CHECK-LABEL: @test_pmxvf64ger_u1_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %2, align 64
+! LLVMIR: %[[VAL_298:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_299:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_300:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_301:.*]] = load <256 x i1>, ptr %[[VAL_300]], align 32
+! LLVMIR: %[[VAL_302:.*]] = load <16 x i8>, ptr %[[VAL_298]], align 16
+! LLVMIR: %[[VAL_303:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %[[VAL_301]], <16 x i8> %[[VAL_302]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_303]], ptr %[[VAL_299]], align 64
subroutine test_pmxvf64ger_r8_def()
use, intrinsic :: mma
@@ -781,14 +781,14 @@
end subroutine test_pmxvf64ger_r8_def
!CHECK-LABEL: @test_pmxvf64ger_r8_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %4, <16 x i8> %6, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_304:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_305:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_306:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_307:.*]] = load <256 x i1>, ptr %[[VAL_306]], align 32
+! LLVMIR: %[[VAL_308:.*]] = load <2 x double>, ptr %[[VAL_304]], align 16
+! LLVMIR: %[[VAL_309:.*]] = bitcast <2 x double> %[[VAL_308]] to <16 x i8>
+! LLVMIR: %[[VAL_310:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %[[VAL_307]], <16 x i8> %[[VAL_309]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_310]], ptr %[[VAL_305]], align 64
subroutine test_pmxvf64ger_r8_non_def()
use, intrinsic :: mma
@@ -800,14 +800,14 @@
end subroutine test_pmxvf64ger_r8_non_def
!CHECK-LABEL: @test_pmxvf64ger_r8_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %4, <16 x i8> %6, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_311:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_312:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_313:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_314:.*]] = load <256 x i1>, ptr %[[VAL_313]], align 32
+! LLVMIR: %[[VAL_315:.*]] = load <2 x double>, ptr %[[VAL_311]], align 16
+! LLVMIR: %[[VAL_316:.*]] = bitcast <2 x double> %[[VAL_315]] to <16 x i8>
+! LLVMIR: %[[VAL_317:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64ger(<256 x i1> %[[VAL_314]], <16 x i8> %[[VAL_316]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_317]], ptr %[[VAL_312]], align 64
subroutine test_pmxvf64gernn_u1_def()
use, intrinsic :: mma
@@ -819,14 +819,14 @@
end subroutine test_pmxvf64gernn_u1_def
!CHECK-LABEL: @test_pmxvf64gernn_u1_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_318:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_319:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_320:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_321:.*]] = load <256 x i1>, ptr %[[VAL_320]], align 32
+! LLVMIR: %[[VAL_322:.*]] = load <16 x i8>, ptr %[[VAL_318]], align 16
+! LLVMIR: %[[VAL_323:.*]] = load <512 x i1>, ptr %[[VAL_319]], align 64
+! LLVMIR: %[[VAL_324:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %[[VAL_323]], <256 x i1> %[[VAL_321]], <16 x i8> %[[VAL_322]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_324]], ptr %[[VAL_319]], align 64
subroutine test_pmxvf64gernn_u1_non_def()
use, intrinsic :: mma
@@ -838,14 +838,14 @@
end subroutine test_pmxvf64gernn_u1_non_def
!CHECK-LABEL: @test_pmxvf64gernn_u1_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_325:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_326:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_327:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_328:.*]] = load <256 x i1>, ptr %[[VAL_327]], align 32
+! LLVMIR: %[[VAL_329:.*]] = load <16 x i8>, ptr %[[VAL_325]], align 16
+! LLVMIR: %[[VAL_330:.*]] = load <512 x i1>, ptr %[[VAL_326]], align 64
+! LLVMIR: %[[VAL_331:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %[[VAL_330]], <256 x i1> %[[VAL_328]], <16 x i8> %[[VAL_329]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_331]], ptr %[[VAL_326]], align 64
subroutine test_pmxvf64gernn_r8_def()
use, intrinsic :: mma
@@ -857,15 +857,15 @@
end subroutine test_pmxvf64gernn_r8_def
!CHECK-LABEL: @test_pmxvf64gernn_r8_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_332:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_333:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_334:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_335:.*]] = load <256 x i1>, ptr %[[VAL_334]], align 32
+! LLVMIR: %[[VAL_336:.*]] = load <2 x double>, ptr %[[VAL_332]], align 16
+! LLVMIR: %[[VAL_337:.*]] = load <512 x i1>, ptr %[[VAL_333]], align 64
+! LLVMIR: %[[VAL_338:.*]] = bitcast <2 x double> %[[VAL_336]] to <16 x i8>
+! LLVMIR: %[[VAL_339:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %[[VAL_337]], <256 x i1> %[[VAL_335]], <16 x i8> %[[VAL_338]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_339]], ptr %[[VAL_333]], align 64
subroutine test_pmxvf64gernn_r8_non_def()
use, intrinsic :: mma
@@ -877,15 +877,15 @@
end subroutine test_pmxvf64gernn_r8_non_def
!CHECK-LABEL: @test_pmxvf64gernn_r8_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_340:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_341:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_342:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_343:.*]] = load <256 x i1>, ptr %[[VAL_342]], align 32
+! LLVMIR: %[[VAL_344:.*]] = load <2 x double>, ptr %[[VAL_340]], align 16
+! LLVMIR: %[[VAL_345:.*]] = load <512 x i1>, ptr %[[VAL_341]], align 64
+! LLVMIR: %[[VAL_346:.*]] = bitcast <2 x double> %[[VAL_344]] to <16 x i8>
+! LLVMIR: %[[VAL_347:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernn(<512 x i1> %[[VAL_345]], <256 x i1> %[[VAL_343]], <16 x i8> %[[VAL_346]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_347]], ptr %[[VAL_341]], align 64
subroutine test_pmxvf64gernp_u1_def()
use, intrinsic :: mma
@@ -897,14 +897,14 @@
end subroutine test_pmxvf64gernp_u1_def
!CHECK-LABEL: @test_pmxvf64gernp_u1_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_348:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_349:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_350:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_351:.*]] = load <256 x i1>, ptr %[[VAL_350]], align 32
+! LLVMIR: %[[VAL_352:.*]] = load <16 x i8>, ptr %[[VAL_348]], align 16
+! LLVMIR: %[[VAL_353:.*]] = load <512 x i1>, ptr %[[VAL_349]], align 64
+! LLVMIR: %[[VAL_354:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %[[VAL_353]], <256 x i1> %[[VAL_351]], <16 x i8> %[[VAL_352]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_354]], ptr %[[VAL_349]], align 64
subroutine test_pmxvf64gernp_u1_non_def()
use, intrinsic :: mma
@@ -916,14 +916,14 @@
end subroutine test_pmxvf64gernp_u1_non_def
!CHECK-LABEL: @test_pmxvf64gernp_u1_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_355:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_356:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_357:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_358:.*]] = load <256 x i1>, ptr %[[VAL_357]], align 32
+! LLVMIR: %[[VAL_359:.*]] = load <16 x i8>, ptr %[[VAL_355]], align 16
+! LLVMIR: %[[VAL_360:.*]] = load <512 x i1>, ptr %[[VAL_356]], align 64
+! LLVMIR: %[[VAL_361:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %[[VAL_360]], <256 x i1> %[[VAL_358]], <16 x i8> %[[VAL_359]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_361]], ptr %[[VAL_356]], align 64
subroutine test_pmxvf64gernp_r8_def()
use, intrinsic :: mma
@@ -935,15 +935,15 @@
end subroutine test_pmxvf64gernp_r8_def
!CHECK-LABEL: @test_pmxvf64gernp_r8_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_362:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_363:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_364:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_365:.*]] = load <256 x i1>, ptr %[[VAL_364]], align 32
+! LLVMIR: %[[VAL_366:.*]] = load <2 x double>, ptr %[[VAL_362]], align 16
+! LLVMIR: %[[VAL_367:.*]] = load <512 x i1>, ptr %[[VAL_363]], align 64
+! LLVMIR: %[[VAL_368:.*]] = bitcast <2 x double> %[[VAL_366]] to <16 x i8>
+! LLVMIR: %[[VAL_369:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %[[VAL_367]], <256 x i1> %[[VAL_365]], <16 x i8> %[[VAL_368]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_369]], ptr %[[VAL_363]], align 64
subroutine test_pmxvf64gernp_r8_non_def()
use, intrinsic :: mma
@@ -955,15 +955,15 @@
end subroutine test_pmxvf64gernp_r8_non_def
!CHECK-LABEL: @test_pmxvf64gernp_r8_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_370:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_371:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_372:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_373:.*]] = load <256 x i1>, ptr %[[VAL_372]], align 32
+! LLVMIR: %[[VAL_374:.*]] = load <2 x double>, ptr %[[VAL_370]], align 16
+! LLVMIR: %[[VAL_375:.*]] = load <512 x i1>, ptr %[[VAL_371]], align 64
+! LLVMIR: %[[VAL_376:.*]] = bitcast <2 x double> %[[VAL_374]] to <16 x i8>
+! LLVMIR: %[[VAL_377:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gernp(<512 x i1> %[[VAL_375]], <256 x i1> %[[VAL_373]], <16 x i8> %[[VAL_376]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_377]], ptr %[[VAL_371]], align 64
subroutine test_pmxvf64gerpn_u1_def()
use, intrinsic :: mma
@@ -975,14 +975,14 @@
end subroutine test_pmxvf64gerpn_u1_def
!CHECK-LABEL: @test_pmxvf64gerpn_u1_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_378:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_379:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_380:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_381:.*]] = load <256 x i1>, ptr %[[VAL_380]], align 32
+! LLVMIR: %[[VAL_382:.*]] = load <16 x i8>, ptr %[[VAL_378]], align 16
+! LLVMIR: %[[VAL_383:.*]] = load <512 x i1>, ptr %[[VAL_379]], align 64
+! LLVMIR: %[[VAL_384:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %[[VAL_383]], <256 x i1> %[[VAL_381]], <16 x i8> %[[VAL_382]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_384]], ptr %[[VAL_379]], align 64
subroutine test_pmxvf64gerpn_u1_non_def()
use, intrinsic :: mma
@@ -994,14 +994,14 @@
end subroutine test_pmxvf64gerpn_u1_non_def
!CHECK-LABEL: @test_pmxvf64gerpn_u1_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_385:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_386:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_387:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_388:.*]] = load <256 x i1>, ptr %[[VAL_387]], align 32
+! LLVMIR: %[[VAL_389:.*]] = load <16 x i8>, ptr %[[VAL_385]], align 16
+! LLVMIR: %[[VAL_390:.*]] = load <512 x i1>, ptr %[[VAL_386]], align 64
+! LLVMIR: %[[VAL_391:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %[[VAL_390]], <256 x i1> %[[VAL_388]], <16 x i8> %[[VAL_389]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_391]], ptr %[[VAL_386]], align 64
subroutine test_pmxvf64gerpn_r8_def()
use, intrinsic :: mma
@@ -1013,15 +1013,15 @@
end subroutine test_pmxvf64gerpn_r8_def
!CHECK-LABEL: @test_pmxvf64gerpn_r8_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_392:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_393:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_394:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_395:.*]] = load <256 x i1>, ptr %[[VAL_394]], align 32
+! LLVMIR: %[[VAL_396:.*]] = load <2 x double>, ptr %[[VAL_392]], align 16
+! LLVMIR: %[[VAL_397:.*]] = load <512 x i1>, ptr %[[VAL_393]], align 64
+! LLVMIR: %[[VAL_398:.*]] = bitcast <2 x double> %[[VAL_396]] to <16 x i8>
+! LLVMIR: %[[VAL_399:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %[[VAL_397]], <256 x i1> %[[VAL_395]], <16 x i8> %[[VAL_398]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_399]], ptr %[[VAL_393]], align 64
subroutine test_pmxvf64gerpn_r8_non_def()
use, intrinsic :: mma
@@ -1033,15 +1033,15 @@
end subroutine test_pmxvf64gerpn_r8_non_def
!CHECK-LABEL: @test_pmxvf64gerpn_r8_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_400:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_401:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_402:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_403:.*]] = load <256 x i1>, ptr %[[VAL_402]], align 32
+! LLVMIR: %[[VAL_404:.*]] = load <2 x double>, ptr %[[VAL_400]], align 16
+! LLVMIR: %[[VAL_405:.*]] = load <512 x i1>, ptr %[[VAL_401]], align 64
+! LLVMIR: %[[VAL_406:.*]] = bitcast <2 x double> %[[VAL_404]] to <16 x i8>
+! LLVMIR: %[[VAL_407:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpn(<512 x i1> %[[VAL_405]], <256 x i1> %[[VAL_403]], <16 x i8> %[[VAL_406]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_407]], ptr %[[VAL_401]], align 64
subroutine test_pmxvf64gerpp_u1_def()
use, intrinsic :: mma
@@ -1053,14 +1053,14 @@
end subroutine test_pmxvf64gerpp_u1_def
!CHECK-LABEL: @test_pmxvf64gerpp_u1_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_408:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_409:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_410:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_411:.*]] = load <256 x i1>, ptr %[[VAL_410]], align 32
+! LLVMIR: %[[VAL_412:.*]] = load <16 x i8>, ptr %[[VAL_408]], align 16
+! LLVMIR: %[[VAL_413:.*]] = load <512 x i1>, ptr %[[VAL_409]], align 64
+! LLVMIR: %[[VAL_414:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %[[VAL_413]], <256 x i1> %[[VAL_411]], <16 x i8> %[[VAL_412]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_414]], ptr %[[VAL_409]], align 64
subroutine test_pmxvf64gerpp_u1_non_def()
use, intrinsic :: mma
@@ -1072,14 +1072,14 @@
end subroutine test_pmxvf64gerpp_u1_non_def
!CHECK-LABEL: @test_pmxvf64gerpp_u1_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_415:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_416:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_417:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_418:.*]] = load <256 x i1>, ptr %[[VAL_417]], align 32
+! LLVMIR: %[[VAL_419:.*]] = load <16 x i8>, ptr %[[VAL_415]], align 16
+! LLVMIR: %[[VAL_420:.*]] = load <512 x i1>, ptr %[[VAL_416]], align 64
+! LLVMIR: %[[VAL_421:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %[[VAL_420]], <256 x i1> %[[VAL_418]], <16 x i8> %[[VAL_419]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_421]], ptr %[[VAL_416]], align 64
subroutine test_pmxvf64gerpp_r8_def()
use, intrinsic :: mma
@@ -1091,15 +1091,15 @@
end subroutine test_pmxvf64gerpp_r8_def
!CHECK-LABEL: @test_pmxvf64gerpp_r8_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_422:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_423:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_424:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_425:.*]] = load <256 x i1>, ptr %[[VAL_424]], align 32
+! LLVMIR: %[[VAL_426:.*]] = load <2 x double>, ptr %[[VAL_422]], align 16
+! LLVMIR: %[[VAL_427:.*]] = load <512 x i1>, ptr %[[VAL_423]], align 64
+! LLVMIR: %[[VAL_428:.*]] = bitcast <2 x double> %[[VAL_426]] to <16 x i8>
+! LLVMIR: %[[VAL_429:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %[[VAL_427]], <256 x i1> %[[VAL_425]], <16 x i8> %[[VAL_428]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_429]], ptr %[[VAL_423]], align 64
subroutine test_pmxvf64gerpp_r8_non_def()
use, intrinsic :: mma
@@ -1111,15 +1111,15 @@
end subroutine test_pmxvf64gerpp_r8_non_def
!CHECK-LABEL: @test_pmxvf64gerpp_r8_non_def_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_430:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_431:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_432:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_433:.*]] = load <256 x i1>, ptr %[[VAL_432]], align 32
+! LLVMIR: %[[VAL_434:.*]] = load <2 x double>, ptr %[[VAL_430]], align 16
+! LLVMIR: %[[VAL_435:.*]] = load <512 x i1>, ptr %[[VAL_431]], align 64
+! LLVMIR: %[[VAL_436:.*]] = bitcast <2 x double> %[[VAL_434]] to <16 x i8>
+! LLVMIR: %[[VAL_437:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvf64gerpp(<512 x i1> %[[VAL_435]], <256 x i1> %[[VAL_433]], <16 x i8> %[[VAL_436]], i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_437]], ptr %[[VAL_431]], align 64
subroutine test_pmxvi16ger2_u1_def()
use, intrinsic :: mma
@@ -1130,13 +1130,13 @@
end subroutine test_pmxvi16ger2_u1_def
!CHECK-LABEL: @test_pmxvi16ger2_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_438:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_439:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_440:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_441:.*]] = load <16 x i8>, ptr %[[VAL_439]], align 16
+! LLVMIR: %[[VAL_442:.*]] = load <16 x i8>, ptr %[[VAL_438]], align 16
+! LLVMIR: %[[VAL_443:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %[[VAL_441]], <16 x i8> %[[VAL_442]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_443]], ptr %[[VAL_440]], align 64
subroutine test_pmxvi16ger2_u1_non_def()
use, intrinsic :: mma
@@ -1147,13 +1147,13 @@
end subroutine test_pmxvi16ger2_u1_non_def
!CHECK-LABEL: @test_pmxvi16ger2_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_444:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_445:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_446:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_447:.*]] = load <16 x i8>, ptr %[[VAL_445]], align 16
+! LLVMIR: %[[VAL_448:.*]] = load <16 x i8>, ptr %[[VAL_444]], align 16
+! LLVMIR: %[[VAL_449:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %[[VAL_447]], <16 x i8> %[[VAL_448]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_449]], ptr %[[VAL_446]], align 64
subroutine test_pmxvi16ger2_i2_def()
use, intrinsic :: mma
@@ -1164,15 +1164,15 @@
end subroutine test_pmxvi16ger2_i2_def
!CHECK-LABEL: @test_pmxvi16ger2_i2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %6, <16 x i8> %7, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_450:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_451:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_452:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_453:.*]] = load <8 x i16>, ptr %[[VAL_451]], align 16
+! LLVMIR: %[[VAL_454:.*]] = load <8 x i16>, ptr %[[VAL_450]], align 16
+! LLVMIR: %[[VAL_455:.*]] = bitcast <8 x i16> %[[VAL_453]] to <16 x i8>
+! LLVMIR: %[[VAL_456:.*]] = bitcast <8 x i16> %[[VAL_454]] to <16 x i8>
+! LLVMIR: %[[VAL_457:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %[[VAL_455]], <16 x i8> %[[VAL_456]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_457]], ptr %[[VAL_452]], align 64
subroutine test_pmxvi16ger2_i2_non_def()
use, intrinsic :: mma
@@ -1183,15 +1183,15 @@
end subroutine test_pmxvi16ger2_i2_non_def
!CHECK-LABEL: @test_pmxvi16ger2_i2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %6, <16 x i8> %7, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_458:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_459:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_460:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_461:.*]] = load <8 x i16>, ptr %[[VAL_459]], align 16
+! LLVMIR: %[[VAL_462:.*]] = load <8 x i16>, ptr %[[VAL_458]], align 16
+! LLVMIR: %[[VAL_463:.*]] = bitcast <8 x i16> %[[VAL_461]] to <16 x i8>
+! LLVMIR: %[[VAL_464:.*]] = bitcast <8 x i16> %[[VAL_462]] to <16 x i8>
+! LLVMIR: %[[VAL_465:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2(<16 x i8> %[[VAL_463]], <16 x i8> %[[VAL_464]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_465]], ptr %[[VAL_460]], align 64
subroutine test_pmxvi16ger2pp_u1_def()
use, intrinsic :: mma
@@ -1202,14 +1202,14 @@
end subroutine test_pmxvi16ger2pp_u1_def
!CHECK-LABEL: @test_pmxvi16ger2pp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_466:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_467:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_468:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_469:.*]] = load <16 x i8>, ptr %[[VAL_467]], align 16
+! LLVMIR: %[[VAL_470:.*]] = load <16 x i8>, ptr %[[VAL_466]], align 16
+! LLVMIR: %[[VAL_471:.*]] = load <512 x i1>, ptr %[[VAL_468]], align 64
+! LLVMIR: %[[VAL_472:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %[[VAL_471]], <16 x i8> %[[VAL_469]], <16 x i8> %[[VAL_470]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_472]], ptr %[[VAL_468]], align 64
subroutine test_pmxvi16ger2pp_u1_non_def()
use, intrinsic :: mma
@@ -1220,14 +1220,14 @@
end subroutine test_pmxvi16ger2pp_u1_non_def
!CHECK-LABEL: @test_pmxvi16ger2pp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_473:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_474:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_475:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_476:.*]] = load <16 x i8>, ptr %[[VAL_474]], align 16
+! LLVMIR: %[[VAL_477:.*]] = load <16 x i8>, ptr %[[VAL_473]], align 16
+! LLVMIR: %[[VAL_478:.*]] = load <512 x i1>, ptr %[[VAL_475]], align 64
+! LLVMIR: %[[VAL_479:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %[[VAL_478]], <16 x i8> %[[VAL_476]], <16 x i8> %[[VAL_477]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_479]], ptr %[[VAL_475]], align 64
subroutine test_pmxvi16ger2pp_i2_def()
use, intrinsic :: mma
@@ -1238,16 +1238,16 @@
end subroutine test_pmxvi16ger2pp_i2_def
!CHECK-LABEL: @test_pmxvi16ger2pp_i2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_480:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_481:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_482:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_483:.*]] = load <8 x i16>, ptr %[[VAL_481]], align 16
+! LLVMIR: %[[VAL_484:.*]] = load <8 x i16>, ptr %[[VAL_480]], align 16
+! LLVMIR: %[[VAL_485:.*]] = load <512 x i1>, ptr %[[VAL_482]], align 64
+! LLVMIR: %[[VAL_486:.*]] = bitcast <8 x i16> %[[VAL_483]] to <16 x i8>
+! LLVMIR: %[[VAL_487:.*]] = bitcast <8 x i16> %[[VAL_484]] to <16 x i8>
+! LLVMIR: %[[VAL_488:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %[[VAL_485]], <16 x i8> %[[VAL_486]], <16 x i8> %[[VAL_487]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_488]], ptr %[[VAL_482]], align 64
subroutine test_pmxvi16ger2pp_i2_non_def()
use, intrinsic :: mma
@@ -1258,16 +1258,16 @@
end subroutine test_pmxvi16ger2pp_i2_non_def
!CHECK-LABEL: @test_pmxvi16ger2pp_i2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_489:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_490:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_491:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_492:.*]] = load <8 x i16>, ptr %[[VAL_490]], align 16
+! LLVMIR: %[[VAL_493:.*]] = load <8 x i16>, ptr %[[VAL_489]], align 16
+! LLVMIR: %[[VAL_494:.*]] = load <512 x i1>, ptr %[[VAL_491]], align 64
+! LLVMIR: %[[VAL_495:.*]] = bitcast <8 x i16> %[[VAL_492]] to <16 x i8>
+! LLVMIR: %[[VAL_496:.*]] = bitcast <8 x i16> %[[VAL_493]] to <16 x i8>
+! LLVMIR: %[[VAL_497:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2pp(<512 x i1> %[[VAL_494]], <16 x i8> %[[VAL_495]], <16 x i8> %[[VAL_496]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_497]], ptr %[[VAL_491]], align 64
subroutine test_pmxvi16ger2s_u1_def()
use, intrinsic :: mma
@@ -1278,13 +1278,13 @@
end subroutine test_pmxvi16ger2s_u1_def
!CHECK-LABEL: @test_pmxvi16ger2s_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_498:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_499:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_500:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_501:.*]] = load <16 x i8>, ptr %[[VAL_499]], align 16
+! LLVMIR: %[[VAL_502:.*]] = load <16 x i8>, ptr %[[VAL_498]], align 16
+! LLVMIR: %[[VAL_503:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %[[VAL_501]], <16 x i8> %[[VAL_502]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_503]], ptr %[[VAL_500]], align 64
subroutine test_pmxvi16ger2s_u1_non_def()
use, intrinsic :: mma
@@ -1295,13 +1295,13 @@
end subroutine test_pmxvi16ger2s_u1_non_def
!CHECK-LABEL: @test_pmxvi16ger2s_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_504:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_505:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_506:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_507:.*]] = load <16 x i8>, ptr %[[VAL_505]], align 16
+! LLVMIR: %[[VAL_508:.*]] = load <16 x i8>, ptr %[[VAL_504]], align 16
+! LLVMIR: %[[VAL_509:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %[[VAL_507]], <16 x i8> %[[VAL_508]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_509]], ptr %[[VAL_506]], align 64
subroutine test_pmxvi16ger2s_i2_def()
use, intrinsic :: mma
@@ -1312,15 +1312,15 @@
end subroutine test_pmxvi16ger2s_i2_def
!CHECK-LABEL: @test_pmxvi16ger2s_i2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %6, <16 x i8> %7, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_510:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_511:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_512:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_513:.*]] = load <8 x i16>, ptr %[[VAL_511]], align 16
+! LLVMIR: %[[VAL_514:.*]] = load <8 x i16>, ptr %[[VAL_510]], align 16
+! LLVMIR: %[[VAL_515:.*]] = bitcast <8 x i16> %[[VAL_513]] to <16 x i8>
+! LLVMIR: %[[VAL_516:.*]] = bitcast <8 x i16> %[[VAL_514]] to <16 x i8>
+! LLVMIR: %[[VAL_517:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %[[VAL_515]], <16 x i8> %[[VAL_516]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_517]], ptr %[[VAL_512]], align 64
subroutine test_pmxvi16ger2s_i2_non_def()
use, intrinsic :: mma
@@ -1331,15 +1331,15 @@
end subroutine test_pmxvi16ger2s_i2_non_def
!CHECK-LABEL: @test_pmxvi16ger2s_i2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %6, <16 x i8> %7, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_518:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_519:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_520:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_521:.*]] = load <8 x i16>, ptr %[[VAL_519]], align 16
+! LLVMIR: %[[VAL_522:.*]] = load <8 x i16>, ptr %[[VAL_518]], align 16
+! LLVMIR: %[[VAL_523:.*]] = bitcast <8 x i16> %[[VAL_521]] to <16 x i8>
+! LLVMIR: %[[VAL_524:.*]] = bitcast <8 x i16> %[[VAL_522]] to <16 x i8>
+! LLVMIR: %[[VAL_525:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2s(<16 x i8> %[[VAL_523]], <16 x i8> %[[VAL_524]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_525]], ptr %[[VAL_520]], align 64
subroutine test_pmxvi16ger2spp_u1_def()
use, intrinsic :: mma
@@ -1350,14 +1350,14 @@
end subroutine test_pmxvi16ger2spp_u1_def
!CHECK-LABEL: @test_pmxvi16ger2spp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_526:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_527:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_528:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_529:.*]] = load <16 x i8>, ptr %[[VAL_527]], align 16
+! LLVMIR: %[[VAL_530:.*]] = load <16 x i8>, ptr %[[VAL_526]], align 16
+! LLVMIR: %[[VAL_531:.*]] = load <512 x i1>, ptr %[[VAL_528]], align 64
+! LLVMIR: %[[VAL_532:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %[[VAL_531]], <16 x i8> %[[VAL_529]], <16 x i8> %[[VAL_530]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_532]], ptr %[[VAL_528]], align 64
subroutine test_pmxvi16ger2spp_u1_non_def()
use, intrinsic :: mma
@@ -1368,14 +1368,14 @@
end subroutine test_pmxvi16ger2spp_u1_non_def
!CHECK-LABEL: @test_pmxvi16ger2spp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_533:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_534:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_535:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_536:.*]] = load <16 x i8>, ptr %[[VAL_534]], align 16
+! LLVMIR: %[[VAL_537:.*]] = load <16 x i8>, ptr %[[VAL_533]], align 16
+! LLVMIR: %[[VAL_538:.*]] = load <512 x i1>, ptr %[[VAL_535]], align 64
+! LLVMIR: %[[VAL_539:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %[[VAL_538]], <16 x i8> %[[VAL_536]], <16 x i8> %[[VAL_537]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_539]], ptr %[[VAL_535]], align 64
subroutine test_pmxvi16ger2spp_i2_def()
use, intrinsic :: mma
@@ -1386,16 +1386,16 @@
end subroutine test_pmxvi16ger2spp_i2_def
!CHECK-LABEL: @test_pmxvi16ger2spp_i2_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_540:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_541:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_542:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_543:.*]] = load <8 x i16>, ptr %[[VAL_541]], align 16
+! LLVMIR: %[[VAL_544:.*]] = load <8 x i16>, ptr %[[VAL_540]], align 16
+! LLVMIR: %[[VAL_545:.*]] = load <512 x i1>, ptr %[[VAL_542]], align 64
+! LLVMIR: %[[VAL_546:.*]] = bitcast <8 x i16> %[[VAL_543]] to <16 x i8>
+! LLVMIR: %[[VAL_547:.*]] = bitcast <8 x i16> %[[VAL_544]] to <16 x i8>
+! LLVMIR: %[[VAL_548:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %[[VAL_545]], <16 x i8> %[[VAL_546]], <16 x i8> %[[VAL_547]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_548]], ptr %[[VAL_542]], align 64
subroutine test_pmxvi16ger2spp_i2_non_def()
use, intrinsic :: mma
@@ -1406,16 +1406,16 @@
end subroutine test_pmxvi16ger2spp_i2_non_def
!CHECK-LABEL: @test_pmxvi16ger2spp_i2_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_549:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_550:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_551:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_552:.*]] = load <8 x i16>, ptr %[[VAL_550]], align 16
+! LLVMIR: %[[VAL_553:.*]] = load <8 x i16>, ptr %[[VAL_549]], align 16
+! LLVMIR: %[[VAL_554:.*]] = load <512 x i1>, ptr %[[VAL_551]], align 64
+! LLVMIR: %[[VAL_555:.*]] = bitcast <8 x i16> %[[VAL_552]] to <16 x i8>
+! LLVMIR: %[[VAL_556:.*]] = bitcast <8 x i16> %[[VAL_553]] to <16 x i8>
+! LLVMIR: %[[VAL_557:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi16ger2spp(<512 x i1> %[[VAL_554]], <16 x i8> %[[VAL_555]], <16 x i8> %[[VAL_556]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_557]], ptr %[[VAL_551]], align 64
subroutine test_pmxvi4ger8_def()
@@ -1427,13 +1427,13 @@
end subroutine test_pmxvi4ger8_def
!CHECK-LABEL: @test_pmxvi4ger8_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_558:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_559:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_560:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_561:.*]] = load <16 x i8>, ptr %[[VAL_559]], align 16
+! LLVMIR: %[[VAL_562:.*]] = load <16 x i8>, ptr %[[VAL_558]], align 16
+! LLVMIR: %[[VAL_563:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8(<16 x i8> %[[VAL_561]], <16 x i8> %[[VAL_562]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_563]], ptr %[[VAL_560]], align 64
subroutine test_pmxvi4ger8_non_def()
use, intrinsic :: mma
@@ -1444,13 +1444,13 @@
end subroutine test_pmxvi4ger8_non_def
!CHECK-LABEL: @test_pmxvi4ger8_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_564:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_565:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_566:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_567:.*]] = load <16 x i8>, ptr %[[VAL_565]], align 16
+! LLVMIR: %[[VAL_568:.*]] = load <16 x i8>, ptr %[[VAL_564]], align 16
+! LLVMIR: %[[VAL_569:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8(<16 x i8> %[[VAL_567]], <16 x i8> %[[VAL_568]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_569]], ptr %[[VAL_566]], align 64
subroutine test_pmxvi4ger8pp_def()
use, intrinsic :: mma
@@ -1461,14 +1461,14 @@
end subroutine test_pmxvi4ger8pp_def
!CHECK-LABEL: @test_pmxvi4ger8pp_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_570:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_571:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_572:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_573:.*]] = load <16 x i8>, ptr %[[VAL_571]], align 16
+! LLVMIR: %[[VAL_574:.*]] = load <16 x i8>, ptr %[[VAL_570]], align 16
+! LLVMIR: %[[VAL_575:.*]] = load <512 x i1>, ptr %[[VAL_572]], align 64
+! LLVMIR: %[[VAL_576:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8pp(<512 x i1> %[[VAL_575]], <16 x i8> %[[VAL_573]], <16 x i8> %[[VAL_574]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_576]], ptr %[[VAL_572]], align 64
subroutine test_pmxvi4ger8pp_non_def()
use, intrinsic :: mma
@@ -1479,14 +1479,14 @@
end subroutine test_pmxvi4ger8pp_non_def
!CHECK-LABEL: @test_pmxvi4ger8pp_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_577:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_578:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_579:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_580:.*]] = load <16 x i8>, ptr %[[VAL_578]], align 16
+! LLVMIR: %[[VAL_581:.*]] = load <16 x i8>, ptr %[[VAL_577]], align 16
+! LLVMIR: %[[VAL_582:.*]] = load <512 x i1>, ptr %[[VAL_579]], align 64
+! LLVMIR: %[[VAL_583:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi4ger8pp(<512 x i1> %[[VAL_582]], <16 x i8> %[[VAL_580]], <16 x i8> %[[VAL_581]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_583]], ptr %[[VAL_579]], align 64
subroutine test_pmxvi8ger4_u1_def()
use, intrinsic :: mma
@@ -1497,13 +1497,13 @@
end subroutine test_pmxvi8ger4_u1_def
!CHECK-LABEL: @test_pmxvi8ger4_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_584:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_585:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_586:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_587:.*]] = load <16 x i8>, ptr %[[VAL_585]], align 16
+! LLVMIR: %[[VAL_588:.*]] = load <16 x i8>, ptr %[[VAL_584]], align 16
+! LLVMIR: %[[VAL_589:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %[[VAL_587]], <16 x i8> %[[VAL_588]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_589]], ptr %[[VAL_586]], align 64
subroutine test_pmxvi8ger4_u1_non_def()
use, intrinsic :: mma
@@ -1514,13 +1514,13 @@
end subroutine test_pmxvi8ger4_u1_non_def
!CHECK-LABEL: @test_pmxvi8ger4_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_590:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_591:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_592:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_593:.*]] = load <16 x i8>, ptr %[[VAL_591]], align 16
+! LLVMIR: %[[VAL_594:.*]] = load <16 x i8>, ptr %[[VAL_590]], align 16
+! LLVMIR: %[[VAL_595:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %[[VAL_593]], <16 x i8> %[[VAL_594]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_595]], ptr %[[VAL_592]], align 64
subroutine test_pmxvi8ger4_i1_def()
use, intrinsic :: mma
@@ -1531,13 +1531,13 @@
end subroutine test_pmxvi8ger4_i1_def
!CHECK-LABEL: @test_pmxvi8ger4_i1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_596:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_597:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_598:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_599:.*]] = load <16 x i8>, ptr %[[VAL_597]], align 16
+! LLVMIR: %[[VAL_600:.*]] = load <16 x i8>, ptr %[[VAL_596]], align 16
+! LLVMIR: %[[VAL_601:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %[[VAL_599]], <16 x i8> %[[VAL_600]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_601]], ptr %[[VAL_598]], align 64
subroutine test_pmxvi8ger4_i1_non_def()
use, intrinsic :: mma
@@ -1548,13 +1548,13 @@
end subroutine test_pmxvi8ger4_i1_non_def
!CHECK-LABEL: @test_pmxvi8ger4_i1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_602:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_603:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_604:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_605:.*]] = load <16 x i8>, ptr %[[VAL_603]], align 16
+! LLVMIR: %[[VAL_606:.*]] = load <16 x i8>, ptr %[[VAL_602]], align 16
+! LLVMIR: %[[VAL_607:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4(<16 x i8> %[[VAL_605]], <16 x i8> %[[VAL_606]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_607]], ptr %[[VAL_604]], align 64
subroutine test_pmxvi8ger4pp_u1_def()
use, intrinsic :: mma
@@ -1565,14 +1565,14 @@
end subroutine test_pmxvi8ger4pp_u1_def
!CHECK-LABEL: @test_pmxvi8ger4pp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_608:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_609:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_610:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_611:.*]] = load <16 x i8>, ptr %[[VAL_609]], align 16
+! LLVMIR: %[[VAL_612:.*]] = load <16 x i8>, ptr %[[VAL_608]], align 16
+! LLVMIR: %[[VAL_613:.*]] = load <512 x i1>, ptr %[[VAL_610]], align 64
+! LLVMIR: %[[VAL_614:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %[[VAL_613]], <16 x i8> %[[VAL_611]], <16 x i8> %[[VAL_612]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_614]], ptr %[[VAL_610]], align 64
subroutine test_pmxvi8ger4pp_u1_non_def()
use, intrinsic :: mma
@@ -1583,14 +1583,14 @@
end subroutine test_pmxvi8ger4pp_u1_non_def
!CHECK-LABEL: @test_pmxvi8ger4pp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_615:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_616:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_617:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_618:.*]] = load <16 x i8>, ptr %[[VAL_616]], align 16
+! LLVMIR: %[[VAL_619:.*]] = load <16 x i8>, ptr %[[VAL_615]], align 16
+! LLVMIR: %[[VAL_620:.*]] = load <512 x i1>, ptr %[[VAL_617]], align 64
+! LLVMIR: %[[VAL_621:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %[[VAL_620]], <16 x i8> %[[VAL_618]], <16 x i8> %[[VAL_619]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_621]], ptr %[[VAL_617]], align 64
subroutine test_pmxvi8ger4pp_i1_def()
use, intrinsic :: mma
@@ -1601,14 +1601,14 @@
end subroutine test_pmxvi8ger4pp_i1_def
!CHECK-LABEL: @test_pmxvi8ger4pp_i1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_622:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_623:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_624:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_625:.*]] = load <16 x i8>, ptr %[[VAL_623]], align 16
+! LLVMIR: %[[VAL_626:.*]] = load <16 x i8>, ptr %[[VAL_622]], align 16
+! LLVMIR: %[[VAL_627:.*]] = load <512 x i1>, ptr %[[VAL_624]], align 64
+! LLVMIR: %[[VAL_628:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %[[VAL_627]], <16 x i8> %[[VAL_625]], <16 x i8> %[[VAL_626]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_628]], ptr %[[VAL_624]], align 64
subroutine test_pmxvi8ger4pp_i1_non_def()
use, intrinsic :: mma
@@ -1619,14 +1619,14 @@
end subroutine test_pmxvi8ger4pp_i1_non_def
!CHECK-LABEL: @test_pmxvi8ger4pp_i1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_629:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_630:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_631:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_632:.*]] = load <16 x i8>, ptr %[[VAL_630]], align 16
+! LLVMIR: %[[VAL_633:.*]] = load <16 x i8>, ptr %[[VAL_629]], align 16
+! LLVMIR: %[[VAL_634:.*]] = load <512 x i1>, ptr %[[VAL_631]], align 64
+! LLVMIR: %[[VAL_635:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4pp(<512 x i1> %[[VAL_634]], <16 x i8> %[[VAL_632]], <16 x i8> %[[VAL_633]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_635]], ptr %[[VAL_631]], align 64
subroutine test_pmxvi8ger4spp_u1_def()
use, intrinsic :: mma
@@ -1637,14 +1637,14 @@
end subroutine test_pmxvi8ger4spp_u1_def
!CHECK-LABEL: @test_pmxvi8ger4spp_u1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_636:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_637:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_638:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_639:.*]] = load <16 x i8>, ptr %[[VAL_637]], align 16
+! LLVMIR: %[[VAL_640:.*]] = load <16 x i8>, ptr %[[VAL_636]], align 16
+! LLVMIR: %[[VAL_641:.*]] = load <512 x i1>, ptr %[[VAL_638]], align 64
+! LLVMIR: %[[VAL_642:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %[[VAL_641]], <16 x i8> %[[VAL_639]], <16 x i8> %[[VAL_640]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_642]], ptr %[[VAL_638]], align 64
subroutine test_pmxvi8ger4spp_u1_non_def()
use, intrinsic :: mma
@@ -1655,14 +1655,14 @@
end subroutine test_pmxvi8ger4spp_u1_non_def
!CHECK-LABEL: @test_pmxvi8ger4spp_u1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_643:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_644:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_645:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_646:.*]] = load <16 x i8>, ptr %[[VAL_644]], align 16
+! LLVMIR: %[[VAL_647:.*]] = load <16 x i8>, ptr %[[VAL_643]], align 16
+! LLVMIR: %[[VAL_648:.*]] = load <512 x i1>, ptr %[[VAL_645]], align 64
+! LLVMIR: %[[VAL_649:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %[[VAL_648]], <16 x i8> %[[VAL_646]], <16 x i8> %[[VAL_647]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_649]], ptr %[[VAL_645]], align 64
subroutine test_pmxvi8ger4spp_i1_def()
use, intrinsic :: mma
@@ -1673,14 +1673,14 @@
end subroutine test_pmxvi8ger4spp_i1_def
!CHECK-LABEL: @test_pmxvi8ger4spp_i1_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_650:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_651:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_652:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_653:.*]] = load <16 x i8>, ptr %[[VAL_651]], align 16
+! LLVMIR: %[[VAL_654:.*]] = load <16 x i8>, ptr %[[VAL_650]], align 16
+! LLVMIR: %[[VAL_655:.*]] = load <512 x i1>, ptr %[[VAL_652]], align 64
+! LLVMIR: %[[VAL_656:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %[[VAL_655]], <16 x i8> %[[VAL_653]], <16 x i8> %[[VAL_654]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_656]], ptr %[[VAL_652]], align 64
subroutine test_pmxvi8ger4spp_i1_non_def()
use, intrinsic :: mma
@@ -1691,11 +1691,11 @@
end subroutine test_pmxvi8ger4spp_i1_non_def
!CHECK-LABEL: @test_pmxvi8ger4spp_i1_non_def_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5, i32 7, i32 7, i32 2)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_657:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_658:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_659:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_660:.*]] = load <16 x i8>, ptr %[[VAL_658]], align 16
+! LLVMIR: %[[VAL_661:.*]] = load <16 x i8>, ptr %[[VAL_657]], align 16
+! LLVMIR: %[[VAL_662:.*]] = load <512 x i1>, ptr %[[VAL_659]], align 64
+! LLVMIR: %[[VAL_663:.*]] = call <512 x i1> @llvm.ppc.mma.pmxvi8ger4spp(<512 x i1> %[[VAL_662]], <16 x i8> %[[VAL_660]], <16 x i8> %[[VAL_661]], i32 7, i32 7, i32 2)
+! LLVMIR: store <512 x i1> %[[VAL_663]], ptr %[[VAL_659]], align 64
diff --git a/flang/test/Lower/PowerPC/ppc-mma-outer-product-2.f90 b/flang/test/Lower/PowerPC/ppc-mma-outer-product-2.f90
index 3ef17b2f963f..b37010bfd0d1 100644
--- a/flang/test/Lower/PowerPC/ppc-mma-outer-product-2.f90
+++ b/flang/test/Lower/PowerPC/ppc-mma-outer-product-2.f90
@@ -10,13 +10,13 @@
end subroutine test_xvbf16ger2
!CHECK-LABEL: @test_xvbf16ger2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvbf16ger2(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_0:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_1:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_2:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_3:.*]] = load <16 x i8>, ptr %[[VAL_1]], align 16
+! LLVMIR: %[[VAL_4:.*]] = load <16 x i8>, ptr %[[VAL_0]], align 16
+! LLVMIR: %[[VAL_5:.*]] = call <512 x i1> @llvm.ppc.mma.xvbf16ger2(<16 x i8> %[[VAL_3]], <16 x i8> %[[VAL_4]])
+! LLVMIR: store <512 x i1> %[[VAL_5]], ptr %[[VAL_2]], align 64
subroutine test_xvbf16ger2nn()
@@ -28,14 +28,14 @@
end subroutine test_xvbf16ger2nn
!CHECK-LABEL: @test_xvbf16ger2nn_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvbf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_6:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_7:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_8:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_9:.*]] = load <16 x i8>, ptr %[[VAL_7]], align 16
+! LLVMIR: %[[VAL_10:.*]] = load <16 x i8>, ptr %[[VAL_6]], align 16
+! LLVMIR: %[[VAL_11:.*]] = load <512 x i1>, ptr %[[VAL_8]], align 64
+! LLVMIR: %[[VAL_12:.*]] = call <512 x i1> @llvm.ppc.mma.xvbf16ger2nn(<512 x i1> %[[VAL_11]], <16 x i8> %[[VAL_9]], <16 x i8> %[[VAL_10]])
+! LLVMIR: store <512 x i1> %[[VAL_12]], ptr %[[VAL_8]], align 64
subroutine test_xvbf16ger2np()
use, intrinsic :: mma
@@ -46,14 +46,14 @@
end subroutine test_xvbf16ger2np
!CHECK-LABEL: @test_xvbf16ger2np_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvbf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_13:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_14:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_15:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_16:.*]] = load <16 x i8>, ptr %[[VAL_14]], align 16
+! LLVMIR: %[[VAL_17:.*]] = load <16 x i8>, ptr %[[VAL_13]], align 16
+! LLVMIR: %[[VAL_18:.*]] = load <512 x i1>, ptr %[[VAL_15]], align 64
+! LLVMIR: %[[VAL_19:.*]] = call <512 x i1> @llvm.ppc.mma.xvbf16ger2np(<512 x i1> %[[VAL_18]], <16 x i8> %[[VAL_16]], <16 x i8> %[[VAL_17]])
+! LLVMIR: store <512 x i1> %[[VAL_19]], ptr %[[VAL_15]], align 64
subroutine test_xvbf16ger2pn()
use, intrinsic :: mma
@@ -64,14 +64,14 @@
end subroutine test_xvbf16ger2pn
!CHECK-LABEL: @test_xvbf16ger2pn_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvbf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_20:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_21:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_22:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_23:.*]] = load <16 x i8>, ptr %[[VAL_21]], align 16
+! LLVMIR: %[[VAL_24:.*]] = load <16 x i8>, ptr %[[VAL_20]], align 16
+! LLVMIR: %[[VAL_25:.*]] = load <512 x i1>, ptr %[[VAL_22]], align 64
+! LLVMIR: %[[VAL_26:.*]] = call <512 x i1> @llvm.ppc.mma.xvbf16ger2pn(<512 x i1> %[[VAL_25]], <16 x i8> %[[VAL_23]], <16 x i8> %[[VAL_24]])
+! LLVMIR: store <512 x i1> %[[VAL_26]], ptr %[[VAL_22]], align 64
subroutine test_xvbf16ger2pp()
use, intrinsic :: mma
@@ -82,14 +82,14 @@
end subroutine test_xvbf16ger2pp
!CHECK-LABEL: @test_xvbf16ger2pp_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvbf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_27:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_28:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_29:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_30:.*]] = load <16 x i8>, ptr %[[VAL_28]], align 16
+! LLVMIR: %[[VAL_31:.*]] = load <16 x i8>, ptr %[[VAL_27]], align 16
+! LLVMIR: %[[VAL_32:.*]] = load <512 x i1>, ptr %[[VAL_29]], align 64
+! LLVMIR: %[[VAL_33:.*]] = call <512 x i1> @llvm.ppc.mma.xvbf16ger2pp(<512 x i1> %[[VAL_32]], <16 x i8> %[[VAL_30]], <16 x i8> %[[VAL_31]])
+! LLVMIR: store <512 x i1> %[[VAL_33]], ptr %[[VAL_29]], align 64
subroutine test_xvf16ger2()
use, intrinsic :: mma
@@ -100,13 +100,13 @@
end subroutine test_xvf16ger2
!CHECK-LABEL: @test_xvf16ger2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvf16ger2(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_34:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_35:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_36:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_37:.*]] = load <16 x i8>, ptr %[[VAL_35]], align 16
+! LLVMIR: %[[VAL_38:.*]] = load <16 x i8>, ptr %[[VAL_34]], align 16
+! LLVMIR: %[[VAL_39:.*]] = call <512 x i1> @llvm.ppc.mma.xvf16ger2(<16 x i8> %[[VAL_37]], <16 x i8> %[[VAL_38]])
+! LLVMIR: store <512 x i1> %[[VAL_39]], ptr %[[VAL_36]], align 64
subroutine test_xvf16ger2nn()
use, intrinsic :: mma
@@ -117,14 +117,14 @@
end subroutine test_xvf16ger2nn
!CHECK-LABEL: @test_xvf16ger2nn_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf16ger2nn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_40:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_41:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_42:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_43:.*]] = load <16 x i8>, ptr %[[VAL_41]], align 16
+! LLVMIR: %[[VAL_44:.*]] = load <16 x i8>, ptr %[[VAL_40]], align 16
+! LLVMIR: %[[VAL_45:.*]] = load <512 x i1>, ptr %[[VAL_42]], align 64
+! LLVMIR: %[[VAL_46:.*]] = call <512 x i1> @llvm.ppc.mma.xvf16ger2nn(<512 x i1> %[[VAL_45]], <16 x i8> %[[VAL_43]], <16 x i8> %[[VAL_44]])
+! LLVMIR: store <512 x i1> %[[VAL_46]], ptr %[[VAL_42]], align 64
subroutine test_xvf16ger2np()
use, intrinsic :: mma
@@ -135,14 +135,14 @@
end subroutine test_xvf16ger2np
!CHECK-LABEL: @test_xvf16ger2np_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf16ger2np(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_47:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_48:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_49:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_50:.*]] = load <16 x i8>, ptr %[[VAL_48]], align 16
+! LLVMIR: %[[VAL_51:.*]] = load <16 x i8>, ptr %[[VAL_47]], align 16
+! LLVMIR: %[[VAL_52:.*]] = load <512 x i1>, ptr %[[VAL_49]], align 64
+! LLVMIR: %[[VAL_53:.*]] = call <512 x i1> @llvm.ppc.mma.xvf16ger2np(<512 x i1> %[[VAL_52]], <16 x i8> %[[VAL_50]], <16 x i8> %[[VAL_51]])
+! LLVMIR: store <512 x i1> %[[VAL_53]], ptr %[[VAL_49]], align 64
subroutine test_xvf16ger2pn()
use, intrinsic :: mma
@@ -153,14 +153,14 @@
end subroutine test_xvf16ger2pn
!CHECK-LABEL: @test_xvf16ger2pn_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf16ger2pn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_54:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_55:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_56:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_57:.*]] = load <16 x i8>, ptr %[[VAL_55]], align 16
+! LLVMIR: %[[VAL_58:.*]] = load <16 x i8>, ptr %[[VAL_54]], align 16
+! LLVMIR: %[[VAL_59:.*]] = load <512 x i1>, ptr %[[VAL_56]], align 64
+! LLVMIR: %[[VAL_60:.*]] = call <512 x i1> @llvm.ppc.mma.xvf16ger2pn(<512 x i1> %[[VAL_59]], <16 x i8> %[[VAL_57]], <16 x i8> %[[VAL_58]])
+! LLVMIR: store <512 x i1> %[[VAL_60]], ptr %[[VAL_56]], align 64
subroutine test_xvf16ger2pp()
use, intrinsic :: mma
@@ -171,14 +171,14 @@
end subroutine test_xvf16ger2pp
!CHECK-LABEL: @test_xvf16ger2pp_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_61:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_62:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_63:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_64:.*]] = load <16 x i8>, ptr %[[VAL_62]], align 16
+! LLVMIR: %[[VAL_65:.*]] = load <16 x i8>, ptr %[[VAL_61]], align 16
+! LLVMIR: %[[VAL_66:.*]] = load <512 x i1>, ptr %[[VAL_63]], align 64
+! LLVMIR: %[[VAL_67:.*]] = call <512 x i1> @llvm.ppc.mma.xvf16ger2pp(<512 x i1> %[[VAL_66]], <16 x i8> %[[VAL_64]], <16 x i8> %[[VAL_65]])
+! LLVMIR: store <512 x i1> %[[VAL_67]], ptr %[[VAL_63]], align 64
subroutine test_xvf32ger_u1()
use, intrinsic :: mma
@@ -189,13 +189,13 @@
end subroutine test_xvf32ger_u1
!CHECK-LABEL: @test_xvf32ger_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvf32ger(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_68:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_69:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_70:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_71:.*]] = load <16 x i8>, ptr %[[VAL_69]], align 16
+! LLVMIR: %[[VAL_72:.*]] = load <16 x i8>, ptr %[[VAL_68]], align 16
+! LLVMIR: %[[VAL_73:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32ger(<16 x i8> %[[VAL_71]], <16 x i8> %[[VAL_72]])
+! LLVMIR: store <512 x i1> %[[VAL_73]], ptr %[[VAL_70]], align 64
subroutine test_xvf32ger_r4()
@@ -207,15 +207,15 @@
end subroutine test_xvf32ger_r4
!CHECK-LABEL: @test_xvf32ger_r4_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvf32ger(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_74:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_75:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_76:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_77:.*]] = load <4 x float>, ptr %[[VAL_75]], align 16
+! LLVMIR: %[[VAL_78:.*]] = load <4 x float>, ptr %[[VAL_74]], align 16
+! LLVMIR: %[[VAL_79:.*]] = bitcast <4 x float> %[[VAL_77]] to <16 x i8>
+! LLVMIR: %[[VAL_80:.*]] = bitcast <4 x float> %[[VAL_78]] to <16 x i8>
+! LLVMIR: %[[VAL_81:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32ger(<16 x i8> %[[VAL_79]], <16 x i8> %[[VAL_80]])
+! LLVMIR: store <512 x i1> %[[VAL_81]], ptr %[[VAL_76]], align 64
subroutine test_xvf32gernn_u1()
use, intrinsic :: mma
@@ -226,14 +226,14 @@
end subroutine test_xvf32gernn_u1
!CHECK-LABEL: @test_xvf32gernn_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf32gernn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_82:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_83:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_84:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_85:.*]] = load <16 x i8>, ptr %[[VAL_83]], align 16
+! LLVMIR: %[[VAL_86:.*]] = load <16 x i8>, ptr %[[VAL_82]], align 16
+! LLVMIR: %[[VAL_87:.*]] = load <512 x i1>, ptr %[[VAL_84]], align 64
+! LLVMIR: %[[VAL_88:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gernn(<512 x i1> %[[VAL_87]], <16 x i8> %[[VAL_85]], <16 x i8> %[[VAL_86]])
+! LLVMIR: store <512 x i1> %[[VAL_88]], ptr %[[VAL_84]], align 64
subroutine test_xvf32gernn_r4()
use, intrinsic :: mma
@@ -244,16 +244,16 @@
end subroutine test_xvf32gernn_r4
!CHECK-LABEL: @test_xvf32gernn_r4_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvf32gernn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_89:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_90:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_91:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_92:.*]] = load <4 x float>, ptr %[[VAL_90]], align 16
+! LLVMIR: %[[VAL_93:.*]] = load <4 x float>, ptr %[[VAL_89]], align 16
+! LLVMIR: %[[VAL_94:.*]] = load <512 x i1>, ptr %[[VAL_91]], align 64
+! LLVMIR: %[[VAL_95:.*]] = bitcast <4 x float> %[[VAL_92]] to <16 x i8>
+! LLVMIR: %[[VAL_96:.*]] = bitcast <4 x float> %[[VAL_93]] to <16 x i8>
+! LLVMIR: %[[VAL_97:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gernn(<512 x i1> %[[VAL_94]], <16 x i8> %[[VAL_95]], <16 x i8> %[[VAL_96]])
+! LLVMIR: store <512 x i1> %[[VAL_97]], ptr %[[VAL_91]], align 64
subroutine test_xvf32gernp_u1()
use, intrinsic :: mma
@@ -264,14 +264,14 @@
end subroutine test_xvf32gernp_u1
!CHECK-LABEL: @test_xvf32gernp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf32gernp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_98:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_99:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_100:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_101:.*]] = load <16 x i8>, ptr %[[VAL_99]], align 16
+! LLVMIR: %[[VAL_102:.*]] = load <16 x i8>, ptr %[[VAL_98]], align 16
+! LLVMIR: %[[VAL_103:.*]] = load <512 x i1>, ptr %[[VAL_100]], align 64
+! LLVMIR: %[[VAL_104:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gernp(<512 x i1> %[[VAL_103]], <16 x i8> %[[VAL_101]], <16 x i8> %[[VAL_102]])
+! LLVMIR: store <512 x i1> %[[VAL_104]], ptr %[[VAL_100]], align 64
subroutine test_xvf32gernp_r4()
use, intrinsic :: mma
@@ -282,16 +282,16 @@
end subroutine test_xvf32gernp_r4
!CHECK-LABEL: @test_xvf32gernp_r4_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvf32gernp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_105:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_106:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_107:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_108:.*]] = load <4 x float>, ptr %[[VAL_106]], align 16
+! LLVMIR: %[[VAL_109:.*]] = load <4 x float>, ptr %[[VAL_105]], align 16
+! LLVMIR: %[[VAL_110:.*]] = load <512 x i1>, ptr %[[VAL_107]], align 64
+! LLVMIR: %[[VAL_111:.*]] = bitcast <4 x float> %[[VAL_108]] to <16 x i8>
+! LLVMIR: %[[VAL_112:.*]] = bitcast <4 x float> %[[VAL_109]] to <16 x i8>
+! LLVMIR: %[[VAL_113:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gernp(<512 x i1> %[[VAL_110]], <16 x i8> %[[VAL_111]], <16 x i8> %[[VAL_112]])
+! LLVMIR: store <512 x i1> %[[VAL_113]], ptr %[[VAL_107]], align 64
subroutine test_xvf32gerpn_u1()
use, intrinsic :: mma
@@ -302,14 +302,14 @@
end subroutine test_xvf32gerpn_u1
!CHECK-LABEL: @test_xvf32gerpn_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf32gerpn(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_114:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_115:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_116:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_117:.*]] = load <16 x i8>, ptr %[[VAL_115]], align 16
+! LLVMIR: %[[VAL_118:.*]] = load <16 x i8>, ptr %[[VAL_114]], align 16
+! LLVMIR: %[[VAL_119:.*]] = load <512 x i1>, ptr %[[VAL_116]], align 64
+! LLVMIR: %[[VAL_120:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gerpn(<512 x i1> %[[VAL_119]], <16 x i8> %[[VAL_117]], <16 x i8> %[[VAL_118]])
+! LLVMIR: store <512 x i1> %[[VAL_120]], ptr %[[VAL_116]], align 64
subroutine test_xvf32gerpn_r4()
use, intrinsic :: mma
@@ -320,16 +320,16 @@
end subroutine test_xvf32gerpn_r4
!CHECK-LABEL: @test_xvf32gerpn_r4_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvf32gerpn(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_121:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_122:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_123:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_124:.*]] = load <4 x float>, ptr %[[VAL_122]], align 16
+! LLVMIR: %[[VAL_125:.*]] = load <4 x float>, ptr %[[VAL_121]], align 16
+! LLVMIR: %[[VAL_126:.*]] = load <512 x i1>, ptr %[[VAL_123]], align 64
+! LLVMIR: %[[VAL_127:.*]] = bitcast <4 x float> %[[VAL_124]] to <16 x i8>
+! LLVMIR: %[[VAL_128:.*]] = bitcast <4 x float> %[[VAL_125]] to <16 x i8>
+! LLVMIR: %[[VAL_129:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gerpn(<512 x i1> %[[VAL_126]], <16 x i8> %[[VAL_127]], <16 x i8> %[[VAL_128]])
+! LLVMIR: store <512 x i1> %[[VAL_129]], ptr %[[VAL_123]], align 64
subroutine test_xvf32gerpp_u1()
use, intrinsic :: mma
@@ -340,14 +340,14 @@
end subroutine test_xvf32gerpp_u1
!CHECK-LABEL: @test_xvf32gerpp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf32gerpp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_130:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_131:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_132:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_133:.*]] = load <16 x i8>, ptr %[[VAL_131]], align 16
+! LLVMIR: %[[VAL_134:.*]] = load <16 x i8>, ptr %[[VAL_130]], align 16
+! LLVMIR: %[[VAL_135:.*]] = load <512 x i1>, ptr %[[VAL_132]], align 64
+! LLVMIR: %[[VAL_136:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gerpp(<512 x i1> %[[VAL_135]], <16 x i8> %[[VAL_133]], <16 x i8> %[[VAL_134]])
+! LLVMIR: store <512 x i1> %[[VAL_136]], ptr %[[VAL_132]], align 64
subroutine test_xvf32gerpp_r4()
@@ -359,16 +359,16 @@
end subroutine test_xvf32gerpp_r4
!CHECK-LABEL: @test_xvf32gerpp_r4_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %3 = alloca <4 x float>, i64 1, align 16
-!LLVMIR: %4 = load <4 x float>, ptr %2, align 16
-!LLVMIR: %5 = load <4 x float>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <4 x float> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <4 x float> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvf32gerpp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_137:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_138:.*]] = alloca <4 x float>, i64 1, align 16
+! LLVMIR: %[[VAL_139:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_140:.*]] = load <4 x float>, ptr %[[VAL_138]], align 16
+! LLVMIR: %[[VAL_141:.*]] = load <4 x float>, ptr %[[VAL_137]], align 16
+! LLVMIR: %[[VAL_142:.*]] = load <512 x i1>, ptr %[[VAL_139]], align 64
+! LLVMIR: %[[VAL_143:.*]] = bitcast <4 x float> %[[VAL_140]] to <16 x i8>
+! LLVMIR: %[[VAL_144:.*]] = bitcast <4 x float> %[[VAL_141]] to <16 x i8>
+! LLVMIR: %[[VAL_145:.*]] = call <512 x i1> @llvm.ppc.mma.xvf32gerpp(<512 x i1> %[[VAL_142]], <16 x i8> %[[VAL_143]], <16 x i8> %[[VAL_144]])
+! LLVMIR: store <512 x i1> %[[VAL_145]], ptr %[[VAL_139]], align 64
subroutine test_xvf64ger_u1()
use, intrinsic :: mma
@@ -380,13 +380,13 @@
end subroutine test_xvf64ger_u1
!CHECK-LABEL: @test_xvf64ger_u1_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvf64ger(<256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %2, align 64
+! LLVMIR: %[[VAL_146:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_147:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_148:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_149:.*]] = load <256 x i1>, ptr %[[VAL_148]], align 32
+! LLVMIR: %[[VAL_150:.*]] = load <16 x i8>, ptr %[[VAL_146]], align 16
+! LLVMIR: %[[VAL_151:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64ger(<256 x i1> %[[VAL_149]], <16 x i8> %[[VAL_150]])
+! LLVMIR: store <512 x i1> %[[VAL_151]], ptr %[[VAL_147]], align 64
subroutine test_xvf64ger_r8()
use, intrinsic :: mma
@@ -398,14 +398,14 @@
end subroutine test_xvf64ger_r8
!CHECK-LABEL: @test_xvf64ger_r8_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64ger(<256 x i1> %4, <16 x i8> %6)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_152:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_153:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_154:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_155:.*]] = load <256 x i1>, ptr %[[VAL_154]], align 32
+! LLVMIR: %[[VAL_156:.*]] = load <2 x double>, ptr %[[VAL_152]], align 16
+! LLVMIR: %[[VAL_157:.*]] = bitcast <2 x double> %[[VAL_156]] to <16 x i8>
+! LLVMIR: %[[VAL_158:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64ger(<256 x i1> %[[VAL_155]], <16 x i8> %[[VAL_157]])
+! LLVMIR: store <512 x i1> %[[VAL_158]], ptr %[[VAL_153]], align 64
subroutine test_xvf64gernn_u1()
@@ -418,14 +418,14 @@
end subroutine test_xvf64gernn_u1
!CHECK-LABEL: @test_xvf64gernn_u1_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_159:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_160:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_161:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_162:.*]] = load <256 x i1>, ptr %[[VAL_161]], align 32
+! LLVMIR: %[[VAL_163:.*]] = load <16 x i8>, ptr %[[VAL_159]], align 16
+! LLVMIR: %[[VAL_164:.*]] = load <512 x i1>, ptr %[[VAL_160]], align 64
+! LLVMIR: %[[VAL_165:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gernn(<512 x i1> %[[VAL_164]], <256 x i1> %[[VAL_162]], <16 x i8> %[[VAL_163]])
+! LLVMIR: store <512 x i1> %[[VAL_165]], ptr %[[VAL_160]], align 64
subroutine test_xvf64gernn_r8()
@@ -438,15 +438,15 @@
end subroutine test_xvf64gernn_r8
!CHECK-LABEL: @test_xvf64gernn_r8_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvf64gernn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_166:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_167:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_168:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_169:.*]] = load <256 x i1>, ptr %[[VAL_168]], align 32
+! LLVMIR: %[[VAL_170:.*]] = load <2 x double>, ptr %[[VAL_166]], align 16
+! LLVMIR: %[[VAL_171:.*]] = load <512 x i1>, ptr %[[VAL_167]], align 64
+! LLVMIR: %[[VAL_172:.*]] = bitcast <2 x double> %[[VAL_170]] to <16 x i8>
+! LLVMIR: %[[VAL_173:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gernn(<512 x i1> %[[VAL_171]], <256 x i1> %[[VAL_169]], <16 x i8> %[[VAL_172]])
+! LLVMIR: store <512 x i1> %[[VAL_173]], ptr %[[VAL_167]], align 64
subroutine test_xvf64gernp_u1()
use, intrinsic :: mma
@@ -458,14 +458,14 @@
end subroutine test_xvf64gernp_u1
!CHECK-LABEL: @test_xvf64gernp_u1_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_174:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_175:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_176:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_177:.*]] = load <256 x i1>, ptr %[[VAL_176]], align 32
+! LLVMIR: %[[VAL_178:.*]] = load <16 x i8>, ptr %[[VAL_174]], align 16
+! LLVMIR: %[[VAL_179:.*]] = load <512 x i1>, ptr %[[VAL_175]], align 64
+! LLVMIR: %[[VAL_180:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> %[[VAL_179]], <256 x i1> %[[VAL_177]], <16 x i8> %[[VAL_178]])
+! LLVMIR: store <512 x i1> %[[VAL_180]], ptr %[[VAL_175]], align 64
subroutine test_xvf64gernp_r8()
use, intrinsic :: mma
@@ -477,14 +477,14 @@
end subroutine test_xvf64gernp_r8
!CHECK-LABEL: @test_xvf64gernp_r8_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_181:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_182:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_183:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_184:.*]] = load <256 x i1>, ptr %[[VAL_183]], align 32
+! LLVMIR: %[[VAL_185:.*]] = load <16 x i8>, ptr %[[VAL_181]], align 16
+! LLVMIR: %[[VAL_186:.*]] = load <512 x i1>, ptr %[[VAL_182]], align 64
+! LLVMIR: %[[VAL_187:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gernp(<512 x i1> %[[VAL_186]], <256 x i1> %[[VAL_184]], <16 x i8> %[[VAL_185]])
+! LLVMIR: store <512 x i1> %[[VAL_187]], ptr %[[VAL_182]], align 64
subroutine test_xvf64gerpn_u1()
use, intrinsic :: mma
@@ -496,14 +496,14 @@
end subroutine test_xvf64gerpn_u1
!CHECK-LABEL: @test_xvf64gerpn_u1_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_188:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_189:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_190:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_191:.*]] = load <256 x i1>, ptr %[[VAL_190]], align 32
+! LLVMIR: %[[VAL_192:.*]] = load <16 x i8>, ptr %[[VAL_188]], align 16
+! LLVMIR: %[[VAL_193:.*]] = load <512 x i1>, ptr %[[VAL_189]], align 64
+! LLVMIR: %[[VAL_194:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gerpn(<512 x i1> %[[VAL_193]], <256 x i1> %[[VAL_191]], <16 x i8> %[[VAL_192]])
+! LLVMIR: store <512 x i1> %[[VAL_194]], ptr %[[VAL_189]], align 64
subroutine test_xvf64gerpn_r8()
use, intrinsic :: mma
@@ -515,15 +515,15 @@
end subroutine test_xvf64gerpn_r8
!CHECK-LABEL: @test_xvf64gerpn_r8_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvf64gerpn(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_195:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_196:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_197:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_198:.*]] = load <256 x i1>, ptr %[[VAL_197]], align 32
+! LLVMIR: %[[VAL_199:.*]] = load <2 x double>, ptr %[[VAL_195]], align 16
+! LLVMIR: %[[VAL_200:.*]] = load <512 x i1>, ptr %[[VAL_196]], align 64
+! LLVMIR: %[[VAL_201:.*]] = bitcast <2 x double> %[[VAL_199]] to <16 x i8>
+! LLVMIR: %[[VAL_202:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gerpn(<512 x i1> %[[VAL_200]], <256 x i1> %[[VAL_198]], <16 x i8> %[[VAL_201]])
+! LLVMIR: store <512 x i1> %[[VAL_202]], ptr %[[VAL_196]], align 64
subroutine test_xvf64gerpp_u1()
use, intrinsic :: mma
@@ -535,14 +535,14 @@
end subroutine test_xvf64gerpp_u1
!CHECK-LABEL: @test_xvf64gerpp_u1_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %2, align 64
+! LLVMIR: %[[VAL_203:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_204:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_205:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_206:.*]] = load <256 x i1>, ptr %[[VAL_205]], align 32
+! LLVMIR: %[[VAL_207:.*]] = load <16 x i8>, ptr %[[VAL_203]], align 16
+! LLVMIR: %[[VAL_208:.*]] = load <512 x i1>, ptr %[[VAL_204]], align 64
+! LLVMIR: %[[VAL_209:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gerpp(<512 x i1> %[[VAL_208]], <256 x i1> %[[VAL_206]], <16 x i8> %[[VAL_207]])
+! LLVMIR: store <512 x i1> %[[VAL_209]], ptr %[[VAL_204]], align 64
subroutine test_xvf64gerpp_r8()
@@ -555,15 +555,15 @@
end subroutine test_xvf64gerpp_r8
!CHECK-LABEL: @test_xvf64gerpp_r8_
-!LLVMIR: %1 = alloca <256 x i1>, i64 1, align 32
-!LLVMIR: %2 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %3 = alloca <2 x double>, i64 1, align 16
-!LLVMIR: %4 = load <256 x i1>, ptr %1, align 32
-!LLVMIR: %5 = load <2 x double>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %2, align 64
-!LLVMIR: %7 = bitcast <2 x double> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvf64gerpp(<512 x i1> %6, <256 x i1> %4, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %2, align 64
+! LLVMIR: %[[VAL_210:.*]] = alloca <2 x double>, i64 1, align 16
+! LLVMIR: %[[VAL_211:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_212:.*]] = alloca <256 x i1>, i64 1, align 32
+! LLVMIR: %[[VAL_213:.*]] = load <256 x i1>, ptr %[[VAL_212]], align 32
+! LLVMIR: %[[VAL_214:.*]] = load <2 x double>, ptr %[[VAL_210]], align 16
+! LLVMIR: %[[VAL_215:.*]] = load <512 x i1>, ptr %[[VAL_211]], align 64
+! LLVMIR: %[[VAL_216:.*]] = bitcast <2 x double> %[[VAL_214]] to <16 x i8>
+! LLVMIR: %[[VAL_217:.*]] = call <512 x i1> @llvm.ppc.mma.xvf64gerpp(<512 x i1> %[[VAL_215]], <256 x i1> %[[VAL_213]], <16 x i8> %[[VAL_216]])
+! LLVMIR: store <512 x i1> %[[VAL_217]], ptr %[[VAL_211]], align 64
subroutine test_xvi16ger2_u1()
use, intrinsic :: mma
@@ -574,13 +574,13 @@
end subroutine test_xvi16ger2_u1
!CHECK-LABEL: @test_xvi16ger2_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvi16ger2(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_218:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_219:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_220:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_221:.*]] = load <16 x i8>, ptr %[[VAL_219]], align 16
+! LLVMIR: %[[VAL_222:.*]] = load <16 x i8>, ptr %[[VAL_218]], align 16
+! LLVMIR: %[[VAL_223:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2(<16 x i8> %[[VAL_221]], <16 x i8> %[[VAL_222]])
+! LLVMIR: store <512 x i1> %[[VAL_223]], ptr %[[VAL_220]], align 64
subroutine test_xvi16ger2_i2()
use, intrinsic :: mma
@@ -591,15 +591,15 @@
end subroutine test_xvi16ger2_i2
!CHECK-LABEL: @test_xvi16ger2_i2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvi16ger2(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_224:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_225:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_226:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_227:.*]] = load <8 x i16>, ptr %[[VAL_225]], align 16
+! LLVMIR: %[[VAL_228:.*]] = load <8 x i16>, ptr %[[VAL_224]], align 16
+! LLVMIR: %[[VAL_229:.*]] = bitcast <8 x i16> %[[VAL_227]] to <16 x i8>
+! LLVMIR: %[[VAL_230:.*]] = bitcast <8 x i16> %[[VAL_228]] to <16 x i8>
+! LLVMIR: %[[VAL_231:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2(<16 x i8> %[[VAL_229]], <16 x i8> %[[VAL_230]])
+! LLVMIR: store <512 x i1> %[[VAL_231]], ptr %[[VAL_226]], align 64
subroutine test_xvi16ger2pp_u1()
use, intrinsic :: mma
@@ -610,14 +610,14 @@
end subroutine test_xvi16ger2pp_u1
!CHECK-LABEL: @test_xvi16ger2pp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi16ger2pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_232:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_233:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_234:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_235:.*]] = load <16 x i8>, ptr %[[VAL_233]], align 16
+! LLVMIR: %[[VAL_236:.*]] = load <16 x i8>, ptr %[[VAL_232]], align 16
+! LLVMIR: %[[VAL_237:.*]] = load <512 x i1>, ptr %[[VAL_234]], align 64
+! LLVMIR: %[[VAL_238:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2pp(<512 x i1> %[[VAL_237]], <16 x i8> %[[VAL_235]], <16 x i8> %[[VAL_236]])
+! LLVMIR: store <512 x i1> %[[VAL_238]], ptr %[[VAL_234]], align 64
subroutine test_xvi16ger2pp_i2()
use, intrinsic :: mma
@@ -628,16 +628,16 @@
end subroutine test_xvi16ger2pp_i2
!CHECK-LABEL: @test_xvi16ger2pp_i2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvi16ger2pp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_239:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_240:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_241:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_242:.*]] = load <8 x i16>, ptr %[[VAL_240]], align 16
+! LLVMIR: %[[VAL_243:.*]] = load <8 x i16>, ptr %[[VAL_239]], align 16
+! LLVMIR: %[[VAL_244:.*]] = load <512 x i1>, ptr %[[VAL_241]], align 64
+! LLVMIR: %[[VAL_245:.*]] = bitcast <8 x i16> %[[VAL_242]] to <16 x i8>
+! LLVMIR: %[[VAL_246:.*]] = bitcast <8 x i16> %[[VAL_243]] to <16 x i8>
+! LLVMIR: %[[VAL_247:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2pp(<512 x i1> %[[VAL_244]], <16 x i8> %[[VAL_245]], <16 x i8> %[[VAL_246]])
+! LLVMIR: store <512 x i1> %[[VAL_247]], ptr %[[VAL_241]], align 64
subroutine test_xvi16ger2s_u1()
use, intrinsic :: mma
@@ -648,13 +648,13 @@
end subroutine test_xvi16ger2s_u1
!CHECK-LABEL: @test_xvi16ger2s_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvi16ger2s(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_248:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_249:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_250:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_251:.*]] = load <16 x i8>, ptr %[[VAL_249]], align 16
+! LLVMIR: %[[VAL_252:.*]] = load <16 x i8>, ptr %[[VAL_248]], align 16
+! LLVMIR: %[[VAL_253:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2s(<16 x i8> %[[VAL_251]], <16 x i8> %[[VAL_252]])
+! LLVMIR: store <512 x i1> %[[VAL_253]], ptr %[[VAL_250]], align 64
subroutine test_xvi16ger2s_i2()
use, intrinsic :: mma
@@ -665,15 +665,15 @@
end subroutine test_xvi16ger2s_i2
!CHECK-LABEL: @test_xvi16ger2s_i2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %7 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %8 = call <512 x i1> @llvm.ppc.mma.xvi16ger2s(<16 x i8> %6, <16 x i8> %7)
-!LLVMIR: store <512 x i1> %8, ptr %1, align 64
+! LLVMIR: %[[VAL_254:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_255:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_256:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_257:.*]] = load <8 x i16>, ptr %[[VAL_255]], align 16
+! LLVMIR: %[[VAL_258:.*]] = load <8 x i16>, ptr %[[VAL_254]], align 16
+! LLVMIR: %[[VAL_259:.*]] = bitcast <8 x i16> %[[VAL_257]] to <16 x i8>
+! LLVMIR: %[[VAL_260:.*]] = bitcast <8 x i16> %[[VAL_258]] to <16 x i8>
+! LLVMIR: %[[VAL_261:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2s(<16 x i8> %[[VAL_259]], <16 x i8> %[[VAL_260]])
+! LLVMIR: store <512 x i1> %[[VAL_261]], ptr %[[VAL_256]], align 64
subroutine test_xvi16ger2spp_u1()
use, intrinsic :: mma
@@ -684,14 +684,14 @@
end subroutine test_xvi16ger2spp_u1
!CHECK-LABEL: @test_xvi16ger2spp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi16ger2spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_262:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_263:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_264:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_265:.*]] = load <16 x i8>, ptr %[[VAL_263]], align 16
+! LLVMIR: %[[VAL_266:.*]] = load <16 x i8>, ptr %[[VAL_262]], align 16
+! LLVMIR: %[[VAL_267:.*]] = load <512 x i1>, ptr %[[VAL_264]], align 64
+! LLVMIR: %[[VAL_268:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2spp(<512 x i1> %[[VAL_267]], <16 x i8> %[[VAL_265]], <16 x i8> %[[VAL_266]])
+! LLVMIR: store <512 x i1> %[[VAL_268]], ptr %[[VAL_264]], align 64
subroutine test_xvi16ger2spp_i2()
use, intrinsic :: mma
@@ -702,16 +702,16 @@
end subroutine test_xvi16ger2spp_i2
!CHECK-LABEL: @test_xvi16ger2spp_i2_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %3 = alloca <8 x i16>, i64 1, align 16
-!LLVMIR: %4 = load <8 x i16>, ptr %2, align 16
-!LLVMIR: %5 = load <8 x i16>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = bitcast <8 x i16> %4 to <16 x i8>
-!LLVMIR: %8 = bitcast <8 x i16> %5 to <16 x i8>
-!LLVMIR: %9 = call <512 x i1> @llvm.ppc.mma.xvi16ger2spp(<512 x i1> %6, <16 x i8> %7, <16 x i8> %8)
-!LLVMIR: store <512 x i1> %9, ptr %1, align 64
+! LLVMIR: %[[VAL_269:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_270:.*]] = alloca <8 x i16>, i64 1, align 16
+! LLVMIR: %[[VAL_271:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_272:.*]] = load <8 x i16>, ptr %[[VAL_270]], align 16
+! LLVMIR: %[[VAL_273:.*]] = load <8 x i16>, ptr %[[VAL_269]], align 16
+! LLVMIR: %[[VAL_274:.*]] = load <512 x i1>, ptr %[[VAL_271]], align 64
+! LLVMIR: %[[VAL_275:.*]] = bitcast <8 x i16> %[[VAL_272]] to <16 x i8>
+! LLVMIR: %[[VAL_276:.*]] = bitcast <8 x i16> %[[VAL_273]] to <16 x i8>
+! LLVMIR: %[[VAL_277:.*]] = call <512 x i1> @llvm.ppc.mma.xvi16ger2spp(<512 x i1> %[[VAL_274]], <16 x i8> %[[VAL_275]], <16 x i8> %[[VAL_276]])
+! LLVMIR: store <512 x i1> %[[VAL_277]], ptr %[[VAL_271]], align 64
subroutine test_xvi4ger8()
use, intrinsic :: mma
@@ -722,13 +722,13 @@
end subroutine test_xvi4ger8
!CHECK-LABEL: @test_xvi4ger8_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvi4ger8(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_278:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_279:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_280:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_281:.*]] = load <16 x i8>, ptr %[[VAL_279]], align 16
+! LLVMIR: %[[VAL_282:.*]] = load <16 x i8>, ptr %[[VAL_278]], align 16
+! LLVMIR: %[[VAL_283:.*]] = call <512 x i1> @llvm.ppc.mma.xvi4ger8(<16 x i8> %[[VAL_281]], <16 x i8> %[[VAL_282]])
+! LLVMIR: store <512 x i1> %[[VAL_283]], ptr %[[VAL_280]], align 64
subroutine test_xvi4ger8pp()
use, intrinsic :: mma
@@ -739,14 +739,14 @@
end subroutine test_xvi4ger8pp
!CHECK-LABEL: @test_xvi4ger8pp_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi4ger8pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_284:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_285:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_286:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_287:.*]] = load <16 x i8>, ptr %[[VAL_285]], align 16
+! LLVMIR: %[[VAL_288:.*]] = load <16 x i8>, ptr %[[VAL_284]], align 16
+! LLVMIR: %[[VAL_289:.*]] = load <512 x i1>, ptr %[[VAL_286]], align 64
+! LLVMIR: %[[VAL_290:.*]] = call <512 x i1> @llvm.ppc.mma.xvi4ger8pp(<512 x i1> %[[VAL_289]], <16 x i8> %[[VAL_287]], <16 x i8> %[[VAL_288]])
+! LLVMIR: store <512 x i1> %[[VAL_290]], ptr %[[VAL_286]], align 64
subroutine test_xvi8ger4_u1()
use, intrinsic :: mma
@@ -757,13 +757,13 @@
end subroutine test_xvi8ger4_u1
!CHECK-LABEL: @test_xvi8ger4_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvi8ger4(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_291:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_292:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_293:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_294:.*]] = load <16 x i8>, ptr %[[VAL_292]], align 16
+! LLVMIR: %[[VAL_295:.*]] = load <16 x i8>, ptr %[[VAL_291]], align 16
+! LLVMIR: %[[VAL_296:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4(<16 x i8> %[[VAL_294]], <16 x i8> %[[VAL_295]])
+! LLVMIR: store <512 x i1> %[[VAL_296]], ptr %[[VAL_293]], align 64
subroutine test_xvi8ger4_i1()
@@ -775,13 +775,13 @@
end subroutine test_xvi8ger4_i1
!CHECK-LABEL: @test_xvi8ger4_i1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = call <512 x i1> @llvm.ppc.mma.xvi8ger4(<16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %6, ptr %1, align 64
+! LLVMIR: %[[VAL_297:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_298:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_299:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_300:.*]] = load <16 x i8>, ptr %[[VAL_298]], align 16
+! LLVMIR: %[[VAL_301:.*]] = load <16 x i8>, ptr %[[VAL_297]], align 16
+! LLVMIR: %[[VAL_302:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4(<16 x i8> %[[VAL_300]], <16 x i8> %[[VAL_301]])
+! LLVMIR: store <512 x i1> %[[VAL_302]], ptr %[[VAL_299]], align 64
subroutine test_xvi8ger4pp_u1()
use, intrinsic :: mma
@@ -792,14 +792,14 @@
end subroutine test_xvi8ger4pp_u1
!CHECK-LABEL: @test_xvi8ger4pp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_303:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_304:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_305:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_306:.*]] = load <16 x i8>, ptr %[[VAL_304]], align 16
+! LLVMIR: %[[VAL_307:.*]] = load <16 x i8>, ptr %[[VAL_303]], align 16
+! LLVMIR: %[[VAL_308:.*]] = load <512 x i1>, ptr %[[VAL_305]], align 64
+! LLVMIR: %[[VAL_309:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4pp(<512 x i1> %[[VAL_308]], <16 x i8> %[[VAL_306]], <16 x i8> %[[VAL_307]])
+! LLVMIR: store <512 x i1> %[[VAL_309]], ptr %[[VAL_305]], align 64
subroutine test_xvi8ger4pp_i1()
use, intrinsic :: mma
@@ -810,14 +810,14 @@
end subroutine test_xvi8ger4pp_i1
!CHECK-LABEL: @test_xvi8ger4pp_i1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi8ger4pp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_310:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_311:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_312:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_313:.*]] = load <16 x i8>, ptr %[[VAL_311]], align 16
+! LLVMIR: %[[VAL_314:.*]] = load <16 x i8>, ptr %[[VAL_310]], align 16
+! LLVMIR: %[[VAL_315:.*]] = load <512 x i1>, ptr %[[VAL_312]], align 64
+! LLVMIR: %[[VAL_316:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4pp(<512 x i1> %[[VAL_315]], <16 x i8> %[[VAL_313]], <16 x i8> %[[VAL_314]])
+! LLVMIR: store <512 x i1> %[[VAL_316]], ptr %[[VAL_312]], align 64
subroutine test_xvi8ger4spp_u1()
use, intrinsic :: mma
@@ -828,14 +828,14 @@
end subroutine test_xvi8ger4spp_u1
!CHECK-LABEL: @test_xvi8ger4spp_u1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_317:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_318:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_319:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_320:.*]] = load <16 x i8>, ptr %[[VAL_318]], align 16
+! LLVMIR: %[[VAL_321:.*]] = load <16 x i8>, ptr %[[VAL_317]], align 16
+! LLVMIR: %[[VAL_322:.*]] = load <512 x i1>, ptr %[[VAL_319]], align 64
+! LLVMIR: %[[VAL_323:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4spp(<512 x i1> %[[VAL_322]], <16 x i8> %[[VAL_320]], <16 x i8> %[[VAL_321]])
+! LLVMIR: store <512 x i1> %[[VAL_323]], ptr %[[VAL_319]], align 64
subroutine test_xvi8ger4spp_i1()
use, intrinsic :: mma
@@ -846,11 +846,11 @@
end subroutine test_xvi8ger4spp_i1
!CHECK-LABEL: @test_xvi8ger4spp_i1_
-!LLVMIR: %1 = alloca <512 x i1>, i64 1, align 64
-!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %4 = load <16 x i8>, ptr %2, align 16
-!LLVMIR: %5 = load <16 x i8>, ptr %3, align 16
-!LLVMIR: %6 = load <512 x i1>, ptr %1, align 64
-!LLVMIR: %7 = call <512 x i1> @llvm.ppc.mma.xvi8ger4spp(<512 x i1> %6, <16 x i8> %4, <16 x i8> %5)
-!LLVMIR: store <512 x i1> %7, ptr %1, align 64
+! LLVMIR: %[[VAL_324:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_325:.*]] = alloca <16 x i8>, i64 1, align 16
+! LLVMIR: %[[VAL_326:.*]] = alloca <512 x i1>, i64 1, align 64
+! LLVMIR: %[[VAL_327:.*]] = load <16 x i8>, ptr %[[VAL_325]], align 16
+! LLVMIR: %[[VAL_328:.*]] = load <16 x i8>, ptr %[[VAL_324]], align 16
+! LLVMIR: %[[VAL_329:.*]] = load <512 x i1>, ptr %[[VAL_326]], align 64
+! LLVMIR: %[[VAL_330:.*]] = call <512 x i1> @llvm.ppc.mma.xvi8ger4spp(<512 x i1> %[[VAL_329]], <16 x i8> %[[VAL_327]], <16 x i8> %[[VAL_328]])
+! LLVMIR: store <512 x i1> %[[VAL_330]], ptr %[[VAL_326]], align 64
diff --git a/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90 b/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90
index c49f6f06c60e..1c7c3e4a8b09 100644
--- a/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90
+++ b/flang/test/Lower/PowerPC/ppc-pwr10-vec-intrinsics.f90
@@ -28,9 +28,9 @@
!CHECK-LABEL: @test_cvspbf16_
!LLVMIR: %1 = alloca <16 x i8>, i64 1, align 16
!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = load <16 x i8>, ptr %2, align 16
+!LLVMIR: %3 = load <16 x i8>, ptr %1, align 16
!LLVMIR: %4 = call <16 x i8> @llvm.ppc.vsx.xvcvspbf16(<16 x i8> %3)
-!LLVMIR: store <16 x i8> %4, ptr %1, align 16
+!LLVMIR: store <16 x i8> %4, ptr %2, align 16
subroutine test_cvbf16spn()
implicit none
@@ -41,9 +41,9 @@
!CHECK-LABEL: @test_cvbf16spn_
!LLVMIR: %1 = alloca <16 x i8>, i64 1, align 16
!LLVMIR: %2 = alloca <16 x i8>, i64 1, align 16
-!LLVMIR: %3 = load <16 x i8>, ptr %2, align 16
+!LLVMIR: %3 = load <16 x i8>, ptr %1, align 16
!LLVMIR: %4 = call <16 x i8> @llvm.ppc.vsx.xvcvbf16spn(<16 x i8> %3)
-!LLVMIR: store <16 x i8> %4, ptr %1, align 16
+!LLVMIR: store <16 x i8> %4, ptr %2, align 16
!----------------------
! vec_lxvp
diff --git a/flang/test/Lower/PowerPC/ppc-vector-types.f90 b/flang/test/Lower/PowerPC/ppc-vector-types.f90
index 4745e4567b2d..92c8130222b8 100644
--- a/flang/test/Lower/PowerPC/ppc-vector-types.f90
+++ b/flang/test/Lower/PowerPC/ppc-vector-types.f90
@@ -5,20 +5,20 @@
program ppc_vec_unit
implicit none
- ! CHECK-LLVM-DAG: %[[VI1:.*]] = alloca <4 x i32>, i64 1, align 16
! CHECK-LLVM-DAG: %[[VI2:.*]] = alloca <4 x i32>, i64 1, align 16
+ ! CHECK-LLVM-DAG: %[[VI1:.*]] = alloca <4 x i32>, i64 1, align 16
vector(integer(4)) :: vi1, vi2
- ! CHECK-LLVM-DAG: %[[VR1:.*]] = alloca <2 x double>, i64 1, align 16
! CHECK-LLVM-DAG: %[[VR2:.*]] = alloca <2 x double>, i64 1, align 16
+ ! CHECK-LLVM-DAG: %[[VR1:.*]] = alloca <2 x double>, i64 1, align 16
vector(real(8)) :: vr1, vr2
- ! CHECK-LLVM-DAG: %[[VU1:.*]] = alloca <8 x i16>, i64 1, align 16
! CHECK-LLVM-DAG: %[[VU2:.*]] = alloca <8 x i16>, i64 1, align 16
+ ! CHECK-LLVM-DAG: %[[VU1:.*]] = alloca <8 x i16>, i64 1, align 16
vector(unsigned(2)) :: vu1, vu2
- ! CHECK-LLVM-DAG: %[[VP1:.*]] = alloca <256 x i1>, i64 1, align 32
! CHECK-LLVM-DAG: %[[VP2:.*]] = alloca <256 x i1>, i64 1, align 32
+ ! CHECK-LLVM-DAG: %[[VP1:.*]] = alloca <256 x i1>, i64 1, align 32
__vector_pair :: vp1, vp2
__vector_quad :: vq1, vq2
diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index 304eb083e270..253db7f05a6b 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -33,12 +33,12 @@ subroutine test_assumed_shape_to_array(x)
! Copy-out
! CHECK-DAG: %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
! CHECK-DAG: %[[temp_box:.*]] = fir.embox %[[addr]](%[[shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[rebox:.*]] = fir.rebox %[[temp_box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: fir.store %[[rebox]] to %[[temp_box_ref:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK-DAG: fir.store %[[x]] to %[[arg_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK-DAG: %[[skipToInit:.*]] = arith.constant true
! CHECK-DAG: %[[arg_box_addr:.*]] = fir.convert %[[arg_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
-! CHECK-DAG: %[[temp_box_cast:.*]] = fir.convert %[[temp_box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK-DAG: fir.call @_FortranACopyOutAssign(%[[arg_box_addr]], %[[temp_box_cast]], %[[skipToInit]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.ref<i8>, i32) -> none
-! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
+! CHECK-DAG: %[[temp_box_cast:.*]] = fir.convert %[[temp_box_ref]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK-DAG: fir.call @_FortranACopyOutAssign(%[[arg_box_addr]], %[[temp_box_cast]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> none
call bar(x)
end subroutine
@@ -69,7 +69,6 @@ subroutine eval_expr_only_once(x)
! CHECK: fir.call @_FortranACopyOutAssign
! CHECK-NOT: fir.call @_QPonly_once()
-! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
end subroutine
! Test no copy-in/copy-out is generated for contiguous assumed shapes.
@@ -97,7 +96,6 @@ subroutine test_parenthesis(x)
! CHECK: fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
call bar((x))
! CHECK-NOT: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[temp]] : !fir.heap<!fir.array<?xf32>>
! CHECK: return
end subroutine
@@ -125,7 +123,6 @@ subroutine test_intent_out(x)
! CHECK: fir.if %[[not_contiguous]]
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
! CHECK: return
end subroutine
@@ -155,8 +152,8 @@ subroutine test_intent_in(x)
! CHECK: fir.call @_QPbar_intent_in(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
call bar_intent_in(x)
! CHECK: fir.if %[[not_contiguous]]
-! CHECK-NOT: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
+! CHECK: fir.zero
+! CHECK: fir.call @_FortranACopyOutAssign
! CHECK: return
end subroutine
@@ -183,7 +180,6 @@ subroutine test_intent_inout(x)
call bar_intent_inout(x)
! CHECK: fir.if %[[not_contiguous]]
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
! CHECK: return
end subroutine
@@ -221,12 +217,12 @@ subroutine test_char(x)
! CHECK: fir.if %[[VAL_22]] {
! CHECK: %[[VAL_26:.*]] = fir.shape %[[VAL_20]]#1 : (index) -> !fir.shape<1>
! CHECK: %[[VAL_27:.*]] = fir.embox %[[VAL_24]](%[[VAL_26]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,10>>>
+! CHECK: %[[REBOX:.*]] = fir.rebox %[[VAL_27]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>
+! CHECK: fir.store %[[REBOX]] to %[[TMP_BOX_REF:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
! CHECK: fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>
-! CHECK: %[[VAL_30:.*]] = arith.constant true
! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_27]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<none>
-! CHECK: %[[VAL_34:.*]] = fir.call @_FortranACopyOutAssign(%[[VAL_31]], %[[VAL_32]], %[[VAL_30]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.ref<i8>, i32) -> none
-! CHECK: fir.freemem %[[VAL_24]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
+! CHECK: %[[VAL_32:.*]] = fir.convert %[[TMP_BOX_REF]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %[[VAL_34:.*]] = fir.call @_FortranACopyOutAssign(%[[VAL_31]], %[[VAL_32]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> none
! CHECK: }
character(10) :: x(:)
diff --git a/flang/test/Lower/character-local-variables.f90 b/flang/test/Lower/character-local-variables.f90
index 0cf61a2623c4..d5b959eca1ff 100644
--- a/flang/test/Lower/character-local-variables.f90
+++ b/flang/test/Lower/character-local-variables.f90
@@ -1,4 +1,6 @@
! RUN: bbc -hlfir=false %s -o - | FileCheck %s
+! RUN: bbc -hlfir=false --enable-constant-argument-globalisation %s -o - \
+! RUN: | FileCheck %s --check-prefix=CHECK-CONST
! Test lowering of local character variables
@@ -118,7 +120,8 @@ subroutine assumed_length_param(n)
integer :: n
! CHECK: %[[c4:.*]] = arith.constant 4 : i64
! CHECK: fir.store %[[c4]] to %[[tmp:.*]] : !fir.ref<i64>
- ! CHECK: fir.call @_QPtake_int(%[[tmp]]) {{.*}}: (!fir.ref<i64>) -> ()
+ ! CHECK-CONST: %[[tmp:.*]] = fir.address_of(@_global_const_.{{.*}}) : !fir.ref<i64>
+ ! CHECK-CONST: fir.call @_QPtake_int(%[[tmp]]) {{.*}}: (!fir.ref<i64>) -> ()
call take_int(len(c(n), kind=8))
end
diff --git a/flang/test/Lower/dummy-argument-assumed-shape-optional.f90 b/flang/test/Lower/dummy-argument-assumed-shape-optional.f90
index dfd40acf9ee1..5e52459a2430 100644
--- a/flang/test/Lower/dummy-argument-assumed-shape-optional.f90
+++ b/flang/test/Lower/dummy-argument-assumed-shape-optional.f90
@@ -41,7 +41,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous(%[[VAL_25]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_23]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_3]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
@@ -86,7 +85,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous(%[[VAL_25]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_23]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_3]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
@@ -132,7 +130,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_25]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_23]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_3]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
@@ -192,7 +189,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_38]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_33]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_9]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
@@ -255,7 +251,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_41]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_36]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_11]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
@@ -324,7 +319,6 @@ end subroutine
! CHECK: fir.call @_QPtakes_contiguous_optional(%[[VAL_41]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: fir.if %[[VAL_36]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_11]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
! CHECK: return
! CHECK:}
diff --git a/flang/test/Lower/dummy-argument-optional-2.f90 b/flang/test/Lower/dummy-argument-optional-2.f90
index 1fc7a87c6f3f..cc026132bd08 100644
--- a/flang/test/Lower/dummy-argument-optional-2.f90
+++ b/flang/test/Lower/dummy-argument-optional-2.f90
@@ -121,7 +121,6 @@ subroutine pass_pointer_array(i)
! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_29]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_9]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
end subroutine
@@ -157,7 +156,6 @@ subroutine pass_pointer_array_char(c)
! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_52]]) {{.*}}: (!fir.boxchar<1>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_9]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
! CHECK: }
! CHECK: return
! CHECK: }
@@ -192,7 +190,6 @@ subroutine forward_pointer_array()
! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_14]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_7]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
end subroutine
@@ -231,7 +228,6 @@ subroutine pass_opt_assumed_shape(x)
! CHECK: fir.call @_QPtakes_opt_explicit_shape(%[[VAL_26]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_27]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
end subroutine
@@ -270,7 +266,6 @@ subroutine pass_opt_assumed_shape_char(c)
! CHECK: fir.call @_QPtakes_opt_explicit_shape_char(%[[VAL_50]]) {{.*}}: (!fir.boxchar<1>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_49]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
! CHECK: }
end subroutine
@@ -403,8 +398,8 @@ subroutine pass_opt_assumed_shape_to_intentin(x)
! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_7]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentin(%[[VAL_24]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
! CHECK: fir.if %[[and]] {
-! CHECK-NOT: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_7]] : !fir.heap<!fir.array<?xf32>>
+! CHECK: fir.zero
+! CHECK: fir.call @_FortranACopyOutAssign
! CHECK: }
end subroutine
@@ -435,7 +430,6 @@ subroutine pass_opt_assumed_shape_to_intentout(x)
! CHECK: fir.call @_QPtakes_opt_explicit_shape_intentout(%[[VAL_14]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
! CHECK: fir.if %[[and]] {
! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_7]] : !fir.heap<!fir.array<?xf32>>
! CHECK: }
end subroutine
end module
diff --git a/flang/test/Lower/func-attrs.f90 b/flang/test/Lower/func-attrs.f90
new file mode 100644
index 000000000000..7ab549a0ac7c
--- /dev/null
+++ b/flang/test/Lower/func-attrs.f90
@@ -0,0 +1,31 @@
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+
+pure subroutine sub1()
+end
+
+! CHECK: func.func @_QPsub1() attributes {fir.func_pure}
+
+elemental subroutine sub2()
+end
+
+! CHECK: func.func @_QPsub2() attributes {fir.func_elemental, fir.func_pure}
+
+recursive subroutine sub3()
+end
+
+! CHECK: func.func @_QPsub3() attributes {fir.func_recursive}
+
+pure function fct1()
+end
+
+! CHECK: func.func @_QPfct1() -> f32 attributes {fir.func_pure}
+
+elemental function fct2()
+end
+
+! CHECK: func.func @_QPfct2() -> f32 attributes {fir.func_elemental, fir.func_pure}
+
+recursive function fct3()
+end
+
+! CHECK: func.func @_QPfct3() -> f32 attributes {fir.func_recursive}
diff --git a/flang/test/Lower/host-associated.f90 b/flang/test/Lower/host-associated.f90
index cdc7e6a05288..b0195108238d 100644
--- a/flang/test/Lower/host-associated.f90
+++ b/flang/test/Lower/host-associated.f90
@@ -309,7 +309,7 @@ subroutine test7(j, k)
contains
! CHECK-LABEL: func private @_QFtest7Ptest7_inner(
-! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
+! CHECK-SAME: %[[i:.*]]: !fir.ref<i32>{{.*}}, %[[tup:.*]]: !fir.ref<tuple<!fir.ref<i32>>> {fir.host_assoc}) -> i32 attributes {fir.func_elemental, fir.func_pure, fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
elemental integer function test7_inner(i)
implicit none
integer, intent(in) :: i
diff --git a/flang/test/Lower/loops3.f90 b/flang/test/Lower/loops3.f90
new file mode 100644
index 000000000000..78f39e101308
--- /dev/null
+++ b/flang/test/Lower/loops3.f90
@@ -0,0 +1,23 @@
+! Test do concurrent reduction
+! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s
+
+! CHECK-LABEL: loop_test
+subroutine loop_test
+ integer(4) :: i, j, k, tmp, sum = 0
+ real :: m
+
+ i = 100
+ j = 200
+ k = 300
+
+ ! CHECK: %[[VAL_0:.*]] = fir.alloca f32 {bindc_name = "m", uniq_name = "_QFloop_testEm"}
+ ! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFloop_testEsum) : !fir.ref<i32>
+ ! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered reduce(#fir.reduce_attr<add> -> %[[VAL_1:.*]] : !fir.ref<i32>, #fir.reduce_attr<max> -> %[[VAL_0:.*]] : !fir.ref<f32>) {
+ ! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered reduce(#fir.reduce_attr<add> -> %[[VAL_1:.*]] : !fir.ref<i32>, #fir.reduce_attr<max> -> %[[VAL_0:.*]] : !fir.ref<f32>) {
+ ! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered reduce(#fir.reduce_attr<add> -> %[[VAL_1:.*]] : !fir.ref<i32>, #fir.reduce_attr<max> -> %[[VAL_0:.*]] : !fir.ref<f32>) {
+ do concurrent (i=1:5, j=1:5, k=1:5) local(tmp) reduce(+:sum) reduce(max:m)
+ tmp = i + j + k
+ sum = tmp + sum
+ m = max(m, sum)
+ enddo
+end subroutine loop_test
diff --git a/flang/test/Lower/optional-value-caller.f90 b/flang/test/Lower/optional-value-caller.f90
index a1e6ebf3e218..31bf326dd1df 100644
--- a/flang/test/Lower/optional-value-caller.f90
+++ b/flang/test/Lower/optional-value-caller.f90
@@ -298,8 +298,8 @@ subroutine test_dyn_array_from_assumed(i, n)
! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_8]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
! CHECK: fir.call @_QPdyn_array(%[[VAL_25]], %[[VAL_1]]) {{.*}}: (!fir.ref<!fir.array<?xi32>>, !fir.ref<i64>) -> ()
! CHECK: fir.if %[[and]] {
-! CHECK-NOT: fir.call @_FortranACopyOutAssign
-! CHECK: fir.freemem %[[VAL_8]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.zero
+! CHECK: fir.call @_FortranACopyOutAssign
! CHECK: }
end subroutine
@@ -347,7 +347,8 @@ subroutine test_array_ptr(i)
! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_30:.*]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<100xi32>>
! CHECK: fir.call @_QParray(%[[VAL_29]]) fastmath<contract> : (!fir.ref<!fir.array<100xi32>>) -> ()
! CHECK: fir.if %[[VAL_28]] {
-! CHECK: fir.freemem %[[VAL_30]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.zero
+! CHECK: fir.call @_FortranACopyOutAssign
! CHECK: }
! CHECK: return
! CHECK: }
@@ -455,7 +456,8 @@ subroutine test_char_array(c)
! CHECK: %[[VAL_35:.*]] = fir.emboxchar %[[VAL_33]], %[[VAL_29]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
! CHECK: fir.call @_QPdyn_char_array(%[[VAL_35]], %[[VAL_2]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i64>) -> ()
! CHECK: fir.if %[[VAL_32]] {
-! CHECK: fir.freemem %[[VAL_34]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
+! CHECK: fir.zero
+! CHECK: fir.call @_FortranACopyOutAssign
! CHECK: }
! CHECK: return
! CHECK: }
diff --git a/flang/test/Lower/pre-fir-tree09.f90 b/flang/test/Lower/pre-fir-tree09.f90
new file mode 100644
index 000000000000..15d7672725ab
--- /dev/null
+++ b/flang/test/Lower/pre-fir-tree09.f90
@@ -0,0 +1,100 @@
+! RUN: bbc -pft-test -o %t %s | FileCheck %s
+
+module mm
+ !dir$ some directive 1
+ type t
+ logical :: tag
+ contains
+ final :: fin
+ end type
+ !dir$ some directive 2
+
+contains
+ !dir$ some directive 3
+ subroutine fin(x)
+ type(t), intent(inout) :: x
+ x%tag =.true.
+ !dir$ some directive 4
+ call s1
+ call s2
+ print*, 'fin', x
+
+ contains
+ !dir$ some directive 5
+ subroutine s1
+ print*, 's1'
+ !dir$ some directive 6
+ end subroutine s1
+
+ !dir$ some directive 7
+ subroutine s2
+ !dir$ some directive 8
+ if (.true.) then
+ !dir$ some directive 9
+ print*, 's2'
+ !dir$ some directive 10
+ endif
+ !dir$ some directive 11
+ end subroutine s2
+ !dir$ some directive 12
+ end subroutine fin
+ !dir$ some directive 13
+end module mm
+!dir$ some directive 14
+
+end
+
+! CHECK: Module mm: module mm
+! CHECK: CompilerDirective: !some directive 1
+! CHECK: CompilerDirective: !some directive 2
+
+! CHECK: Contains
+! CHECK: CompilerDirective: !some directive 3
+
+! CHECK: Subroutine fin: subroutine fin(x)
+! CHECK: AssignmentStmt: x%tag =.true.
+! CHECK: CompilerDirective: !some directive 4
+! CHECK: CallStmt: call s1
+! CHECK: CallStmt: call s2
+! CHECK: PrintStmt: print*, 'fin', x
+! CHECK: EndSubroutineStmt: end subroutine fin
+
+! CHECK: Contains
+! CHECK: CompilerDirective: !some directive 5
+
+! CHECK: Subroutine s1: subroutine s1
+! CHECK: PrintStmt: print*, 's1'
+! CHECK: CompilerDirective: !some directive 6
+! CHECK: EndSubroutineStmt: end subroutine s1
+! CHECK: End Subroutine s1
+
+! CHECK: CompilerDirective: !some directive 7
+
+! CHECK: Subroutine s2: subroutine s2
+! CHECK: CompilerDirective: !some directive 8
+! CHECK: <<IfConstruct>> -> 7
+! CHECK: IfThenStmt -> 7: if(.true.) then
+! CHECK: ^CompilerDirective: !some directive 9
+! CHECK: PrintStmt: print*, 's2'
+! CHECK: CompilerDirective: !some directive 10
+! CHECK: EndIfStmt: endif
+! CHECK: <<End IfConstruct>>
+! CHECK: CompilerDirective: !some directive 11
+! CHECK: EndSubroutineStmt: end subroutine s2
+! CHECK: End Subroutine s2
+
+! CHECK: CompilerDirective: !some directive 12
+
+! CHECK: End Contains
+! CHECK: End Subroutine fin
+
+! CHECK: CompilerDirective: !some directive 13
+
+! CHECK: End Contains
+! CHECK: End Module mm
+
+! CHECK: CompilerDirective: !some directive 14
+
+! CHECK: Program <anonymous>
+! CHECK: EndProgramStmt: end
+! CHECK: End Program <anonymous>
diff --git a/flang/test/Lower/vector-always.f90 b/flang/test/Lower/vector-always.f90
new file mode 100644
index 000000000000..1822fc33dfdb
--- /dev/null
+++ b/flang/test/Lower/vector-always.f90
@@ -0,0 +1,26 @@
+! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
+
+! CHECK: #loop_vectorize = #llvm.loop_vectorize<disable = false>
+! CHECK: #loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize>
+
+! CHECK-LABEL: vector_always
+subroutine vector_always
+ integer :: a(10)
+ !dir$ vector always
+ !CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
+ do i=1,10
+ a(i)=i
+ end do
+end subroutine vector_always
+
+
+! CHECK-LABEL: intermediate_directive
+subroutine intermediate_directive
+ integer :: a(10)
+ !dir$ vector always
+ !dir$ unknown
+ !CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
+ do i=1,10
+ a(i)=i
+ end do
+end subroutine intermediate_directive
diff --git a/flang/test/Parser/OpenMP/target-loop-unparse.f90 b/flang/test/Parser/OpenMP/target-loop-unparse.f90
new file mode 100644
index 000000000000..3ee2fcef075a
--- /dev/null
+++ b/flang/test/Parser/OpenMP/target-loop-unparse.f90
@@ -0,0 +1,53 @@
+
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+! Check for parsing of loop directive
+
+subroutine test_loop
+ integer :: i, j = 1
+ !PARSE-TREE: OmpBeginLoopDirective
+ !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = loop
+ !CHECK: !$omp loop
+ !$omp loop
+ do i=1,10
+ j = j + 1
+ end do
+ !$omp end loop
+end subroutine
+
+subroutine test_target_loop
+ integer :: i, j = 1
+ !PARSE-TREE: OmpBeginLoopDirective
+ !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target loop
+ !CHECK: !$omp target loop
+ !$omp target loop
+ do i=1,10
+ j = j + 1
+ end do
+ !$omp end target loop
+end subroutine
+
+subroutine test_target_teams_loop
+ integer :: i, j = 1
+ !PARSE-TREE: OmpBeginLoopDirective
+ !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams loop
+ !CHECK: !$omp target teams loop
+ !$omp target teams loop
+ do i=1,10
+ j = j + 1
+ end do
+ !$omp end target teams loop
+end subroutine
+
+subroutine test_target_parallel_loop
+ integer :: i, j = 1
+ !PARSE-TREE: OmpBeginLoopDirective
+ !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel loop
+ !CHECK: !$omp target parallel loop
+ !$omp target parallel loop
+ do i=1,10
+ j = j + 1
+ end do
+ !$omp end target parallel loop
+end subroutine
diff --git a/flang/test/Parser/compiler-directives.f90 b/flang/test/Parser/compiler-directives.f90
index d4c99ae12f14..246eaf985251 100644
--- a/flang/test/Parser/compiler-directives.f90
+++ b/flang/test/Parser/compiler-directives.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fdebug-unparse %s 2>&1
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
! Test that compiler directives can appear in various places.
@@ -28,3 +28,10 @@ module m
!dir$ align : 1024 :: d
end type stuff
end
+
+subroutine vector_always
+ !dir$ vector always
+ ! CHECK: !DIR$ VECTOR ALWAYS
+ do i=1,10
+ enddo
+end subroutine
diff --git a/flang/test/Parser/recovery01.f90 b/flang/test/Parser/recovery01.f90
new file mode 100644
index 000000000000..674abaccc7c7
--- /dev/null
+++ b/flang/test/Parser/recovery01.f90
@@ -0,0 +1,10 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+program main
+ call foo(i, &
+ j, &
+ k, &
+ 1$)
+end
+
+!CHECK: error: expected ')'
+!CHECK: in the context: CALL statement
diff --git a/flang/test/Parser/recovery02.f90 b/flang/test/Parser/recovery02.f90
new file mode 100644
index 000000000000..0d0d15545cf3
--- /dev/null
+++ b/flang/test/Parser/recovery02.f90
@@ -0,0 +1,8 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+continue ! force executable part
+CALL ADD_HASH_BLOCK(d_c,f_c,dimc, &
+ (h2b-1+noab*(h1b-1+noab*(p4b-noab-1+nvab*(p3b-noab-1$)))))
+end
+
+!CHECK: error: expected ')'
+!CHECK: in the context: CALL statement
diff --git a/flang/test/Preprocessing/cond-contin.F90 b/flang/test/Preprocessing/cond-contin.F90
new file mode 100644
index 000000000000..9221e34e013f
--- /dev/null
+++ b/flang/test/Preprocessing/cond-contin.F90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s
+! CHECK: subroutine test(ARG1, FA, FB, ARG2)
+! CHECK: end
+
+subroutine test( &
+ARG1, &
+! test
+#ifndef SWAP
+#define ARG1 FA
+#define ARG2 FB
+#else
+#define ARG1 FB
+#define ARG2 FA
+#endif
+ARG1, ARG2, &
+! test
+#undef ARG1
+#undef ARG2
+&ARG2)
+! comment
+end
diff --git a/flang/test/Preprocessing/directive-contin-with-pp.F90 b/flang/test/Preprocessing/directive-contin-with-pp.F90
index 9a06ae843821..64f1dc43f72b 100644
--- a/flang/test/Preprocessing/directive-contin-with-pp.F90
+++ b/flang/test/Preprocessing/directive-contin-with-pp.F90
@@ -1,12 +1,17 @@
-! RUN: %flang -E %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s 2>&1 | FileCheck %s
#define DIR_START !dir$
#define DIR_CONT !dir$&
#define FIRST(x) DIR_START x
#define NEXT(x) DIR_CONT x
#define AMPER &
+#define COMMENT !
+#define OMP_START !$omp
+#define OMP_CONT !$omp&
-subroutine s(x1, x2, x3, x4, x5, x6, x7)
+module m
+ contains
+ subroutine s(x1, x2, x3, x4, x5, x6, x7)
!dir$ ignore_tkr x1
@@ -24,18 +29,48 @@ FIRST(ignore_tkr &)
FIRST(ignore_tkr &)
NEXT(x6)
-FIRST(ignore_tkr &)
-NEXT(x7 &)
-NEXT(x8)
+COMMENT blah &
+COMMENT & more
+ stop 1
+
+OMP_START parallel &
+OMP_START do &
+OMP_START reduction(+:x)
+ do j1 = 1, n
+ end do
+
+OMP_START parallel &
+OMP_START & do &
+OMP_START & reduction(+:x)
+ do j2 = 1, n
+ end do
+OMP_START parallel &
+OMP_CONT do &
+OMP_CONT reduction(+:x)
+ do j3 = 1, n
+ end do
+ end
end
-!CHECK: subroutine s(x1, x2, x3, x4, x5, x6, x7)
-!CHECK: !dir$ ignore_tkr x1
-!CHECK: !dir$ ignore_tkr x2
-!CHECK: !dir$ ignore_tkr x3
-!CHECK: !dir$ ignore_tkr x4
-!CHECK: !dir$ ignore_tkr x5
-!CHECK: !dir$ ignore_tkr x6
-!CHECK: !dir$ ignore_tkr x7 x8
-!CHECK: end
+!CHECK: MODULE m
+!CHECK: CONTAINS
+!CHECK: SUBROUTINE s (x1, x2, x3, x4, x5, x6, x7)
+!CHECK: !DIR$ IGNORE_TKR x1
+!CHECK: !DIR$ IGNORE_TKR x2
+!CHECK: !DIR$ IGNORE_TKR x3
+!CHECK: !DIR$ IGNORE_TKR x4
+!CHECK: !DIR$ IGNORE_TKR x5
+!CHECK: !DIR$ IGNORE_TKR x6
+!CHECK: STOP 1_4
+!CHECK: !$OMP PARALLEL DO REDUCTION(+:x)
+!CHECK: DO j1=1_4,n
+!CHECK: END DO
+!CHECK: !$OMP PARALLEL DO REDUCTION(+:x)
+!CHECK: DO j2=1_4,n
+!CHECK: END DO
+!CHECK: !$OMP PARALLEL DO REDUCTION(+:x)
+!CHECK: DO j3=1_4,n
+!CHECK: END DO
+!CHECK: END SUBROUTINE
+!CHECK: END MODULE
diff --git a/flang/test/Preprocessing/ff-args.h b/flang/test/Preprocessing/ff-args.h
new file mode 100644
index 000000000000..99562784006c
--- /dev/null
+++ b/flang/test/Preprocessing/ff-args.h
@@ -0,0 +1 @@
+ +3.14159) \ No newline at end of file
diff --git a/flang/test/Preprocessing/ff-include-args.F b/flang/test/Preprocessing/ff-include-args.F
new file mode 100644
index 000000000000..81e4102598c2
--- /dev/null
+++ b/flang/test/Preprocessing/ff-include-args.F
@@ -0,0 +1,14 @@
+! RUN: %flang -E %s 2>&1 | FileCheck %s
+! CHECK: call foo ( 3.14159)
+! CHECK: subroutine foo(test)
+ call foo (
+#include "ff-args.h"
+ end
+#define TEST
+ subroutine foo(
+#ifdef TEST
+ +test)
+#else
+ +)
+#endif
+ end
diff --git a/flang/test/Preprocessing/inc-contin-1.F b/flang/test/Preprocessing/inc-contin-1.F
new file mode 100644
index 000000000000..7a4e3a0cb0b5
--- /dev/null
+++ b/flang/test/Preprocessing/inc-contin-1.F
@@ -0,0 +1,6 @@
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s
+! CHECK: call t(1 ,.false.)
+ program main
+#include "inc-contin-1.h"
+ $,.false.)
+ end
diff --git a/flang/test/Preprocessing/inc-contin-1.h b/flang/test/Preprocessing/inc-contin-1.h
new file mode 100644
index 000000000000..d4b6461e7527
--- /dev/null
+++ b/flang/test/Preprocessing/inc-contin-1.h
@@ -0,0 +1 @@
+ call t(1
diff --git a/flang/test/Preprocessing/inc-contin-2.F90 b/flang/test/Preprocessing/inc-contin-2.F90
new file mode 100644
index 000000000000..3386ee0dfcdd
--- /dev/null
+++ b/flang/test/Preprocessing/inc-contin-2.F90
@@ -0,0 +1,9 @@
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s
+! CHECK: print *, 3.14159
+! CHECK: print *, 3. 14159
+ program main
+#include "inc-contin-2a.h"
+ &14159
+#include "inc-contin-2b.h"
+ &14159
+ end program main
diff --git a/flang/test/Preprocessing/inc-contin-2a.h b/flang/test/Preprocessing/inc-contin-2a.h
new file mode 100644
index 000000000000..24a4fa4830fa
--- /dev/null
+++ b/flang/test/Preprocessing/inc-contin-2a.h
@@ -0,0 +1 @@
+print *, 3.&
diff --git a/flang/test/Preprocessing/inc-contin-2b.h b/flang/test/Preprocessing/inc-contin-2b.h
new file mode 100644
index 000000000000..b84a464af86e
--- /dev/null
+++ b/flang/test/Preprocessing/inc-contin-2b.h
@@ -0,0 +1 @@
+print *, 3. &
diff --git a/flang/test/Preprocessing/include-args.F90 b/flang/test/Preprocessing/include-args.F90
index 011e4dba13e7..7c521db666ff 100644
--- a/flang/test/Preprocessing/include-args.F90
+++ b/flang/test/Preprocessing/include-args.F90
@@ -1,5 +1,5 @@
! RUN: %flang -E %s 2>&1 | FileCheck %s
-! CHECK: call foo(3.14159)
+! CHECK: call foo(3.14159 )
call foo (&
#include "args.h"
)
diff --git a/flang/test/Preprocessing/multi-cont.F90 b/flang/test/Preprocessing/multi-cont.F90
new file mode 100644
index 000000000000..5a2c0b9c4797
--- /dev/null
+++ b/flang/test/Preprocessing/multi-cont.F90
@@ -0,0 +1,6 @@
+! RUN: %flang -E %s 2>&1 | FileCheck --strict-whitespace %s
+! CHECK: print *, 666
+pr&
+&i&
+&nt *, 666
+end
diff --git a/flang/test/Semantics/OpenMP/reduction09.f90 b/flang/test/Semantics/OpenMP/reduction09.f90
index 095b49ba0c40..dbc8d1b060e6 100644
--- a/flang/test/Semantics/OpenMP/reduction09.f90
+++ b/flang/test/Semantics/OpenMP/reduction09.f90
@@ -73,14 +73,4 @@ program omp_reduction
k = k+1
end do
!$omp end do
-
-
- !$omp do reduction(.and.:k) reduction(.or.:j) reduction(.eqv.:l)
- !DEF: /omp_reduction/OtherConstruct8/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
- do i=1,10
- !DEF: /omp_reduction/OtherConstruct8/k (OmpReduction) HostAssoc INTEGER(4)
- k = k+1
- end do
- !$omp end do
-
end program omp_reduction
diff --git a/flang/test/Semantics/OpenMP/reduction14.f90 b/flang/test/Semantics/OpenMP/reduction14.f90
new file mode 100644
index 000000000000..7d3f8d468f76
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/reduction14.f90
@@ -0,0 +1,97 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_reduction
+ integer :: i
+ real :: r
+ character :: c
+ complex :: z
+ logical :: l
+
+ ! * is allowed for integer, real, and complex
+ ! but not for logical or character
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(*:i,r,c,z,l)
+ !$omp end parallel
+
+ ! + is allowed for integer, real, and complex
+ ! but not for logical or character
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(+:i,r,c,z,l)
+ !$omp end parallel
+
+ ! - is deprecated for all types
+ ! ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ !$omp parallel reduction(-:i,r,c,z,l)
+ !$omp end parallel
+
+ ! .and. is only supported for logical operations
+ ! ERROR: The type of 'i' is incompatible with the reduction operator.
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ !$omp parallel reduction(.and.:i,r,c,z,l)
+ !$omp end parallel
+
+ ! .or. is only supported for logical operations
+ ! ERROR: The type of 'i' is incompatible with the reduction operator.
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ !$omp parallel reduction(.or.:i,r,c,z,l)
+ !$omp end parallel
+
+ ! .eqv. is only supported for logical operations
+ ! ERROR: The type of 'i' is incompatible with the reduction operator.
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ !$omp parallel reduction(.eqv.:i,r,c,z,l)
+ !$omp end parallel
+
+ ! .neqv. is only supported for logical operations
+ ! ERROR: The type of 'i' is incompatible with the reduction operator.
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ !$omp parallel reduction(.neqv.:i,r,c,z,l)
+ !$omp end parallel
+
+ ! iand only supports integers
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(iand:i,r,c,z,l)
+ !$omp end parallel
+
+ ! ior only supports integers
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(ior:i,r,c,z,l)
+ !$omp end parallel
+
+ ! ieor only supports integers
+ ! ERROR: The type of 'r' is incompatible with the reduction operator.
+ ! ERROR: The type of 'c' is incompatible with the reduction operator.
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(ieor:i,r,c,z,l)
+ !$omp end parallel
+
+ ! max arguments may be integer, real, or character:
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(max:i,r,c,z,l)
+ !$omp end parallel
+
+ ! min arguments may be integer, real, or character:
+ ! ERROR: The type of 'z' is incompatible with the reduction operator.
+ ! ERROR: The type of 'l' is incompatible with the reduction operator.
+ !$omp parallel reduction(min:i,r,c,z,l)
+ !$omp end parallel
+end program omp_reduction
diff --git a/flang/test/Semantics/bind-c15.f90 b/flang/test/Semantics/bind-c15.f90
index 9aaad52cc0e0..82a3cbef791e 100644
--- a/flang/test/Semantics/bind-c15.f90
+++ b/flang/test/Semantics/bind-c15.f90
@@ -16,6 +16,13 @@ module m
type :: non_interoperable2
type(non_interoperable1) b
end type
+ type :: no_bind_c
+ real a
+ end type
+ type, bind(c) :: has_bind_c
+ !WARNING: Derived type of component 'a' of an interoperable derived type should have the BIND attribute
+ type(no_bind_c) :: a
+ end type
interface
subroutine sub_bind_c_1(x_bind_c) bind(c)
import explicit_bind_c
diff --git a/flang/test/Semantics/bind-c16.f90 b/flang/test/Semantics/bind-c16.f90
index b9dfb03e35ee..77c1a9160889 100644
--- a/flang/test/Semantics/bind-c16.f90
+++ b/flang/test/Semantics/bind-c16.f90
@@ -84,3 +84,8 @@ module m3
end
end interface
end
+
+!CHECK: cdef01, BIND(C), PUBLIC size=4 offset=0: ObjectEntity type: REAL(4) bindName:cDef01 CDEFINED
+module m4
+ real, bind(c, name='cDef01', cdefined) :: cdef01
+end
diff --git a/flang/test/Semantics/c_loc01.f90 b/flang/test/Semantics/c_loc01.f90
index 7c9e29417299..83b88d2ebd4b 100644
--- a/flang/test/Semantics/c_loc01.f90
+++ b/flang/test/Semantics/c_loc01.f90
@@ -4,7 +4,10 @@ module m
type haslen(L)
integer, len :: L
end type
+ integer, target :: targ
contains
+ subroutine subr
+ end
subroutine test(assumedType, poly, nclen)
type(*), target :: assumedType
class(*), target :: poly
@@ -17,6 +20,8 @@ module m
type(hasLen(1)), target :: clen
type(hasLen(*)), target :: nclen
character(2), target :: ch
+ real :: arr1(purefun1(c_loc(targ))) ! ok
+ real :: arr2(purefun2(c_funloc(subr))) ! ok
!ERROR: C_LOC() argument must be a data pointer or target
cp = c_loc(notATarget)
!ERROR: C_LOC() argument must be a data pointer or target
@@ -44,4 +49,12 @@ module m
!ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types TYPE(c_funptr) and TYPE(c_ptr)
cfp = cp
end
+ pure integer function purefun1(p)
+ type(c_ptr), intent(in) :: p
+ purefun1 = 1
+ end
+ pure integer function purefun2(p)
+ type(c_funptr), intent(in) :: p
+ purefun2 = 1
+ end
end module
diff --git a/flang/test/Semantics/call05.f90 b/flang/test/Semantics/call05.f90
index 71f2197067f7..8a4386e28e2b 100644
--- a/flang/test/Semantics/call05.f90
+++ b/flang/test/Semantics/call05.f90
@@ -123,9 +123,7 @@ end module
module m2
- !ERROR: Procedure 't3' may not be ALLOCATABLE without an explicit interface
character(len=10), allocatable :: t1, t2, t3, t4
- !ERROR: Procedure 't6' may not be ALLOCATABLE without an explicit interface
character(len=:), allocatable :: t5, t6, t7, t8(:)
character(len=10), pointer :: p1
@@ -189,7 +187,7 @@ module m2
!ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
call sma(t2(:))
- !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
+ !ERROR: 't3' is not a callable procedure
call sma(t3(1))
!ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
@@ -208,7 +206,7 @@ module m2
!ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
call sma(t5(:))
- !ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
+ !ERROR: 't6' is not a callable procedure
call sma(t6(1))
!ERROR: ALLOCATABLE dummy argument 'a=' must be associated with an ALLOCATABLE actual argument
diff --git a/flang/test/Semantics/call10.f90 b/flang/test/Semantics/call10.f90
index ff19f104b051..ffb3b48c329e 100644
--- a/flang/test/Semantics/call10.f90
+++ b/flang/test/Semantics/call10.f90
@@ -53,7 +53,7 @@ module m
real, value :: a ! ok
end function
pure real function f03(a) ! C1583
- !ERROR: non-POINTER dummy argument of pure function must have INTENT() or VALUE attribute
+ !WARNING: non-POINTER dummy argument of pure function must have INTENT() or VALUE attribute
real :: a
end function
pure real function f03a(a)
@@ -83,7 +83,7 @@ module m
end function
pure subroutine s01(a) ! C1586
- !ERROR: non-POINTER dummy argument of pure subroutine must have INTENT() or VALUE attribute
+ !WARNING: non-POINTER dummy argument of pure subroutine must have INTENT() or VALUE attribute
real :: a
end subroutine
pure subroutine s01a(a)
diff --git a/flang/test/Semantics/cuf16.cuf b/flang/test/Semantics/cuf16.cuf
new file mode 100644
index 000000000000..4a7595b47950
--- /dev/null
+++ b/flang/test/Semantics/cuf16.cuf
@@ -0,0 +1,95 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+module m
+ interface operator(-)
+ !ERROR: OPERATOR(-) function 'f1' conflicts with intrinsic operator
+ function f1(x)
+ real, intent(in) :: x
+ end
+ !ERROR: OPERATOR(-) function 'f2' conflicts with intrinsic operator
+ attributes(device) function f2(x)
+ real, intent(in), device :: x(:)
+ end
+ function f3(x) ! ok
+ real, intent(in), device :: x(:,:)
+ end
+ !ERROR: OPERATOR(-) function 'f4' conflicts with intrinsic operator
+ attributes(device) function f4(x)
+ real, intent(in) :: x(:,:,:)
+ end
+ !ERROR: OPERATOR(-) function 'f5' conflicts with intrinsic operator
+ function f5(x)
+ real, intent(in), unified :: x(:,:,:,:)
+ end
+ !ERROR: OPERATOR(-) function 'f6' conflicts with intrinsic operator
+ attributes(device) function f6(x)
+ real, intent(in), managed :: x(:,:,:,:,:)
+ end
+ end interface
+ interface operator(*)
+ !ERROR: OPERATOR(*) function 'f11' conflicts with intrinsic operator
+ function f11(x, y)
+ real, intent(in) :: x, y
+ end
+ !ERROR: OPERATOR(*) function 'f12' conflicts with intrinsic operator
+ attributes(device) function f12(x, y)
+ real, intent(in), device :: x, y(:)
+ end
+ !ERROR: OPERATOR(*) function 'f13' conflicts with intrinsic operator
+ attributes(device) function f13(x, y)
+ real, intent(in) :: x(:), y
+ end
+ function f14a(x, y) ! ok
+ real, intent(in), device :: x(:)
+ real, intent(in) :: y(:)
+ end
+ function f14b(x, y) ! ok
+ real, intent(in) :: x
+ real, intent(in), device :: y(:,:)
+ end
+ !ERROR: OPERATOR(*) function 'f15' conflicts with intrinsic operator
+ function f15(x, y)
+ real, intent(in) :: x(:,:)
+ real, intent(in), unified :: y
+ end
+ !ERROR: OPERATOR(*) function 'f16' conflicts with intrinsic operator
+ attributes(device) function f16(x, y)
+ real, intent(in), device :: x(:,:)
+ real, intent(in), managed :: y(:,:)
+ end
+ end interface
+ interface assignment(=)
+ !ERROR: Defined assignment subroutine 's1' conflicts with intrinsic assignment
+ subroutine s1(x, y)
+ real, intent(in out) :: x
+ real, intent(in) :: y
+ end
+ !ERROR: Defined assignment subroutine 's2' conflicts with intrinsic assignment
+ attributes(device) subroutine s2(x, y)
+ real, intent(in out), device :: x(:)
+ real, intent(in), device :: y
+ end
+ !ERROR: Defined assignment subroutine 's3' conflicts with intrinsic assignment
+ attributes(device) subroutine s3(x, y)
+ real, intent(in out) :: x(:)
+ real, intent(in) :: y(:)
+ end
+ subroutine s4a(x, y) ! ok
+ real, intent(in out), device :: x(:,:)
+ real, intent(in) :: y
+ end
+ subroutine s4b(x, y) ! ok
+ real, intent(in out) :: x(:,:)
+ real, intent(in), device :: y(:,:)
+ end
+ !ERROR: Defined assignment subroutine 's5' conflicts with intrinsic assignment
+ subroutine s5(x, y)
+ real, intent(in out) :: x(:,:,:)
+ real, intent(in), unified :: y
+ end
+ !ERROR: Defined assignment subroutine 's6' conflicts with intrinsic assignment
+ attributes(device) subroutine s6(x, y)
+ real, intent(in out), device :: x(:,:,:)
+ real, intent(in), managed :: y(:,:,:)
+ end
+ end interface
+end
diff --git a/flang/test/Semantics/declarations02.f90 b/flang/test/Semantics/declarations02.f90
index f39c233c1c3a..32c3517d13cd 100644
--- a/flang/test/Semantics/declarations02.f90
+++ b/flang/test/Semantics/declarations02.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
module m
!ERROR: 'x1' may not have both the BIND(C) and PARAMETER attributes
@@ -32,14 +32,14 @@ module m
end type
!ERROR: 't1' may not have both the BIND(C) and PARAMETER attributes
- !ERROR: The derived type of a BIND(C) object must also be BIND(C)
+ !WARNING: The derived type of an interoperable object should be BIND(C)
type(my_type1), bind(c), parameter :: t1 = my_type1(1)
!ERROR: 't2' may not have both the BIND(C) and PARAMETER attributes
type(my_type2), bind(c), parameter :: t2 = my_type2(1)
type(my_type2), parameter :: t3 = my_type2(1) ! no error
!ERROR: 't4' may not have both the BIND(C) and PARAMETER attributes
- !ERROR: The derived type of a BIND(C) object must also be BIND(C)
+ !WARNING: The derived type of an interoperable object should be BIND(C)
type(my_type1), parameter :: t4 = my_type1(1)
!ERROR: 't5' may not have both the BIND(C) and PARAMETER attributes
type(my_type2), parameter :: t5 = my_type2(1)
diff --git a/flang/test/Semantics/elemental01.f90 b/flang/test/Semantics/elemental01.f90
index 6b2b25907ef6..f0e501e9d831 100644
--- a/flang/test/Semantics/elemental01.f90
+++ b/flang/test/Semantics/elemental01.f90
@@ -47,3 +47,41 @@ elemental function ptrf(n)
!ERROR: The result of an ELEMENTAL function may not be a POINTER
real, pointer :: ptrf
end function
+
+module m
+ integer modvar
+ type t
+ character(:), allocatable :: c
+ end type
+ type pdt(L)
+ integer, len :: L
+ end type
+ type container
+ class(pdt(:)), allocatable :: c
+ end type
+ contains
+ !ERROR: Invalid specification expression for elemental function result: dependence on value of dummy argument 'n'
+ elemental character(n) function bad1(n)
+ integer, intent(in) :: n
+ end
+ !ERROR: Invalid specification expression for elemental function result: non-constant inquiry function 'len' not allowed for local object
+ elemental character(x%c%len) function bad2(x)
+ type(t), intent(in) :: x
+ end
+ !ERROR: Invalid specification expression for elemental function result: non-constant type parameter inquiry not allowed for local object
+ elemental character(x%c%L) function bad3(x)
+ class(container), intent(in) :: x
+ end
+ elemental character(len(x)) function ok1(x) ! ok
+ character(*), intent(in) :: x
+ end
+ elemental character(modvar) function ok2(x) ! ok
+ character(*), intent(in) :: x
+ end
+ elemental character(len(x)) function ok3(x) ! ok
+ character(modvar), intent(in) :: x
+ end
+ elemental character(storage_size(x)) function ok4(x) ! ok
+ class(*), intent(in) :: x
+ end
+end
diff --git a/flang/test/Semantics/loop-directives.f90 b/flang/test/Semantics/loop-directives.f90
new file mode 100644
index 000000000000..6f994c767d45
--- /dev/null
+++ b/flang/test/Semantics/loop-directives.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror
+
+subroutine empty
+ ! WARNING: A DO loop must follow the VECTOR ALWAYS directive
+ !dir$ vector always
+end subroutine empty
+
+subroutine non_do
+ ! WARNING: A DO loop must follow the VECTOR ALWAYS directive
+ !dir$ vector always
+ a = 1
+end subroutine non_do
+
+subroutine execution_part
+ do i=1,10
+ ! WARNING: A DO loop must follow the VECTOR ALWAYS directive
+ !dir$ vector always
+ end do
+end subroutine execution_part
diff --git a/flang/test/Semantics/null01.f90 b/flang/test/Semantics/null01.f90
index 3bf620048e2f..04d94865356b 100644
--- a/flang/test/Semantics/null01.f90
+++ b/flang/test/Semantics/null01.f90
@@ -151,10 +151,16 @@ module m
subroutine s2(x)
type(pdt(*)), pointer, intent(in) :: x
end
- subroutine test
+ subroutine s3(ar)
+ real, pointer :: ar(..)
+ end
+ subroutine test(ar)
+ real, pointer :: ar(..)
!ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a character length
call s1(null())
!ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a value for the assumed type parameter 'n'
call s2(null())
+ !ERROR: MOLD= argument to NULL() must not be assumed-rank
+ call s3(null(ar))
end
end
diff --git a/flang/test/Semantics/select-rank03.f90 b/flang/test/Semantics/select-rank03.f90
index 8a965e950d38..77b76f5f584c 100644
--- a/flang/test/Semantics/select-rank03.f90
+++ b/flang/test/Semantics/select-rank03.f90
@@ -52,10 +52,12 @@ program test
!ERROR: Whole assumed-size array 'a' may not appear here without subscripts
a = 1.
rank default
- !ERROR: An assumed-rank object may not appear in an ALLOCATE statement
+ !ERROR: An assumed-rank dummy argument may not appear in an ALLOCATE statement
allocate(a)
deallocate(a)
- a = 1.
+ !ERROR: An assumed-rank dummy argument is not allowed in an assignment statement
+ !ERROR: An assumed-rank dummy argument is not allowed as an operand here
+ a = a + 1.
end select
! Test nested associations
select rank(a)
@@ -121,11 +123,13 @@ program test
!ERROR: Whole assumed-size array 'p' may not appear here without subscripts
deallocate(p)
rank default
- !ERROR: An assumed-rank object may not appear in an ALLOCATE statement
+ !ERROR: An assumed-rank dummy argument may not appear in an ALLOCATE statement
allocate(p)
deallocate(p)
+ !ERROR: The left-hand side of a pointer assignment must not be an assumed-rank dummy argument
!ERROR: pointer 'p' associated with object 't0' with incompatible type or shape
p => t0
+ !ERROR: The left-hand side of a pointer assignment must not be an assumed-rank dummy argument
!ERROR: pointer 'p' associated with object 't1' with incompatible type or shape
p => t1
end select
diff --git a/flang/test/Transforms/constant-argument-globalisation-2.fir b/flang/test/Transforms/constant-argument-globalisation-2.fir
new file mode 100644
index 000000000000..03e08a0dcb91
--- /dev/null
+++ b/flang/test/Transforms/constant-argument-globalisation-2.fir
@@ -0,0 +1,98 @@
+// RUN: fir-opt --split-input-file --constant-argument-globalisation-opt < %s | FileCheck %s
+
+module {
+// Test for "two conditional writes to the same alloca doesn't get replaced."
+ func.func @func(%arg0: i32, %arg1: i1) {
+ %c2_i32 = arith.constant 2 : i32
+ %addr = fir.alloca i32 {adapt.valuebyref}
+ fir.if %arg1 {
+ fir.store %c2_i32 to %addr : !fir.ref<i32>
+ } else {
+ fir.store %arg0 to %addr : !fir.ref<i32>
+ }
+ fir.call @sub2(%addr) : (!fir.ref<i32>) -> ()
+ return
+ }
+ func.func private @sub2(!fir.ref<i32>)
+
+// CHECK-LABEL: func.func @func
+// CHECK-SAME: [[ARG0:%.*]]: i32
+// CHECK-SAME: [[ARG1:%.*]]: i1)
+// CHECK: [[CONST:%.*]] = arith.constant
+// CHECK: [[ADDR:%.*]] = fir.alloca i32
+// CHECK: fir.if [[ARG1]]
+// CHECK: fir.store [[CONST]] to [[ADDR]]
+// CHECK: } else {
+// CHECK: fir.store [[ARG0]] to [[ADDR]]
+// CHECK: fir.call @sub2([[ADDR]])
+// CHECK: return
+
+}
+
+// -----
+
+module {
+// Test for "two writes to the same alloca doesn't get replaced."
+ func.func @func() {
+ %c1_i32 = arith.constant 1 : i32
+ %c2_i32 = arith.constant 2 : i32
+ %addr = fir.alloca i32 {adapt.valuebyref}
+ fir.store %c1_i32 to %addr : !fir.ref<i32>
+ fir.store %c2_i32 to %addr : !fir.ref<i32>
+ fir.call @sub2(%addr) : (!fir.ref<i32>) -> ()
+ return
+ }
+ func.func private @sub2(!fir.ref<i32>)
+
+// CHECK-LABEL: func.func @func
+// CHECK: [[CONST1:%.*]] = arith.constant
+// CHECK: [[CONST2:%.*]] = arith.constant
+// CHECK: [[ADDR:%.*]] = fir.alloca i32
+// CHECK: fir.store [[CONST1]] to [[ADDR]]
+// CHECK: fir.store [[CONST2]] to [[ADDR]]
+// CHECK: fir.call @sub2([[ADDR]])
+// CHECK: return
+
+}
+
+// -----
+
+module {
+// Test for "one write to the the alloca gets replaced."
+ func.func @func() {
+ %c1_i32 = arith.constant 1 : i32
+ %addr = fir.alloca i32 {adapt.valuebyref}
+ fir.store %c1_i32 to %addr : !fir.ref<i32>
+ fir.call @sub2(%addr) : (!fir.ref<i32>) -> ()
+ return
+ }
+ func.func private @sub2(!fir.ref<i32>)
+
+// CHECK-LABEL: func.func @func
+// CHECK: [[ADDR:%.*]] = fir.address_of([[EXTR:@.*]]) : !fir.ref<i32>
+// CHECK: fir.call @sub2([[ADDR]])
+// CHECK: return
+// CHECK: fir.global internal [[EXTR]] constant : i32 {
+// CHECK: %{{.*}} = arith.constant 1 : i32
+// CHECK: fir.has_value %{{.*}} : i32
+// CHECK: }
+
+}
+
+// -----
+// Check that same argument used twice is converted.
+module {
+ func.func @func(%arg0: !fir.ref<i32>, %arg1: i1) {
+ %c2_i32 = arith.constant 2 : i32
+ %addr1 = fir.alloca i32 {adapt.valuebyref}
+ fir.store %c2_i32 to %addr1 : !fir.ref<i32>
+ fir.call @sub1(%addr1, %addr1) : (!fir.ref<i32>, !fir.ref<i32>) -> ()
+ return
+ }
+}
+
+// CHECK-LABEL: func.func @func
+// CHECK-NEXT: %[[ARG1:.*]] = fir.address_of([[CONST1:@.*]]) : !fir.ref<i32>
+// CHECK-NEXT: %[[ARG2:.*]] = fir.address_of([[CONST2:@.*]]) : !fir.ref<i32>
+// CHECK-NEXT: fir.call @sub1(%[[ARG1]], %[[ARG2]])
+// CHECK-NEXT: return
diff --git a/flang/test/Transforms/constant-argument-globalisation.fir b/flang/test/Transforms/constant-argument-globalisation.fir
new file mode 100644
index 000000000000..553c3c6c2484
--- /dev/null
+++ b/flang/test/Transforms/constant-argument-globalisation.fir
@@ -0,0 +1,67 @@
+// RUN: fir-opt --constant-argument-globalisation-opt < %s | FileCheck %s
+// RUN: %flang_fc1 -emit-llvm -flang-deprecated-no-hlfir -O2 -o - %s | FileCheck --check-prefix=DISABLE %s
+module {
+ func.func @sub1(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "y"}) {
+ %0 = fir.alloca i32 {adapt.valuebyref}
+ %1 = fir.alloca f64 {adapt.valuebyref}
+ %2 = fir.alloca f64 {adapt.valuebyref}
+ %c1_i32 = arith.constant 1 : i32
+ %cst = arith.constant 1.000000e+00 : f64
+ %cst_0 = arith.constant 0.000000e+00 : f64
+ %3 = fir.declare %arg0 {uniq_name = "_QFsub1Ex"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %4 = fir.declare %arg1 {uniq_name = "_QFsub1Ey"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ fir.store %cst_0 to %2 : !fir.ref<f64>
+ %false = arith.constant false
+ fir.store %cst to %1 : !fir.ref<f64>
+ %false_1 = arith.constant false
+ fir.store %c1_i32 to %0 : !fir.ref<i32>
+ %false_2 = arith.constant false
+ fir.call @sub2(%2, %1, %3, %4, %0) fastmath<contract> : (!fir.ref<f64>, !fir.ref<f64>, !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) -> ()
+ return
+ }
+ func.func private @sub2(!fir.ref<f64>, !fir.ref<f64>, !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
+
+// CHECK-LABEL: func.func @sub1(
+// CHECK-SAME: [[ARG0:%.*]]: !fir.ref<i32> {{{.*}}},
+// CHECK-SAME: [[ARG1:%.*]]: !fir.ref<i32> {{{.*}}}) {
+// CHECK: [[X:%.*]] = fir.declare [[ARG0]] {{.*}}
+// CHECK: [[Y:%.*]] = fir.declare [[ARG1]] {{.*}}
+// CHECK: [[CONST_R0:%.*]] = fir.address_of([[EXTR_0:@.*]]) : !fir.ref<f64>
+// CHECK: [[CONST_R1:%.*]] = fir.address_of([[EXTR_1:@.*]]) : !fir.ref<f64>
+// CHECK: [[CONST_I:%.*]] = fir.address_of([[EXTR_2:@.*]]) : !fir.ref<i32>
+// CHECK: fir.call @sub2([[CONST_R0]], [[CONST_R1]], [[X]], [[Y]], [[CONST_I]])
+// CHECK-SAME: fastmath<contract>
+// CHECK: return
+
+// CHECK: fir.global internal [[EXTR_0]] constant : f64 {
+// CHECK: %{{.*}} = arith.constant 0.000000e+00 : f64
+// CHECK: fir.has_value %{{.*}} : f64
+// CHECK: }
+// CHECK: fir.global internal [[EXTR_1]] constant : f64 {
+// CHECK: %{{.*}} = arith.constant 1.000000e+00 : f64
+// CHECK: fir.has_value %{{.*}} : f64
+// CHECK: }
+// CHECK: fir.global internal [[EXTR_2]] constant : i32 {
+// CHECK: %{{.*}} = arith.constant 1 : i32
+// CHECK: fir.has_value %{{.*}} : i32
+// CHECK: }
+
+// DISABLE-LABEL: ; ModuleID =
+// DISABLE-NOT: @_extruded
+// DISABLE: define void @sub1(
+// DISABLE-SAME: ptr [[ARG0:%.*]],
+// DISABLE-SAME: ptr [[ARG1:%.*]])
+// DISABLE-SAME: {
+// DISABLE: [[CONST_R0:%.*]] = alloca double
+// DISABLE: [[CONST_R1:%.*]] = alloca double
+// DISABLE: [[CONST_I:%.*]] = alloca i32
+// DISABLE: store double 0.0{{.*}}+00, ptr [[CONST_R0]]
+// DISABLE: store double 1.0{{.*}}+00, ptr [[CONST_R1]]
+// DISABLE: store i32 1, ptr [[CONST_I]]
+// DISABLE: call void @sub2(ptr nonnull [[CONST_R0]],
+// DISABLE-SAME: ptr nonnull [[CONST_R1]],
+// DISABLE-SAME: ptr [[ARG0]], ptr [[ARG1]],
+// DISABLE-SAME: ptr nonnull [[CONST_I]])
+// DISABLE: ret void
+// DISABLE: }
+}
diff --git a/flang/test/Transforms/debug-90683.fir b/flang/test/Transforms/debug-90683.fir
index 9da0e5347d3f..cc6929c10411 100644
--- a/flang/test/Transforms/debug-90683.fir
+++ b/flang/test/Transforms/debug-90683.fir
@@ -2,7 +2,7 @@
// This test checks that debug information for fir.real type works ok.
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPfn1(%arg0: !fir.ref<!fir.complex<8>> {fir.bindc_name = "a"} ) {
%0 = fir.declare %arg0 {uniq_name = "_QFfn1Ea"} : (!fir.ref<!fir.complex<8>>) -> !fir.ref<!fir.complex<8>>
%1 = fir.alloca f32 {bindc_name = "abserror", uniq_name = "_QFfn1Eabserror"}
diff --git a/flang/test/Transforms/debug-allocatable-1.fir b/flang/test/Transforms/debug-allocatable-1.fir
new file mode 100644
index 000000000000..fd0beaddcdb7
--- /dev/null
+++ b/flang/test/Transforms/debug-allocatable-1.fir
@@ -0,0 +1,26 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ func.func private @_QFPff() {
+ %c1 = arith.constant 1 : index
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope
+ %1 = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi32>>> {bindc_name = "ar2", uniq_name = "_QFFffEar2"}
+ %4 = fircg.ext_declare %1 {uniq_name = "_QFFffEar2"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>> loc(#loc1)
+ %15 = fir.alloca !fir.box<!fir.heap<f32>> {bindc_name = "sc", uniq_name = "_QFFffEsc"}
+ %18 = fircg.ext_declare %15 {uniq_name = "_QFFffEsc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>> loc(#loc2)
+ return
+ } loc(#loc3)
+}
+
+#loc1 = loc("test.f90":3:3)
+#loc2 = loc("test.f90":4:3)
+#loc3 = loc("test.f90":1:3)
+
+// CHECK-DAG: #[[TY1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real"{{.*}}>
+// CHECK-DAG: #[[TY2:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}#llvm.di_subrange{{.*}}#llvm.di_subrange{{.*}}allocated = <[DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne]>>
+// CHECK-DAG: #[[TY3:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type{{.*}}baseType = #[[TY1]]{{.*}}>
+
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "ar2"{{.*}}type = #[[TY2]]>
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "sc"{{.*}}type = #[[TY3]]>
diff --git a/flang/test/Transforms/debug-assumed-shape-array.fir b/flang/test/Transforms/debug-assumed-shape-array.fir
new file mode 100644
index 000000000000..00dec9b318c8
--- /dev/null
+++ b/flang/test/Transforms/debug-assumed-shape-array.fir
@@ -0,0 +1,16 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"} {
+ func.func @ff_(%arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} ) {
+ %0 = fir.undefined !fir.dscope
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFffEarr"} : (!fir.box<!fir.array<?x?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xi32>> loc(#loc1)
+ return
+ } loc(#loc2)
+}
+#loc1 = loc("test1.f90":1:1)
+#loc2 = loc("test1.f90":3:16)
+
+// CHECK: #llvm.di_composite_type<tag = DW_TAG_array_type
+// CHECK-SAME: elements = #llvm.di_subrange<lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), DW_OP_deref]>, upperBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), DW_OP_deref]>>
+// CHECK-SAME: #llvm.di_subrange<lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(48), DW_OP_deref]>, upperBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(56), DW_OP_deref]>>
+// CHECK-SAME: dataLocation = <[DW_OP_push_object_address, DW_OP_deref]>>
diff --git a/flang/test/Transforms/debug-char-type-1.fir b/flang/test/Transforms/debug-char-type-1.fir
new file mode 100644
index 000000000000..630b52d96cb8
--- /dev/null
+++ b/flang/test/Transforms/debug-char-type-1.fir
@@ -0,0 +1,26 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ fir.global @_QMhelperEstr1 : !fir.char<1,40> {
+ %0 = fir.zero_bits !fir.char<1,40>
+ fir.has_value %0 : !fir.char<1,40>
+ } loc(#loc1)
+ fir.global @_QMhelperEstr2 : !fir.char<4,20> {
+ %0 = fir.zero_bits !fir.char<4,20>
+ fir.has_value %0 : !fir.char<4,20>
+ } loc(#loc1)
+ fir.global @_QMhelperEstr3 : !fir.box<!fir.heap<!fir.char<1,?>>> {
+ %c0 = arith.constant 0 : index
+ %0 = fir.zero_bits !fir.heap<!fir.char<1,?>>
+ %1 = fir.embox %0 typeparams %c0 : (!fir.heap<!fir.char<1,?>>, index) -> !fir.box<!fir.heap<!fir.char<1,?>>>
+ fir.has_value %1 : !fir.box<!fir.heap<!fir.char<1,?>>>
+ } loc(#loc1)
+}
+#loc1 = loc("string.f90":1:1)
+
+// CHECK-DAG: #[[TY1:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 320, encoding = DW_ATE_ASCII>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str1"{{.*}}type = #[[TY1]]{{.*}}>
+// CHECK-DAG: #[[TY2:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 640, encoding = DW_ATE_UCS>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str2"{{.*}}type = #[[TY2]]{{.*}}>
+// CHECK-DAG: #[[TY3:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type{{.*}}stringLengthExp = <[DW_OP_push_object_address, DW_OP_plus_uconst(8)]>, stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>, encoding = DW_ATE_ASCII>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str3"{{.*}}type = #[[TY3]]{{.*}}>
diff --git a/flang/test/Transforms/debug-complex-1.fir b/flang/test/Transforms/debug-complex-1.fir
index a3cbd767d8a5..cc742d3b183b 100644
--- a/flang/test/Transforms/debug-complex-1.fir
+++ b/flang/test/Transforms/debug-complex-1.fir
@@ -3,7 +3,7 @@
// check conversion of complex type of different size. Both fir and mlir
// variants are checked.
-module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "native"} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @test1(%x : !fir.complex<4>) -> !fir.complex<8> {
%1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<8>
return %1 : !fir.complex<8>
diff --git a/flang/test/Transforms/debug-fixed-array-type.fir b/flang/test/Transforms/debug-fixed-array-type.fir
index 401c72541183..d4ed0b970208 100644
--- a/flang/test/Transforms/debug-fixed-array-type.fir
+++ b/flang/test/Transforms/debug-fixed-array-type.fir
@@ -1,6 +1,6 @@
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
%c7 = arith.constant 7 : index
%c8 = arith.constant 8 : index
diff --git a/flang/test/Transforms/debug-fn-info.f90 b/flang/test/Transforms/debug-fn-info.f90
deleted file mode 100644
index 97a34e8676de..000000000000
--- a/flang/test/Transforms/debug-fn-info.f90
+++ /dev/null
@@ -1,45 +0,0 @@
-! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
-
-
-! CHECK-DAG: #[[INT8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
-! CHECK-DAG: #[[INT4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
-! CHECK-DAG: #[[REAL8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
-! CHECK-DAG: #[[LOG1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 8, encoding = DW_ATE_boolean>
-! CHECK-DAG: #[[REAL4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
-! CHECK-DAG: #[[LOG4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 32, encoding = DW_ATE_boolean>
-! CHECK: #[[TY0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_program>
-! CHECK: #[[TY1:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT8]], #[[INT4]], #[[REAL8]], #[[LOG1]]>
-! CHECK: #[[TY2:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT4]], #[[INT8]], #[[REAL4]], #[[LOG4]]>
-
-! CHECK: #di_subprogram1 = #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "_QQmain", linkageName = "_QQmain", file = {{.*}}, line = [[@LINE+1]], scopeLine = [[@LINE+1]], subprogramFlags = Definition, type = #[[TY0]]>
-program mn
- integer(kind=4) :: i4
- integer(kind=8) :: i8
- real(kind=4) :: r4
- real(kind=8) :: r8
- logical(kind=1) :: l1
- logical(kind=4) :: l4
- i8 = fn1(i4, r8, l1)
- i4 = fn2(i8, r4, l4)
-contains
- ! CHECK: #di_subprogram2 = #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn1", linkageName = "_QFPfn1", file = {{.*}}, line = [[@LINE+1]], scopeLine = [[@LINE+1]], subprogramFlags = Definition, type = #[[TY1]]>
- function fn1(a, b, c) result (res)
- implicit none
- integer(kind=4), intent(in) :: a
- real(kind=8), intent(in) :: b
- logical(kind=1), intent(in) :: c
- integer(kind=8) :: res
- res = a + b
- end function
-
-! CHECK: #di_subprogram3 = #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn2", linkageName = "_QFPfn2", file = {{.*}}, line = [[@LINE+1]], scopeLine = [[@LINE+1]], subprogramFlags = Definition, type = #[[TY2]]>
- function fn2(a, b, c) result (res)
- implicit none
- integer(kind=8), intent(in) :: a
- real(kind=4), intent(in) :: b
- logical(kind=4), intent(in) :: c
- integer(kind=4) :: res
- res = a + b
- end function
-end program
-
diff --git a/flang/test/Transforms/debug-fn-info.fir b/flang/test/Transforms/debug-fn-info.fir
new file mode 100644
index 000000000000..f456e35d3dd7
--- /dev/null
+++ b/flang/test/Transforms/debug-fn-info.fir
@@ -0,0 +1,75 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
+ %0 = fir.alloca i32 {bindc_name = "i4", uniq_name = "_QFEi4"}
+ %1 = fircg.ext_declare %0 {uniq_name = "_QFEi4"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %2 = fir.alloca i64 {bindc_name = "i8", uniq_name = "_QFEi8"}
+ %3 = fircg.ext_declare %2 {uniq_name = "_QFEi8"} : (!fir.ref<i64>) -> !fir.ref<i64>
+ %4 = fir.alloca !fir.logical<1> {bindc_name = "l1", uniq_name = "_QFEl1"}
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFEl1"} : (!fir.ref<!fir.logical<1>>) -> !fir.ref<!fir.logical<1>>
+ %6 = fir.alloca !fir.logical<4> {bindc_name = "l4", uniq_name = "_QFEl4"}
+ %7 = fircg.ext_declare %6 {uniq_name = "_QFEl4"} : (!fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>>
+ %8 = fir.alloca f32 {bindc_name = "r4", uniq_name = "_QFEr4"}
+ %9 = fircg.ext_declare %8 {uniq_name = "_QFEr4"} : (!fir.ref<f32>) -> !fir.ref<f32>
+ %10 = fir.alloca f64 {bindc_name = "r8", uniq_name = "_QFEr8"}
+ %11 = fircg.ext_declare %10 {uniq_name = "_QFEr8"} : (!fir.ref<f64>) -> !fir.ref<f64>
+ %12 = fir.call @_QFPfn1(%1, %11, %5) fastmath<contract> : (!fir.ref<i32>, !fir.ref<f64>, !fir.ref<!fir.logical<1>>) -> i64
+ fir.store %12 to %3 : !fir.ref<i64>
+ %13 = fir.call @_QFPfn2(%3, %9, %7) fastmath<contract> : (!fir.ref<i64>, !fir.ref<f32>, !fir.ref<!fir.logical<4>>) -> i32
+ fir.store %13 to %1 : !fir.ref<i32>
+ return
+ } loc(#loc1)
+ func.func private @_QFPfn1(%arg0: !fir.ref<i32> {fir.bindc_name = "a"} , %arg1: !fir.ref<f64> {fir.bindc_name = "b"}, %arg2: !fir.ref<!fir.logical<1>> {fir.bindc_name = "c"}) -> i64 attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>} {
+ %0 = fir.undefined !fir.dscope
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFFfn1Ea"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %2 = fircg.ext_declare %arg1 dummy_scope %0 {uniq_name = "_QFFfn1Eb"} : (!fir.ref<f64>, !fir.dscope) -> !fir.ref<f64>
+ %3 = fircg.ext_declare %arg2 dummy_scope %0 {uniq_name = "_QFFfn1Ec"} : (!fir.ref<!fir.logical<1>>, !fir.dscope) -> !fir.ref<!fir.logical<1>>
+ %4 = fir.alloca i64 {bindc_name = "res", uniq_name = "_QFFfn1Eres"}
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFFfn1Eres"} : (!fir.ref<i64>) -> !fir.ref<i64>
+ %6 = fir.load %1 : !fir.ref<i32>
+ %7 = fir.convert %6 : (i32) -> f64
+ %8 = fir.load %2 : !fir.ref<f64>
+ %9 = arith.addf %7, %8 fastmath<contract> : f64
+ %10 = fir.convert %9 : (f64) -> i64
+ fir.store %10 to %5 : !fir.ref<i64>
+ %11 = fir.load %5 : !fir.ref<i64>
+ return %11 : i64
+ } loc(#loc2)
+ func.func private @_QFPfn2(%arg0: !fir.ref<i64> {fir.bindc_name = "a"}, %arg1: !fir.ref<f32> {fir.bindc_name = "b"}, %arg2: !fir.ref<!fir.logical<4>> {fir.bindc_name = "c"}) -> i32 attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>} {
+ %0 = fir.undefined !fir.dscope
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFFfn2Ea"} : (!fir.ref<i64>, !fir.dscope) -> !fir.ref<i64>
+ %2 = fircg.ext_declare %arg1 dummy_scope %0 {uniq_name = "_QFFfn2Eb"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
+ %3 = fircg.ext_declare %arg2 dummy_scope %0 {uniq_name = "_QFFfn2Ec"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> !fir.ref<!fir.logical<4>>
+ %4 = fir.alloca i32 {bindc_name = "res", uniq_name = "_QFFfn2Eres"}
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFFfn2Eres"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %6 = fir.load %1 : !fir.ref<i64>
+ %7 = fir.convert %6 : (i64) -> f32
+ %8 = fir.load %2 : !fir.ref<f32>
+ %9 = arith.addf %7, %8 fastmath<contract> : f32
+ %10 = fir.convert %9 : (f32) -> i32
+ fir.store %10 to %5 : !fir.ref<i32>
+ %11 = fir.load %5 : !fir.ref<i32>
+ return %11 : i32
+ } loc(#loc3)
+}
+#loc1 = loc("test.f90":15:1)
+#loc2 = loc("test.f90":26:22)
+#loc3 = loc("test2.f90":43:22)
+
+
+// CHECK-DAG: #[[INT8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
+// CHECK-DAG: #[[INT4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+// CHECK-DAG: #[[REAL8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
+// CHECK-DAG: #[[LOG1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 8, encoding = DW_ATE_boolean>
+// CHECK-DAG: #[[REAL4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+// CHECK-DAG: #[[LOG4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 32, encoding = DW_ATE_boolean>
+// CHECK: #[[TY0:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_program>
+// CHECK: #[[TY1:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT8]], #[[INT4]], #[[REAL8]], #[[LOG1]]>
+// CHECK: #[[TY2:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT4]], #[[INT8]], #[[REAL4]], #[[LOG4]]>
+
+// Line numbers should match the number in corresponding loc entry.
+// CHECK: #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "_QQmain", linkageName = "_QQmain", file = {{.*}}, line = 15, scopeLine = 15, subprogramFlags = Definition, type = #[[TY0]]>
+// CHECK: #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn1", linkageName = "_QFPfn1", file = {{.*}}, line = 26, scopeLine = 26, subprogramFlags = Definition, type = #[[TY1]]>
+// CHECK: #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn2", linkageName = "_QFPfn2", file = {{.*}}, line = 43, scopeLine = 43, subprogramFlags = Definition, type = #[[TY2]]>
+
diff --git a/flang/test/Transforms/debug-line-table-existing.fir b/flang/test/Transforms/debug-line-table-existing.fir
index 534278ebc972..0e006303c8a8 100644
--- a/flang/test/Transforms/debug-line-table-existing.fir
+++ b/flang/test/Transforms/debug-line-table-existing.fir
@@ -3,7 +3,7 @@
// REQUIRES: system-linux
// Test that there are no changes to a function with existed fused loc debug
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPs1() {
return loc(#loc1)
} loc(#loc2)
diff --git a/flang/test/Transforms/debug-line-table-inc-file.fir b/flang/test/Transforms/debug-line-table-inc-file.fir
index 9370c138fd42..065039b59c5a 100644
--- a/flang/test/Transforms/debug-line-table-inc-file.fir
+++ b/flang/test/Transforms/debug-line-table-inc-file.fir
@@ -3,7 +3,7 @@
// REQUIRES: system-linux
// Test for included functions that have a different debug location than the current file
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPsinc() {
return loc(#loc2)
} loc(#loc1)
@@ -19,7 +19,7 @@ module attributes {} {
#loc4 = loc("/home/user01/llvm-project/build_release/simple.f90":4:3)
#loc5 = loc("/home/user01/llvm-project/build_release/simple.f90":5:1)
-// CHECK: module {
+// CHECK: module
// CHECK: func.func @_QPsinc() {
// CHECK: } loc(#[[FUSED_LOC_INC_FILE:.*]])
// CHECK: func.func @_QQmain() {
diff --git a/flang/test/Transforms/debug-line-table-inc-same-file.fir b/flang/test/Transforms/debug-line-table-inc-same-file.fir
index 4836f2e21dd9..bcaf44979823 100644
--- a/flang/test/Transforms/debug-line-table-inc-same-file.fir
+++ b/flang/test/Transforms/debug-line-table-inc-same-file.fir
@@ -4,7 +4,7 @@
// Test that there is only one FileAttribute generated for multiple functions
// in the same file.
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPs1() {
return loc(#loc2)
} loc(#loc1)
diff --git a/flang/test/Transforms/debug-line-table.fir b/flang/test/Transforms/debug-line-table.fir
index 8a72ca2a856a..d6e54fd1ac46 100644
--- a/flang/test/Transforms/debug-line-table.fir
+++ b/flang/test/Transforms/debug-line-table.fir
@@ -3,7 +3,7 @@
// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=LINETABLE
// RUN: fir-opt --add-debug-info="is-optimized=true" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=OPT
-module attributes { fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", llvm.target_triple = "aarch64-unknown-linux-gnu"} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @_QPsb() {
return loc(#loc_sb)
} loc(#loc_sb)
diff --git a/flang/test/Transforms/debug-local-var-2.f90 b/flang/test/Transforms/debug-local-var-2.f90
deleted file mode 100644
index 0fe1b81c27e6..000000000000
--- a/flang/test/Transforms/debug-local-var-2.f90
+++ /dev/null
@@ -1,94 +0,0 @@
-! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck --check-prefix=LINEONLY %s
-
-! This tests checks the debug information for local variables in llvm IR.
-
-! CHECK-LABEL: define void @_QQmain
-! CHECK-DAG: %[[AL11:.*]] = alloca i32
-! CHECK-DAG: %[[AL12:.*]] = alloca i64
-! CHECK-DAG: %[[AL13:.*]] = alloca i8
-! CHECK-DAG: %[[AL14:.*]] = alloca i32
-! CHECK-DAG: %[[AL15:.*]] = alloca float
-! CHECK-DAG: %[[AL16:.*]] = alloca double
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL11]], metadata ![[I4:.*]], metadata !DIExpression())
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL12]], metadata ![[I8:.*]], metadata !DIExpression())
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL13]], metadata ![[L1:.*]], metadata !DIExpression())
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL14]], metadata ![[L4:.*]], metadata !DIExpression())
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL15]], metadata ![[R4:.*]], metadata !DIExpression())
-! CHECK-DAG: call void @llvm.dbg.declare(metadata ptr %[[AL16]], metadata ![[R8:.*]], metadata !DIExpression())
-! CHECK-LABEL: }
-
-! CHECK-LABEL: define {{.*}}i64 @_QFPfn1
-! CHECK-SAME: (ptr %[[ARG1:.*]], ptr %[[ARG2:.*]], ptr %[[ARG3:.*]])
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[ARG1]], metadata ![[A1:.*]], metadata !DIExpression())
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[ARG2]], metadata ![[B1:.*]], metadata !DIExpression())
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[ARG3]], metadata ![[C1:.*]], metadata !DIExpression())
-! CHECK-DAG: %[[AL2:.*]] = alloca i64
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[AL2]], metadata ![[RES1:.*]], metadata !DIExpression())
-! CHECK-LABEL: }
-
-! CHECK-LABEL: define {{.*}}i32 @_QFPfn2
-! CHECK-SAME: (ptr %[[FN2ARG1:.*]], ptr %[[FN2ARG2:.*]], ptr %[[FN2ARG3:.*]])
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[FN2ARG1]], metadata ![[A2:.*]], metadata !DIExpression())
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[FN2ARG2]], metadata ![[B2:.*]], metadata !DIExpression())
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[FN2ARG3]], metadata ![[C2:.*]], metadata !DIExpression())
-! CHECK-DAG: %[[AL3:.*]] = alloca i32
-! CHECK-DAG: tail call void @llvm.dbg.declare(metadata ptr %[[AL3]], metadata ![[RES2:.*]], metadata !DIExpression())
-! CHECK-LABEL: }
-
-program mn
-! CHECK-DAG: ![[MAIN:.*]] = distinct !DISubprogram(name: "_QQmain", {{.*}})
-
-! CHECK-DAG: ![[TYI32:.*]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
-! CHECK-DAG: ![[TYI64:.*]] = !DIBasicType(name: "integer", size: 64, encoding: DW_ATE_signed)
-! CHECK-DAG: ![[TYL8:.*]] = !DIBasicType(name: "logical", size: 8, encoding: DW_ATE_boolean)
-! CHECK-DAG: ![[TYL32:.*]] = !DIBasicType(name: "logical", size: 32, encoding: DW_ATE_boolean)
-! CHECK-DAG: ![[TYR32:.*]] = !DIBasicType(name: "real", size: 32, encoding: DW_ATE_float)
-! CHECK-DAG: ![[TYR64:.*]] = !DIBasicType(name: "real", size: 64, encoding: DW_ATE_float)
-
-! CHECK-DAG: ![[I4]] = !DILocalVariable(name: "i4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYI32]])
-! CHECK-DAG: ![[I8]] = !DILocalVariable(name: "i8", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYI64]])
-! CHECK-DAG: ![[R4]] = !DILocalVariable(name: "r4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYR32]])
-! CHECK-DAG: ![[R8]] = !DILocalVariable(name: "r8", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYR64]])
-! CHECK-DAG: ![[L1]] = !DILocalVariable(name: "l1", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYL8]])
-! CHECK-DAG: ![[L4]] = !DILocalVariable(name: "l4", scope: ![[MAIN]], file: !{{.*}}, line: [[@LINE+6]], type: ![[TYL32]])
- integer(kind=4) :: i4
- integer(kind=8) :: i8
- real(kind=4) :: r4
- real(kind=8) :: r8
- logical(kind=1) :: l1
- logical(kind=4) :: l4
-
- i8 = fn1(i4, r8, l1)
- i4 = fn2(i8, r4, l4)
-contains
-! CHECK-DAG: ![[FN1:.*]] = distinct !DISubprogram(name: "fn1", {{.*}})
-! CHECK-DAG: ![[A1]] = !DILocalVariable(name: "a1", arg: 1, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI32]])
-! CHECK-DAG: ![[B1]] = !DILocalVariable(name: "b1", arg: 2, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYR64]])
-! CHECK-DAG: ![[C1]] = !DILocalVariable(name: "c1", arg: 3, scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYL8]])
-! CHECK-DAG: ![[RES1]] = !DILocalVariable(name: "res1", scope: ![[FN1]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI64]])
- function fn1(a1, b1, c1) result (res1)
- integer(kind=4), intent(in) :: a1
- real(kind=8), intent(in) :: b1
- logical(kind=1), intent(in) :: c1
- integer(kind=8) :: res1
-
- res1 = a1 + b1
- end function
-
-! CHECK-DAG: ![[FN2:.*]] = distinct !DISubprogram(name: "fn2", {{.*}})
-! CHECK-DAG: ![[A2]] = !DILocalVariable(name: "a2", arg: 1, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI64]])
-! CHECK-DAG: ![[B2]] = !DILocalVariable(name: "b2", arg: 2, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYR32]])
-! CHECK-DAG: ![[C2]] = !DILocalVariable(name: "c2", arg: 3, scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYL32]])
-! CHECK-DAG: ![[RES2]] = !DILocalVariable(name: "res2", scope: ![[FN2]], file: !{{.*}}, line: [[@LINE+5]], type: ![[TYI32]])
- function fn2(a2, b2, c2) result (res2)
- integer(kind=8), intent(in) :: a2
- real(kind=4), intent(in) :: b2
- logical(kind=4), intent(in) :: c2
- integer(kind=4) :: res2
-
- res2 = a2 + b2
- end function
-end program
-
-LINEONLY-NOT: DILocalVariable
diff --git a/flang/test/Transforms/debug-local-var.f90 b/flang/test/Transforms/debug-local-var.f90
deleted file mode 100644
index 96dc111ad308..000000000000
--- a/flang/test/Transforms/debug-local-var.f90
+++ /dev/null
@@ -1,54 +0,0 @@
-! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
-! RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
-
-! CHECK-DAG: #[[INT8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
-! CHECK-DAG: #[[INT4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
-! CHECK-DAG: #[[REAL8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
-! CHECK-DAG: #[[LOG1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 8, encoding = DW_ATE_boolean>
-! CHECK-DAG: #[[REAL4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
-! CHECK-DAG: #[[LOG4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 32, encoding = DW_ATE_boolean>
-! CHECK-DAG: #[[MAIN:.*]] = #llvm.di_subprogram<{{.*}}name = "_QQmain"{{.*}}>
-! CHECK-DAG: #[[FN1:.*]] = #llvm.di_subprogram<{{.*}}name = "fn1"{{.*}}>
-! CHECK-DAG: #[[FN2:.*]] = #llvm.di_subprogram<{{.*}}name = "fn2"{{.*}}>
-
-program mn
-! CHECK-DAG: #[[I4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "i4", file = #{{.*}}, line = [[@LINE+6]], type = #[[INT4]]>
-! CHECK-DAG: #[[I8:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "i8", file = #{{.*}}, line = [[@LINE+6]], type = #[[INT8]]>
-! CHECK-DAG: #[[R4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "r4", file = #{{.*}}, line = [[@LINE+6]], type = #[[REAL4]]>
-! CHECK-DAG: #[[R8:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "r8", file = #{{.*}}, line = [[@LINE+6]], type = #[[REAL8]]>
-! CHECK-DAG: #[[L1:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "l1", file = #{{.*}}, line = [[@LINE+6]], type = #[[LOG1]]>
-! CHECK-DAG: #[[L4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "l4", file = #{{.*}}, line = [[@LINE+6]], type = #[[LOG4]]>
- integer(kind=4) :: i4
- integer(kind=8) :: i8
- real(kind=4) :: r4
- real(kind=8) :: r8
- logical(kind=1) :: l1
- logical(kind=4) :: l4
- i8 = fn1(i4, r8, l1)
- i4 = fn2(i8, r4, l4)
-contains
- function fn1(a1, b1, c1) result (res1)
-! CHECK-DAG: #[[A1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "a1", file = #{{.*}}, line = [[@LINE+4]], arg = 1, type = #[[INT4]]>
-! CHECK-DAG: #[[B1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "b1", file = #{{.*}}, line = [[@LINE+4]], arg = 2, type = #[[REAL8]]>
-! CHECK-DAG: #[[C1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "c1", file = #{{.*}}, line = [[@LINE+4]], arg = 3, type = #[[LOG1]]>
-! CHECK-DAG: #[[RES1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "res1", file = #{{.*}}, line = [[@LINE+4]], type = #[[INT8]]>
- integer(kind=4), intent(in) :: a1
- real(kind=8), intent(in) :: b1
- logical(kind=1), intent(in) :: c1
- integer(kind=8) :: res1
- res1 = a1 + b1
- end function
-
- function fn2(a2, b2, c2) result (res2)
- implicit none
-! CHECK-DAG: #[[A2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "a2", file = #{{.*}}, line = [[@LINE+4]], arg = 1, type = #[[INT8]]>
-! CHECK-DAG: #[[B2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "b2", file = #{{.*}}, line = [[@LINE+4]], arg = 2, type = #[[REAL4]]>
-! CHECK-DAG: #[[C2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "c2", file = #{{.*}}, line = [[@LINE+4]], arg = 3, type = #[[LOG4]]>
-! CHECK-DAG: #[[RES2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "res2", file = #{{.*}}, line = [[@LINE+4]], type = #[[INT4]]>
- integer(kind=8), intent(in) :: a2
- real(kind=4), intent(in) :: b2
- logical(kind=4), intent(in) :: c2
- integer(kind=4) :: res2
- res2 = a2 + b2
- end function
-end program
diff --git a/flang/test/Transforms/debug-local-var.fir b/flang/test/Transforms/debug-local-var.fir
new file mode 100644
index 000000000000..762f5ed269ef
--- /dev/null
+++ b/flang/test/Transforms/debug-local-var.fir
@@ -0,0 +1,100 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
+ %0 = fir.alloca i32 {bindc_name = "i4", uniq_name = "_QFEi4"}
+ %1 = fircg.ext_declare %0 {uniq_name = "_QFEi4"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc1)
+ %2 = fir.alloca i64 {bindc_name = "i8", uniq_name = "_QFEi8"}
+ %3 = fircg.ext_declare %2 {uniq_name = "_QFEi8"} : (!fir.ref<i64>) -> !fir.ref<i64> loc(#loc2)
+ %4 = fir.alloca !fir.logical<1> {bindc_name = "l1", uniq_name = "_QFEl1"}
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFEl1"} : (!fir.ref<!fir.logical<1>>) -> !fir.ref<!fir.logical<1>> loc(#loc3)
+ %6 = fir.alloca !fir.logical<4> {bindc_name = "l4", uniq_name = "_QFEl4"}
+ %7 = fircg.ext_declare %6 {uniq_name = "_QFEl4"} : (!fir.ref<!fir.logical<4>>) -> !fir.ref<!fir.logical<4>> loc(#loc4)
+ %8 = fir.alloca f32 {bindc_name = "r4", uniq_name = "_QFEr4"}
+ %9 = fircg.ext_declare %8 {uniq_name = "_QFEr4"} : (!fir.ref<f32>) -> !fir.ref<f32> loc(#loc5)
+ %10 = fir.alloca f64 {bindc_name = "r8", uniq_name = "_QFEr8"}
+ %11 = fircg.ext_declare %10 {uniq_name = "_QFEr8"} : (!fir.ref<f64>) -> !fir.ref<f64> loc(#loc6)
+ %12 = fir.call @_QFPfn1(%1, %11, %5) fastmath<contract> : (!fir.ref<i32>, !fir.ref<f64>, !fir.ref<!fir.logical<1>>) -> i64
+ fir.store %12 to %3 : !fir.ref<i64>
+ %13 = fir.call @_QFPfn2(%3, %9, %7) fastmath<contract> : (!fir.ref<i64>, !fir.ref<f32>, !fir.ref<!fir.logical<4>>) -> i32
+ fir.store %13 to %1 : !fir.ref<i32>
+ return
+ } loc(#loc7)
+ func.func private @_QFPfn1(%arg0: !fir.ref<i32> {fir.bindc_name = "a1"}, %arg1: !fir.ref<f64> {fir.bindc_name = "b1"}, %arg2: !fir.ref<!fir.logical<1>> {fir.bindc_name = "c1"}) -> i64 attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>} {
+ %0 = fir.undefined !fir.dscope loc(#loc11)
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFFfn1Ea1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc8)
+ %2 = fircg.ext_declare %arg1 dummy_scope %0 {uniq_name = "_QFFfn1Eb1"} : (!fir.ref<f64>, !fir.dscope) -> !fir.ref<f64> loc(#loc9)
+ %3 = fircg.ext_declare %arg2 dummy_scope %0 {uniq_name = "_QFFfn1Ec1"} : (!fir.ref<!fir.logical<1>>, !fir.dscope) -> !fir.ref<!fir.logical<1>> loc(#loc10)
+ %4 = fir.alloca i64 {bindc_name = "res1", uniq_name = "_QFFfn1Eres1"} loc(#loc15)
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFFfn1Eres1"} : (!fir.ref<i64>) -> !fir.ref<i64> loc(#loc11)
+ %6 = fir.load %1 : !fir.ref<i32>
+ %7 = fir.convert %6 : (i32) -> f64
+ %8 = fir.load %2 : !fir.ref<f64>
+ %9 = arith.addf %7, %8 fastmath<contract> : f64
+ %10 = fir.convert %9 : (f64) -> i64
+ fir.store %10 to %5 : !fir.ref<i64>
+ %11 = fir.load %5 : !fir.ref<i64>
+ return %11 : i64
+ } loc(#loc12)
+ func.func private @_QFPfn2(%arg0: !fir.ref<i64> {fir.bindc_name = "a2"}, %arg1: !fir.ref<f32> {fir.bindc_name = "b2"}, %arg2: !fir.ref<!fir.logical<4>> {fir.bindc_name = "c2"}) -> i32 attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage<internal>} {
+ %0 = fir.undefined !fir.dscope
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFFfn2Ea2"} : (!fir.ref<i64>, !fir.dscope) -> !fir.ref<i64> loc(#loc13)
+ %2 = fircg.ext_declare %arg1 dummy_scope %0 {uniq_name = "_QFFfn2Eb2"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32> loc(#loc14)
+ %3 = fircg.ext_declare %arg2 dummy_scope %0 {uniq_name = "_QFFfn2Ec2"} : (!fir.ref<!fir.logical<4>>, !fir.dscope) -> !fir.ref<!fir.logical<4>> loc(#loc15)
+ %4 = fir.alloca i32 {bindc_name = "res2", uniq_name = "_QFFfn2Eres2"}
+ %5 = fircg.ext_declare %4 {uniq_name = "_QFFfn2Eres2"} : (!fir.ref<i32>) -> !fir.ref<i32> loc(#loc16)
+ %6 = fir.load %1 : !fir.ref<i64>
+ %7 = fir.convert %6 : (i64) -> f32
+ %8 = fir.load %2 : !fir.ref<f32>
+ %9 = arith.addf %7, %8 fastmath<contract> : f32
+ %10 = fir.convert %9 : (f32) -> i32
+ fir.store %10 to %5 : !fir.ref<i32>
+ %11 = fir.load %5 : !fir.ref<i32>
+ return %11 : i32
+ } loc(#loc17)
+}
+#loc7 = loc("test.f90":4:19)
+#loc1 = loc("test.f90":5:1)
+#loc2 = loc("test.f90":6:22)
+#loc3 = loc("test.f90":7:22)
+#loc4 = loc("test.f90":8:22)
+#loc5 = loc("test.f90":9:22)
+#loc6 = loc("test.f90":10:19)
+#loc12 = loc("test.f90":12:36)
+#loc8 = loc("test.f90":13:3)
+#loc9 = loc("test.f90":14:3)
+#loc10 = loc("test.f90":15:1)
+#loc11 = loc("test.f90":16:1)
+#loc17 = loc("test.f90":18:33)
+#loc13 = loc("test.f90":19:33)
+#loc14 = loc("test.f90":20:36)
+#loc15 = loc("test.f90":21:24)
+#loc16 = loc("test.f90":22:5)
+
+// CHECK-DAG: #[[INT8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
+// CHECK-DAG: #[[INT4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+// CHECK-DAG: #[[REAL8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
+// CHECK-DAG: #[[LOG1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 8, encoding = DW_ATE_boolean>
+// CHECK-DAG: #[[REAL4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+// CHECK-DAG: #[[LOG4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 32, encoding = DW_ATE_boolean>
+// CHECK-DAG: #[[MAIN:.*]] = #llvm.di_subprogram<{{.*}}name = "_QQmain"{{.*}}>
+// CHECK-DAG: #[[FN1:.*]] = #llvm.di_subprogram<{{.*}}name = "fn1"{{.*}}>
+// CHECK-DAG: #[[FN2:.*]] = #llvm.di_subprogram<{{.*}}name = "fn2"{{.*}}>
+
+// Line numbers should match the number in corresponding loc entry.
+// CHECK-DAG: #[[I4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "i4", file = #{{.*}}, line = 5, type = #[[INT4]]>
+// CHECK-DAG: #[[I8:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "i8", file = #{{.*}}, line = 6, type = #[[INT8]]>
+// CHECK-DAG: #[[R4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "r4", file = #{{.*}}, line = 9, type = #[[REAL4]]>
+// CHECK-DAG: #[[R8:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "r8", file = #{{.*}}, line = 10, type = #[[REAL8]]>
+// CHECK-DAG: #[[L1:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "l1", file = #{{.*}}, line = 7, type = #[[LOG1]]>
+// CHECK-DAG: #[[L4:.*]] = #llvm.di_local_variable<scope = #[[MAIN]], name = "l4", file = #{{.*}}, line = 8, type = #[[LOG4]]>
+
+// CHECK-DAG: #[[A1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "a1", file = #{{.*}}, line = 13, arg = 1, type = #[[INT4]]>
+// CHECK-DAG: #[[B1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "b1", file = #{{.*}}, line = 14, arg = 2, type = #[[REAL8]]>
+// CHECK-DAG: #[[C1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "c1", file = #{{.*}}, line = 15, arg = 3, type = #[[LOG1]]>
+// CHECK-DAG: #[[RES1:.*]] = #llvm.di_local_variable<scope = #[[FN1]], name = "res1", file = #{{.*}}, line = 16, type = #[[INT8]]>
+
+// CHECK-DAG: #[[A2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "a2", file = #{{.*}}, line = 19, arg = 1, type = #[[INT8]]>
+// CHECK-DAG: #[[B2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "b2", file = #{{.*}}, line = 20, arg = 2, type = #[[REAL4]]>
+// CHECK-DAG: #[[C2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "c2", file = #{{.*}}, line = 21, arg = 3, type = #[[LOG4]]>
+// CHECK-DAG: #[[RES2:.*]] = #llvm.di_local_variable<scope = #[[FN2]], name = "res2", file = #{{.*}}, line = 22, type = #[[INT4]]>
diff --git a/flang/test/Transforms/debug-module-1.fir b/flang/test/Transforms/debug-module-1.fir
index 822ae01b99aa..71457d32b159 100644
--- a/flang/test/Transforms/debug-module-1.fir
+++ b/flang/test/Transforms/debug-module-1.fir
@@ -1,7 +1,7 @@
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
-module attributes {} {
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
fir.global @_QMhelperEgli : i32 {
%0 = fir.zero_bits i32
fir.has_value %0 : i32
diff --git a/flang/test/Transforms/debug-ptr-type.fir b/flang/test/Transforms/debug-ptr-type.fir
new file mode 100644
index 000000000000..3f6c895ddaf8
--- /dev/null
+++ b/flang/test/Transforms/debug-ptr-type.fir
@@ -0,0 +1,40 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ fir.global @_QMhelperEpar : !fir.box<!fir.ptr<!fir.array<?x?xf32>>> {
+ %0 = fir.zero_bits !fir.ptr<!fir.array<?x?xf32>>
+ %c0 = arith.constant 0 : index
+ %1 = fir.shape %c0, %c0 : (index, index) -> !fir.shape<2>
+ %2 = fir.embox %0(%1) : (!fir.ptr<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
+ fir.has_value %2 : !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
+ } loc(#loc1)
+ fir.global @_QMhelperEpar2 : !fir.box<!fir.ptr<!fir.array<?xi32>>> {
+ %0 = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
+ %c0 = arith.constant 0 : index
+ %1 = fir.shape %c0 : (index) -> !fir.shape<1>
+ %2 = fir.embox %0(%1) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+ fir.has_value %2 : !fir.box<!fir.ptr<!fir.array<?xi32>>>
+ } loc(#loc2)
+ fir.global @_QMhelperEpsc : !fir.box<!fir.ptr<i32>> {
+ %0 = fir.zero_bits !fir.ptr<i32>
+ %1 = fir.embox %0 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+ fir.has_value %1 : !fir.box<!fir.ptr<i32>>
+ } loc(#loc3)
+ fir.global @_QMmEpstr : !fir.box<!fir.ptr<!fir.char<1,16>>> {
+ %0 = fir.zero_bits !fir.ptr<!fir.char<1,16>>
+ %1 = fir.embox %0 : (!fir.ptr<!fir.char<1,16>>) -> !fir.box<!fir.ptr<!fir.char<1,16>>>
+ fir.has_value %1 : !fir.box<!fir.ptr<!fir.char<1,16>>>
+ } loc(#loc4)
+}
+#loc1 = loc("test.f90":5:1)
+#loc2 = loc("test.f90":6:1)
+#loc3 = loc("test.f90":7:1)
+#loc4 = loc("test.f90":8:1)
+
+// CHECK-DAG: #[[INT_TY:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer"{{.*}}>
+// CHECK-DAG: #[[ARR1_TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_subrange<lowerBound = #llvm.di_expression{{.*}}, upperBound = #llvm.di_expression{{.*}}>, #llvm.di_subrange<lowerBound = #llvm.di_expression{{.*}}, upperBound = #llvm.di_expression{{.*}}>, dataLocation = {{.*}}, associated = <[DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne]>>
+// CHECK-DAG: #[[ARR2_TY:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_subrange<lowerBound = #llvm.di_expression{{.*}}, upperBound = #llvm.di_expression{{.*}}>, dataLocation = {{.*}}, associated = <[DW_OP_push_object_address, DW_OP_deref, DW_OP_lit0, DW_OP_ne]>>
+// CHECK-DAG: #[[PTR_TY:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type{{.*}}baseType = #[[INT_TY]]{{.*}}>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "par"{{.*}}type = #[[ARR1_TY]]{{.*}}>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "par2"{{.*}}type = #[[ARR2_TY]]{{.*}}>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "psc"{{.*}}type = #[[PTR_TY]]{{.*}}>
diff --git a/flang/test/Transforms/stack-reclaime.fir b/flang/test/Transforms/stack-reclaime.fir
new file mode 100644
index 000000000000..b53cc9603575
--- /dev/null
+++ b/flang/test/Transforms/stack-reclaime.fir
@@ -0,0 +1,14 @@
+// RUN: fir-opt --split-input-file --stack-reclaim %s | FileCheck %s
+
+func.func @alloca_in_loop(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) {
+ fir.do_loop %iv = %lb to %ub step %step unordered {
+ %0 = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
+ }
+ return
+}
+
+// CHECK-LABEL: func.func @alloca_in_loop
+// CHECK: fir.do_loop
+// CHECK: %[[STACKPTR:.*]] = llvm.intr.stacksave : !llvm.ptr
+// CHECK: %{{.*}} = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
+// CHECK: llvm.intr.stackrestore %0 : !llvm.ptr
diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp
index 0bbc7fede699..86c471d2c629 100644
--- a/flang/unittests/Evaluate/intrinsics.cpp
+++ b/flang/unittests/Evaluate/intrinsics.cpp
@@ -344,6 +344,7 @@ void TestIntrinsics() {
TEST(table.GetGenericIntrinsicName("dcos") == "cos");
TEST(table.GetGenericIntrinsicName("dcosh") == "cosh");
TEST(table.GetGenericIntrinsicName("ddim") == "dim");
+ TEST(table.GetGenericIntrinsicName("derf") == "erf");
TEST(table.GetGenericIntrinsicName("dexp") == "exp");
TEST(table.GetGenericIntrinsicName("dint") == "aint");
TEST(table.GetGenericIntrinsicName("dlog") == "log");
diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp
index 123f428cc8b4..bdf5a23fdbf6 100644
--- a/flang/unittests/Frontend/FrontendActionTest.cpp
+++ b/flang/unittests/Frontend/FrontendActionTest.cpp
@@ -143,7 +143,7 @@ TEST_F(FrontendActionTest, PrintPreprocessedInput) {
EXPECT_TRUE(success);
EXPECT_TRUE(!outputFileBuffer.empty());
EXPECT_TRUE(
- llvm::StringRef(outputFileBuffer.data()).starts_with("program b\n"));
+ llvm::StringRef(outputFileBuffer.data()).starts_with(" program b\n"));
}
TEST_F(FrontendActionTest, ParseSyntaxOnly) {
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 08daa4ba37f2..20bd7a5b5ff3 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -311,8 +311,8 @@ TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
bool wait{true};
- OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
- OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
+ OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
+ OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
RTNAME(ExecuteCommandLine)
@@ -339,40 +339,91 @@ TEST_F(ZeroArguments, ECLValidCommandStatusSetSync) {
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
-TEST_F(ZeroArguments, ECLInvalidCommandErrorSync) {
- OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
+TEST_F(ZeroArguments, ECLGeneralErrorCommandErrorSync) {
+ OwningPtr<Descriptor> command{CharDescriptor("cat GeneralErrorCommand")};
+ bool wait{true};
+ OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
+ OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
+ OwningPtr<Descriptor> cmdMsg{CharDescriptor("cmd msg buffer XXXXXXXXXXXXXX")};
+
+ RTNAME(ExecuteCommandLine)
+ (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
+#ifdef _WIN32
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
+ CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXXXXXXX");
+#else
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 3);
+ CheckDescriptorEqStr(cmdMsg.get(), "Command line execution failed");
+#endif
+}
+
+TEST_F(ZeroArguments, ECLNotExecutedCommandErrorSync) {
+ OwningPtr<Descriptor> command{CharDescriptor(
+ "touch NotExecutedCommandFile && chmod -x NotExecutedCommandFile && "
+ "./NotExecutedCommandFile")};
+ bool wait{true};
+ OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
+ OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
+ OwningPtr<Descriptor> cmdMsg{CharDescriptor("cmd msg buffer XXXXXXXX")};
+
+ RTNAME(ExecuteCommandLine)
+ (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
+#ifdef _WIN32
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
+ CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXX");
+#else
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 126);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 4);
+ CheckDescriptorEqStr(cmdMsg.get(), "Command cannot be execu");
+ // removing the file only on Linux (file is not created on Win)
+ OwningPtr<Descriptor> commandClean{
+ CharDescriptor("rm -f NotExecutedCommandFile")};
+ OwningPtr<Descriptor> cmdMsgNoErr{CharDescriptor("No Error")};
+ RTNAME(ExecuteCommandLine)
+ (*commandClean.get(), wait, exitStat.get(), cmdStat.get(), cmdMsgNoErr.get());
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
+ CheckDescriptorEqStr(cmdMsgNoErr.get(), "No Error");
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
+#endif
+}
+
+TEST_F(ZeroArguments, ECLNotFoundCommandErrorSync) {
+ OwningPtr<Descriptor> command{CharDescriptor("NotFoundCommand")};
bool wait{true};
OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
- OwningPtr<Descriptor> cmdMsg{CharDescriptor("Message ChangedXXXXXXXXX")};
+ OwningPtr<Descriptor> cmdMsg{CharDescriptor("unmodified buffer XXXXXXXXX")};
RTNAME(ExecuteCommandLine)
(*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
#ifdef _WIN32
- CheckDescriptorEqInt(exitStat.get(), 1);
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
+ CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXXXXX");
#else
CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 127);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 5);
+ CheckDescriptorEqStr(cmdMsg.get(), "Command not found with exit");
#endif
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 3);
- CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXX");
}
TEST_F(ZeroArguments, ECLInvalidCommandTerminatedSync) {
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
bool wait{true};
- OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No Change")};
#ifdef _WIN32
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()),
+ *command.get(), wait, nullptr, nullptr, cmdMsg.get()),
"Invalid command quit with exit status code: 1");
#else
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()),
- "Invalid command quit with exit status code: 127");
+ *command.get(), wait, nullptr, nullptr, cmdMsg.get()),
+ "Command not found with exit code: 127.");
#endif
- CheckDescriptorEqInt(exitStat.get(), 404);
CheckDescriptorEqStr(cmdMsg.get(), "No Change");
}
@@ -394,13 +445,10 @@ TEST_F(ZeroArguments, ECLValidCommandAndExitStatNoChangeAndCMDStatusSetAsync) {
TEST_F(ZeroArguments, ECLInvalidCommandParentNotTerminatedAsync) {
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
bool wait{false};
- OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()));
-
- CheckDescriptorEqInt(exitStat.get(), 404);
+ *command.get(), wait, nullptr, nullptr, cmdMsg.get()));
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
diff --git a/flang/unittests/Runtime/Inquiry.cpp b/flang/unittests/Runtime/Inquiry.cpp
index 665a930ee4ff..3b523e992a31 100644
--- a/flang/unittests/Runtime/Inquiry.cpp
+++ b/flang/unittests/Runtime/Inquiry.cpp
@@ -14,7 +14,7 @@
using namespace Fortran::runtime;
using Fortran::common::TypeCategory;
-TEST(Inquiry, Lbound) {
+TEST(Inquiry, LboundDim) {
// ARRAY 1 3 5
// 2 4 6
auto array{MakeArray<TypeCategory::Integer, 4>(
@@ -26,6 +26,42 @@ TEST(Inquiry, Lbound) {
EXPECT_EQ(RTNAME(LboundDim)(*array, 2, __FILE__, __LINE__), std::int64_t{-1});
}
+TEST(Inquiry, Lbound) {
+ // ARRAY 1 3 5
+ // 2 4 6
+ auto array{MakeArray<TypeCategory::Integer, 4>(
+ std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
+ array->GetDimension(0).SetLowerBound(0);
+ array->GetDimension(1).SetLowerBound(-1);
+
+ // LBOUND(ARRAY, KIND=1)
+ auto int8Result{
+ MakeArray<TypeCategory::Integer, 1>(std::vector<int>{array->rank()},
+ std::vector<std::int8_t>(array->rank(), 0))};
+ RTNAME(Lbound)
+ (int8Result->raw().base_addr, *array, /*KIND=*/1, __FILE__, __LINE__);
+ EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(0), 0);
+ EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(1), -1);
+
+ // LBOUND(ARRAY, KIND=4)
+ auto int32Result{
+ MakeArray<TypeCategory::Integer, 4>(std::vector<int>{array->rank()},
+ std::vector<std::int32_t>(array->rank(), 0))};
+ RTNAME(Lbound)
+ (int32Result->raw().base_addr, *array, /*KIND=*/4, __FILE__, __LINE__);
+ EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(0), 0);
+ EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(1), -1);
+
+ // LBOUND(ARRAY, KIND=8)
+ auto int64Result{
+ MakeArray<TypeCategory::Integer, 8>(std::vector<int>{array->rank()},
+ std::vector<std::int64_t>(array->rank(), 0))};
+ RTNAME(Lbound)
+ (int64Result->raw().base_addr, *array, /*KIND=*/8, __FILE__, __LINE__);
+ EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(0), 0);
+ EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(1), -1);
+}
+
TEST(Inquiry, Ubound) {
// ARRAY 1 3 5
// 2 4 6
@@ -33,35 +69,33 @@ TEST(Inquiry, Ubound) {
std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
array->GetDimension(0).SetLowerBound(1000);
array->GetDimension(1).SetLowerBound(1);
- StaticDescriptor<2, true> statDesc;
-
- int intValue{1};
- SubscriptValue extent[]{2};
- Descriptor &result{statDesc.descriptor()};
- result.Establish(TypeCategory::Integer, /*KIND=*/4,
- static_cast<void *>(&intValue), 1, extent, CFI_attribute_pointer);
- RTNAME(Ubound)(result, *array, /*KIND=*/4, __FILE__, __LINE__);
- EXPECT_EQ(result.rank(), 1);
- EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Integer, 4}.raw()));
- // The lower bound of UBOUND's result array is always 1
- EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
- EXPECT_EQ(result.GetDimension(0).Extent(), 2);
- EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int32_t>(0), 1001);
- EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int32_t>(1), 3);
- result.Destroy();
-
- result = statDesc.descriptor();
- result.Establish(TypeCategory::Integer, /*KIND=*/1,
- static_cast<void *>(&intValue), 1, extent, CFI_attribute_pointer);
- RTNAME(Ubound)(result, *array, /*KIND=*/1, __FILE__, __LINE__);
- EXPECT_EQ(result.rank(), 1);
- EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Integer, 1}.raw()));
- // The lower bound of UBOUND's result array is always 1
- EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
- EXPECT_EQ(result.GetDimension(0).Extent(), 2);
- EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int8_t>(0), -23);
- EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int8_t>(1), 3);
- result.Destroy();
+
+ // UBOUND(ARRAY, KIND=1)
+ auto int8Result{
+ MakeArray<TypeCategory::Integer, 1>(std::vector<int>{array->rank()},
+ std::vector<std::int8_t>(array->rank(), 0))};
+ RTNAME(Ubound)
+ (int8Result->raw().base_addr, *array, /*KIND=*/1, __FILE__, __LINE__);
+ EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(0), -23);
+ EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(1), 3);
+
+ // UBOUND(ARRAY, KIND=4)
+ auto int32Result{
+ MakeArray<TypeCategory::Integer, 4>(std::vector<int>{array->rank()},
+ std::vector<std::int32_t>(array->rank(), 0))};
+ RTNAME(Ubound)
+ (int32Result->raw().base_addr, *array, /*KIND=*/4, __FILE__, __LINE__);
+ EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(0), 1001);
+ EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(1), 3);
+
+ // UBOUND(ARRAY, KIND=8)
+ auto int64Result{
+ MakeArray<TypeCategory::Integer, 8>(std::vector<int>{array->rank()},
+ std::vector<std::int64_t>(array->rank(), 0))};
+ RTNAME(Ubound)
+ (int64Result->raw().base_addr, *array, /*KIND=*/8, __FILE__, __LINE__);
+ EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(0), 1001);
+ EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(1), 3);
}
TEST(Inquiry, Size) {
@@ -87,7 +121,8 @@ TEST(Inquiry, Shape) {
auto int8Result{
MakeArray<TypeCategory::Integer, 1>(std::vector<int>{array->rank()},
std::vector<std::int8_t>(array->rank(), 0))};
- RTNAME(Shape)(int8Result->raw().base_addr, *array, /*KIND=*/1);
+ RTNAME(Shape)
+ (int8Result->raw().base_addr, *array, /*KIND=*/1, __FILE__, __LINE__);
EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(0), 2);
EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(1), 3);
@@ -95,7 +130,8 @@ TEST(Inquiry, Shape) {
auto int32Result{
MakeArray<TypeCategory::Integer, 4>(std::vector<int>{array->rank()},
std::vector<std::int32_t>(array->rank(), 0))};
- RTNAME(Shape)(int32Result->raw().base_addr, *array, /*KIND=*/4);
+ RTNAME(Shape)
+ (int32Result->raw().base_addr, *array, /*KIND=*/4, __FILE__, __LINE__);
EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(0), 2);
EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(1), 3);
@@ -103,7 +139,8 @@ TEST(Inquiry, Shape) {
auto int64Result{
MakeArray<TypeCategory::Integer, 8>(std::vector<int>{array->rank()},
std::vector<std::int64_t>(array->rank(), 0))};
- RTNAME(Shape)(int64Result->raw().base_addr, *array, /*KIND=*/8);
+ RTNAME(Shape)
+ (int64Result->raw().base_addr, *array, /*KIND=*/8, __FILE__, __LINE__);
EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(0), 2);
EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(1), 3);
}
diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index b69ff21ea79f..9f77e1657078 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -31,6 +31,14 @@ TEST(Numeric, Floor) {
EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0);
}
+TEST(Numeric, Erfc_scaled) {
+ EXPECT_NEAR(RTNAME(ErfcScaled4)(Real<4>{20.0}), 0.02817434874, 1.0e-8);
+ EXPECT_NEAR(RTNAME(ErfcScaled8)(Real<8>{20.0}), 0.02817434874, 1.0e-11);
+#if LDBL_MANT_DIG == 64
+ EXPECT_NEAR(RTNAME(ErfcScaled10)(Real<10>{20.0}), 0.02817434874, 1.0e-8);
+#endif
+}
+
TEST(Numeric, Exponent) {
EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
diff --git a/flang/unittests/Runtime/Reduction.cpp b/flang/unittests/Runtime/Reduction.cpp
index b2661e78abdf..41c8d86c35b7 100644
--- a/flang/unittests/Runtime/Reduction.cpp
+++ b/flang/unittests/Runtime/Reduction.cpp
@@ -647,23 +647,24 @@ static std::int32_t IMultiply(const std::int32_t *x, const std::int32_t *y) {
TEST(Reductions, ReduceInt4) {
auto intVector{MakeArray<TypeCategory::Integer, 4>(
std::vector<int>{4}, std::vector<std::int32_t>{1, 2, 3, 4})};
- EXPECT_EQ(RTNAME(ReduceInteger4)(*intVector, IAdd, __FILE__, __LINE__), 10);
EXPECT_EQ(
- RTNAME(ReduceInteger4)(*intVector, IMultiply, __FILE__, __LINE__), 24);
+ RTNAME(ReduceInteger4Ref)(*intVector, IAdd, __FILE__, __LINE__), 10);
+ EXPECT_EQ(
+ RTNAME(ReduceInteger4Ref)(*intVector, IMultiply, __FILE__, __LINE__), 24);
}
TEST(Reductions, ReduceInt4Dim) {
auto intMatrix{MakeArray<TypeCategory::Integer, 4>(
std::vector<int>{2, 2}, std::vector<std::int32_t>{1, 2, 3, 4})};
StaticDescriptor<1, true> statDesc;
Descriptor &sums{statDesc.descriptor()};
- RTNAME(ReduceInteger4Dim)(sums, *intMatrix, IAdd, __FILE__, __LINE__, 1);
+ RTNAME(ReduceInteger4DimRef)(sums, *intMatrix, IAdd, __FILE__, __LINE__, 1);
EXPECT_EQ(sums.rank(), 1);
EXPECT_EQ(sums.GetDimension(0).LowerBound(), 1);
EXPECT_EQ(sums.GetDimension(0).Extent(), 2);
EXPECT_EQ(*sums.ZeroBasedIndexedElement<std::int32_t>(0), 3);
EXPECT_EQ(*sums.ZeroBasedIndexedElement<std::int32_t>(1), 7);
sums.Destroy();
- RTNAME(ReduceInteger4Dim)(sums, *intMatrix, IAdd, __FILE__, __LINE__, 2);
+ RTNAME(ReduceInteger4DimRef)(sums, *intMatrix, IAdd, __FILE__, __LINE__, 2);
EXPECT_EQ(sums.rank(), 1);
EXPECT_EQ(sums.GetDimension(0).LowerBound(), 1);
EXPECT_EQ(sums.GetDimension(0).Extent(), 2);