diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 8dbc9df9f553d..497d099fbe936 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2494,6 +2494,21 @@ def fir_CallOp : fir_Op<"call", llvm::cast(callee)); setOperand(0, llvm::cast(callee)); } + + /// Always allow FastMathFlags for fir.call's. + /// It is required to be able to propagate the call site's + /// FastMathFlags to the operations resulting from inlining + /// (if any) of a fir.call (see SimplifyIntrinsics pass). + /// We could analyze the arguments' data types to see if there are + /// any floating point types, but this is unreliable. For example, + /// the runtime calls mostly take !fir.box arguments, + /// and tracking them to the definitions may be not easy. + /// TODO: this should be restricted to fir.runtime calls, + /// because FastMathFlags for the user calls must come + /// from the function body, not the call site. + bool isArithFastMathApplicable() { + return true; + } }]; } @@ -2672,6 +2687,15 @@ def fir_CmpcOp : fir_Op<"cmpc", } static mlir::arith::CmpFPredicate getPredicateByName(llvm::StringRef name); + + /// Always allow FastMathFlags on fir.cmpc. + /// It does not produce a floating point result, but + /// LLVM is currently relying on fast-math flags attached + /// to floating point comparison. + /// This can be removed whenever LLVM stops doing it. + bool isArithFastMathApplicable() { + return true; + } }]; } @@ -2735,6 +2759,8 @@ def fir_ConvertOp : fir_SimpleOneResultOp<"convert", [NoMemoryEffect]> { static bool isPointerCompatible(mlir::Type ty); static bool canBeConverted(mlir::Type inType, mlir::Type outType); static bool areVectorsCompatible(mlir::Type inTy, mlir::Type outTy); + + // FIXME: fir.convert should support ArithFastMathInterface. }]; let hasCanonicalizer = 1; } diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h index 15296aa7e8c75..0e6d536d9bde5 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h +++ b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h @@ -139,6 +139,11 @@ bool mayHaveAllocatableComponent(mlir::Type ty); /// Scalar integer or a sequence of integers (via boxed array or expr). bool isFortranIntegerScalarOrArrayObject(mlir::Type type); +/// Return true iff FastMathFlagsAttr is applicable +/// to the given HLFIR dialect operation that supports +/// ArithFastMathInterface. +bool isArithFastMathApplicable(mlir::Operation *op); + } // namespace hlfir #endif // FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td index f4102538efc3c..f90ef8ed019ce 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td @@ -434,6 +434,12 @@ def hlfir_MaxvalOp : hlfir_Op<"maxval", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_MinvalOp : hlfir_Op<"minval", [AttrSizedOperandSegments, @@ -461,6 +467,12 @@ def hlfir_MinvalOp : hlfir_Op<"minval", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_MinlocOp : hlfir_Op<"minloc", [AttrSizedOperandSegments, @@ -487,6 +499,12 @@ def hlfir_MinlocOp : hlfir_Op<"minloc", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_MaxlocOp : hlfir_Op<"maxloc", [AttrSizedOperandSegments, @@ -513,6 +531,12 @@ def hlfir_MaxlocOp : hlfir_Op<"maxloc", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments, @@ -539,6 +563,12 @@ def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_SetLengthOp : hlfir_Op<"set_length", @@ -604,6 +634,12 @@ def hlfir_SumOp : hlfir_Op<"sum", [AttrSizedOperandSegments, }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_DotProductOp : hlfir_Op<"dot_product", @@ -628,6 +664,12 @@ def hlfir_DotProductOp : hlfir_Op<"dot_product", }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_MatmulOp : hlfir_Op<"matmul", @@ -655,6 +697,12 @@ def hlfir_MatmulOp : hlfir_Op<"matmul", let hasCanonicalizeMethod = 1; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_TransposeOp : hlfir_Op<"transpose", @@ -697,6 +745,12 @@ def hlfir_MatmulTransposeOp : hlfir_Op<"matmul_transpose", }]; let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool isArithFastMathApplicable() { + return hlfir::isArithFastMathApplicable(getOperation()); + } + }]; } def hlfir_CShiftOp diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index d9779c46ae79e..d749fc9c633d7 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -786,9 +786,7 @@ mlir::Value fir::FirOpBuilder::genAbsentOp(mlir::Location loc, void fir::FirOpBuilder::setCommonAttributes(mlir::Operation *op) const { auto fmi = mlir::dyn_cast(*op); - if (fmi) { - // TODO: use fmi.setFastMathFlagsAttr() after D137114 is merged. - // For now set the attribute by the name. + if (fmi && fmi.isArithFastMathApplicable()) { llvm::StringRef arithFMFAttrName = fmi.getFastMathAttrName(); if (fastMathFlags != mlir::arith::FastMathFlags::none) op->setAttr(arithFMFAttrName, mlir::arith::FastMathFlagsAttr::get( diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index cb4eb8303a495..109524635b3b6 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -589,10 +589,15 @@ struct CallOpConversion : public fir::FIROpConversion { // Convert arith::FastMathFlagsAttr to LLVM::FastMathFlagsAttr. mlir::arith::AttrConvertFastMathToLLVM attrConvert(call); - rewriter.replaceOpWithNewOp( - call, resultTys, adaptor.getOperands(), + auto llvmCall = rewriter.create( + call.getLoc(), resultTys, adaptor.getOperands(), addLLVMOpBundleAttrs(rewriter, attrConvert.getAttrs(), adaptor.getOperands().size())); + auto fmi = + mlir::cast(llvmCall.getOperation()); + if (!fmi.isFastmathApplicable()) + llvmCall.setFastmathFlags(mlir::LLVM::FastmathFlags::none); + rewriter.replaceOp(call, llvmCall); return mlir::success(); } }; diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp index cb77aef74acd5..254e579a66b90 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp @@ -237,3 +237,20 @@ bool hlfir::isFortranIntegerScalarOrArrayObject(mlir::Type type) { mlir::Type elementType = getFortranElementType(unwrappedType); return mlir::isa(elementType); } + +bool hlfir::isArithFastMathApplicable(mlir::Operation *op) { + if (llvm::any_of(op->getResults(), [](mlir::Value v) { + mlir::Type elementType = getFortranElementType(v.getType()); + return mlir::arith::ArithFastMathInterface::isCompatibleType( + elementType); + })) + return true; + if (llvm::any_of(op->getOperands(), [](mlir::Value v) { + mlir::Type elementType = getFortranElementType(v.getType()); + return mlir::arith::ArithFastMathInterface::isCompatibleType( + elementType); + })) + return true; + + return false; +} diff --git a/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir b/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir index 0827e378c7c07..b04188d3ee1d9 100644 --- a/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir +++ b/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir @@ -56,7 +56,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : ve %45 = llvm.call @_FortranACUFDataTransferPtrPtr(%14, %25, %2, %11, %13, %5) : (!llvm.ptr, !llvm.ptr, i64, i32, !llvm.ptr, i32) -> !llvm.struct<()> gpu.launch_func @cuda_device_mod::@_QMmod1Psub1 blocks in (%7, %7, %7) threads in (%12, %7, %7) : i64 dynamic_shared_memory_size %11 args(%14 : !llvm.ptr) %46 = llvm.call @_FortranACUFDataTransferPtrPtr(%25, %14, %2, %10, %13, %4) : (!llvm.ptr, !llvm.ptr, i64, i32, !llvm.ptr, i32) -> !llvm.struct<()> - %47 = llvm.call @_FortranAioBeginExternalListOutput(%9, %13, %8) {fastmathFlags = #llvm.fastmath} : (i32, !llvm.ptr, i32) -> !llvm.ptr + %47 = llvm.call @_FortranAioBeginExternalListOutput(%9, %13, %8) : (i32, !llvm.ptr, i32) -> !llvm.ptr %48 = llvm.mlir.constant(9 : i32) : i32 %49 = llvm.mlir.zero : !llvm.ptr %50 = llvm.getelementptr %49[1] : (!llvm.ptr) -> !llvm.ptr, i32 diff --git a/flang/test/Fir/tbaa.fir b/flang/test/Fir/tbaa.fir index 401ebbc8c49fe..c2c9ad362370f 100644 --- a/flang/test/Fir/tbaa.fir +++ b/flang/test/Fir/tbaa.fir @@ -136,7 +136,7 @@ module { // CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(-1 : i32) : i32 // CHECK: %[[VAL_7:.*]] = llvm.mlir.addressof @_QFEx : !llvm.ptr // CHECK: %[[VAL_8:.*]] = llvm.mlir.addressof @_QQclX2E2F64756D6D792E66393000 : !llvm.ptr -// CHECK: %[[VAL_10:.*]] = llvm.call @_FortranAioBeginExternalListOutput(%[[VAL_6]], %[[VAL_8]], %[[VAL_5]]) {fastmathFlags = #llvm.fastmath} : (i32, !llvm.ptr, i32) -> !llvm.ptr +// CHECK: %[[VAL_10:.*]] = llvm.call @_FortranAioBeginExternalListOutput(%[[VAL_6]], %[[VAL_8]], %[[VAL_5]]) : (i32, !llvm.ptr, i32) -> !llvm.ptr // CHECK: %[[VAL_11:.*]] = llvm.mlir.constant(64 : i32) : i32 // CHECK: "llvm.intr.memcpy"(%[[VAL_3]], %[[VAL_7]], %[[VAL_11]]) <{isVolatile = false, tbaa = [#[[$BOXT]]]}> // CHECK: %[[VAL_12:.*]] = llvm.getelementptr %[[VAL_3]][0, 7, %[[VAL_4]], 0] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)> @@ -188,8 +188,8 @@ module { // CHECK: %[[VAL_59:.*]] = llvm.insertvalue %[[VAL_50]], %[[VAL_58]][7, 0, 2] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)> // CHECK: %[[VAL_61:.*]] = llvm.insertvalue %[[VAL_52]], %[[VAL_59]][0] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)> // CHECK: llvm.store %[[VAL_61]], %[[VAL_1]] {tbaa = [#[[$BOXT]]]} : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>, !llvm.ptr -// CHECK: %[[VAL_63:.*]] = llvm.call @_FortranAioOutputDescriptor(%[[VAL_10]], %[[VAL_1]]) {fastmathFlags = #llvm.fastmath} : (!llvm.ptr, !llvm.ptr) -> i1 -// CHECK: %[[VAL_64:.*]] = llvm.call @_FortranAioEndIoStatement(%[[VAL_10]]) {fastmathFlags = #llvm.fastmath} : (!llvm.ptr) -> i32 +// CHECK: %[[VAL_63:.*]] = llvm.call @_FortranAioOutputDescriptor(%[[VAL_10]], %[[VAL_1]]) : (!llvm.ptr, !llvm.ptr) -> i1 +// CHECK: %[[VAL_64:.*]] = llvm.call @_FortranAioEndIoStatement(%[[VAL_10]]) : (!llvm.ptr) -> i32 // CHECK: llvm.return // CHECK: } // CHECK: llvm.func @_FortranAioBeginExternalListOutput(i32, !llvm.ptr, i32) -> !llvm.ptr attributes {fir.io, fir.runtime, sym_visibility = "private"} diff --git a/flang/test/HLFIR/dot_product-lowering.fir b/flang/test/HLFIR/dot_product-lowering.fir index 64d65665433f1..f3d90c7cedd87 100644 --- a/flang/test/HLFIR/dot_product-lowering.fir +++ b/flang/test/HLFIR/dot_product-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPdot_product1(%arg0: !fir.box> {fir.bindc_name = %0:2 = hlfir.declare %arg0 {uniq_name = "_QFdot_product1Elhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFdot_product1Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFdot_product1Erhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.dot_product %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> i32 + %3 = hlfir.dot_product %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> i32 hlfir.assign %3 to %1#0 : i32, !fir.ref return } @@ -29,7 +29,7 @@ func.func @_QPdot_product2(%arg0: !fir.box>> {fir.b %0:2 = hlfir.declare %arg0 {uniq_name = "_QFdot_product2Elhs"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFdot_product2Eres"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFdot_product2Erhs"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) - %3 = hlfir.dot_product %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !fir.logical<4> + %3 = hlfir.dot_product %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !fir.logical<4> hlfir.assign %3 to %1#0 : !fir.logical<4>, !fir.ref> return } @@ -58,7 +58,7 @@ func.func @_QPdot_product2(%arg0: !fir.box>> {fir.b %c5_0 = arith.constant 5 : index %3 = fir.shape %c5_0 : (index) -> !fir.shape<1> %4:2 = hlfir.declare %arg1(%3) {uniq_name = "_QFdot_product3Erhs"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) - %5 = hlfir.dot_product %1#0 %4#0 {fastmath = #arith.fastmath} : (!fir.ref>, !fir.ref>) -> i32 + %5 = hlfir.dot_product %1#0 %4#0 {fastmath = #arith.fastmath} : (!fir.ref>, !fir.ref>) -> i32 hlfir.assign %5 to %2#0 : i32, !fir.ref return } @@ -86,7 +86,7 @@ func.func @_QPdot_product4(%arg0: !fir.box>> {fir.b %temp = fir.alloca !fir.logical<4> %0:2 = hlfir.declare %arg0 {uniq_name = "_QFdot_product2Elhs"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFdot_product2Erhs"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) - %2 = hlfir.dot_product %0#0 %1#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !fir.logical<4> + %2 = hlfir.dot_product %0#0 %1#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !fir.logical<4> fir.store %2 to %temp : !fir.ref> return } @@ -98,8 +98,34 @@ func.func @_QPdot_product4(%arg0: !fir.box>> {fir.b // CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFdot_product2Erhs"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) // CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.box>>) -> !fir.box // CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_12:.*]] = fir.call @_FortranADotProductLogical(%[[VAL_9]], %[[VAL_10]], %{{.*}}, %{{.*}}) fastmath : (!fir.box, !fir.box, !fir.ref, i32) -> i1 +// CHECK: %[[VAL_12:.*]] = fir.call @_FortranADotProductLogical(%[[VAL_9]], %[[VAL_10]], %{{.*}}, %{{.*}}) : (!fir.box, !fir.box, !fir.ref, i32) -> i1 // CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<4> // CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref> // CHECK: return // CHECK: } + +// floating point dot_product +func.func @_QPdot_product5(%arg0: !fir.box> {fir.bindc_name = "lhs"}, %arg1: !fir.box> {fir.bindc_name = "rhs"}, %arg2: !fir.ref {fir.bindc_name = "res"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFdot_product1Elhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFdot_product1Eres"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFdot_product1Erhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %3 = hlfir.dot_product %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> f32 + hlfir.assign %3 to %1#0 : f32, !fir.ref + return +} +// CHECK-LABEL: func.func @_QPdot_product5( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "lhs"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "rhs"} +// CHECK: %[[ARG2:.*]]: !fir.ref {fir.bindc_name = "res"} +// CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[ARG0]] +// CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[ARG1]] +// CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[ARG2]] + +// CHECK-DAG: %[[LHS_ARG:.*]] = fir.convert %[[LHS_VAR]]#1 : (!fir.box>) -> !fir.box +// CHECK-DAG: %[[RHS_ARG:.*]] = fir.convert %[[RHS_VAR]]#1 : (!fir.box>) -> !fir.box + +// CHECK: %[[RES_VAL:.*]] = fir.call @_FortranADotProductReal4(%[[LHS_ARG]], %[[RHS_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) fastmath +// CHECK-NEXT: hlfir.assign %[[RES_VAL]] to %[[RES_VAR]]#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } + diff --git a/flang/test/HLFIR/matmul-lowering.fir b/flang/test/HLFIR/matmul-lowering.fir index 51a859401bf4a..c99c2da0d3289 100644 --- a/flang/test/HLFIR/matmul-lowering.fir +++ b/flang/test/HLFIR/matmul-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPmatmul1(%arg0: !fir.box> {fir.bindc_name = "lh %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmatmul1Elhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmatmul1Eres"} : (!fir.box>) -> (!fir.box>, !fir.box>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmatmul1Erhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.matmul %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> !hlfir.expr + %3 = hlfir.matmul %0#0 %2#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> !hlfir.expr hlfir.assign %3 to %1#0 : !hlfir.expr, !fir.box> hlfir.destroy %3 : !hlfir.expr return @@ -29,7 +29,7 @@ func.func @_QPmatmul1(%arg0: !fir.box> {fir.bindc_name = "lh // CHECK: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] : (!fir.ref>>>) -> !fir.ref> // CHECK-DAG: %[[LHS_ARG:.*]] = fir.convert %[[LHS_VAR]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[RHS_ARG:.*]] = fir.convert %[[RHS_VAR]]#1 : (!fir.box>) -> !fir.box -// CHECK: fir.call @_FortranAMatmulInteger4Integer4(%[[RET_ARG]], %[[LHS_ARG]], %[[RHS_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) fastmath +// CHECK: fir.call @_FortranAMatmulInteger4Integer4(%[[RET_ARG]], %[[LHS_ARG]], %[[RHS_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]]) // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK-DAG: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] diff --git a/flang/test/HLFIR/maxloc-elemental.fir b/flang/test/HLFIR/maxloc-elemental.fir index c9210a59f0340..b6d5508f85b8c 100644 --- a/flang/test/HLFIR/maxloc-elemental.fir +++ b/flang/test/HLFIR/maxloc-elemental.fir @@ -16,7 +16,7 @@ func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"} %11 = fir.convert %10 : (i1) -> !fir.logical<4> hlfir.yield_element %11 : !fir.logical<4> } - %7 = hlfir.maxloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + %7 = hlfir.maxloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> hlfir.destroy %7 : !hlfir.expr<1xi32> hlfir.destroy %6 : !hlfir.expr> diff --git a/flang/test/HLFIR/maxloc-lowering.fir b/flang/test/HLFIR/maxloc-lowering.fir index be52627564c49..aa407fe6641b1 100644 --- a/flang/test/HLFIR/maxloc-lowering.fir +++ b/flang/test/HLFIR/maxloc-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPmaxloc1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr + %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> hlfir.destroy %2 : !hlfir.expr return @@ -28,7 +28,7 @@ func.func @_QPmaxloc1(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -45,7 +45,7 @@ func.func @_QPmaxloc2(%arg0: !fir.box> {fir.bindc_name = "a" %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.maxloc %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.maxloc %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -72,7 +72,7 @@ func.func @_QPmaxloc2(%arg0: !fir.box> {fir.bindc_name = "a" // CHECK: %[[V11:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V12:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V15:.*]] = fir.convert %[[V6]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V11]], %[[V12]], %[[C4]], %[[V5]], {{.*}}, {{.*}}, %[[V15]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V11]], %[[V12]], %[[C4]], %[[V5]], {{.*}}, {{.*}}, %[[V15]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V17:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V18:.*]]:3 = fir.box_dims %[[V17]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V19:.*]] = fir.box_addr %[[V17]] : (!fir.box>>) -> !fir.heap> @@ -89,7 +89,7 @@ func.func @_QPmaxloc3(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc3Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr + %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %3 : !hlfir.expr return @@ -114,7 +114,7 @@ func.func @_QPmaxloc3(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V9:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V10:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V13:.*]] = fir.convert %[[V4]] : (!fir.box>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V9]], %[[V10]], %[[C4]], {{.*}}, {{.*}}, %[[V13]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V9]], %[[V10]], %[[C4]], {{.*}}, {{.*}}, %[[V13]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V15:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V16:.*]]:3 = fir.box_dims %[[V15]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V15]] : (!fir.box>>) -> !fir.heap> @@ -131,7 +131,7 @@ func.func @_QPmaxloc4(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxloc4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr + %3 = hlfir.maxloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %3 : !hlfir.expr return @@ -155,7 +155,7 @@ func.func @_QPmaxloc4(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V2]]#1 : (!fir.box>>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -194,7 +194,7 @@ func.func @_QPmaxloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFmaxloc5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.maxloc %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.maxloc %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -226,7 +226,7 @@ func.func @_QPmaxloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK: %[[V15:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V16:.*]] = fir.convert %[[V8]] : (!fir.box>) -> !fir.box // CHECK: %[[V19:.*]] = fir.convert %[[V10]] : (!fir.box>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V15]], %[[V16]], %[[C4]], %[[C1]], {{.*}}, {{.*}}, %[[V19]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V15]], %[[V16]], %[[C4]], %[[C1]], {{.*}}, {{.*}}, %[[V19]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V21:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V22:.*]]:3 = fir.box_dims %[[V21]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V23:.*]] = fir.box_addr %[[V21]] : (!fir.box>>) -> !fir.heap> @@ -242,7 +242,7 @@ func.func @_QPmaxloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) func.func @_QPmaxloc6(%arg0: !fir.box>> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr + %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> hlfir.destroy %2 : !hlfir.expr return @@ -265,7 +265,7 @@ func.func @_QPmaxloc6(%arg0: !fir.box>> {fir.bindc_n // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocCharacter(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocCharacter(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -285,7 +285,7 @@ func.func @_QPmaxloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, %3:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEm"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %4:2 = hlfir.declare %arg4 {uniq_name = "_QFFtestEs"} : (!fir.box>) -> (!fir.box>, !fir.box>) %5 = fir.load %2#0 : !fir.ref - %6 = hlfir.maxloc %0#0 dim %5 mask %3#0 {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> i32 + %6 = hlfir.maxloc %0#0 dim %5 mask %3#0 {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> i32 hlfir.assign %6 to %4#0 : i32, !fir.box> return } @@ -310,7 +310,7 @@ func.func @_QPmaxloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V10:.*]] = fir.convert %[[V0]] : (!fir.ref>>) -> !fir.ref> // CHECK-NEXT: %[[V11:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V14:.*]] = fir.convert %[[V4]]#1 : (!fir.box>>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V10]], %[[V11]], %[[C4]], %[[V6]], {{.*}}, {{.*}}, %[[V14]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMaxlocDim(%[[V10]], %[[V11]], %[[C4]], %[[V6]], {{.*}}, {{.*}}, %[[V14]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V16:.*]] = fir.load %[[V0]] : !fir.ref>> // CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V16]] : (!fir.box>) -> !fir.heap // CHECK-NEXT: %[[V18:.*]] = fir.load %[[V17]] : !fir.heap @@ -318,3 +318,39 @@ func.func @_QPmaxloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-NEXT: hlfir.assign %[[V18]] to %[[V5]]#0 : i32, !fir.box> // CHECK-NEXT: return +// floating point maxloc +func.func @_QPmaxloc8(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.maxloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr + hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPmaxloc8( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK-DAG: %[[TRUE:.*]] = arith.constant true +// CHECK-DAG: %[[FALSE:.*]] = arith.constant false +// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index +// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : i32 +// CHECK: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFmaxloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFmaxloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V3:.*]] = fir.absent !fir.box +// CHECK-NEXT: %[[V4:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %[[V5:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]] = fir.embox %[[V4]](%[[V5]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V6]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box +// CHECK-NEXT: fir.call @_FortranAMaxlocReal4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V17:.*]] = fir.shape_shift %[[V15]]#0, %[[V15]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V18:.*]]:2 = hlfir.declare %[[V16]](%[[V17]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %[[V19:.*]] = hlfir.as_expr %[[V18]]#0 move %[[TRUE]] : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V19]] to %[[V2]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V19]] : !hlfir.expr diff --git a/flang/test/HLFIR/maxval-elemental.fir b/flang/test/HLFIR/maxval-elemental.fir index aa642253b0832..da7529c124ced 100644 --- a/flang/test/HLFIR/maxval-elemental.fir +++ b/flang/test/HLFIR/maxval-elemental.fir @@ -24,7 +24,7 @@ func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"} %12 = arith.subi %11, %10 : i32 hlfir.yield_element %12 : i32 } - %7 = hlfir.maxval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 + %7 = hlfir.maxval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 hlfir.assign %7 to %3#0 : i32, !fir.ref hlfir.destroy %6 : !hlfir.expr return diff --git a/flang/test/HLFIR/maxval-lowering.fir b/flang/test/HLFIR/maxval-lowering.fir index fbf75d9050544..01b01615edea2 100644 --- a/flang/test/HLFIR/maxval-lowering.fir +++ b/flang/test/HLFIR/maxval-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPmaxval1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxval1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxval1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %2 = hlfir.maxval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 + %2 = hlfir.maxval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 hlfir.assign %2 to %1#0 : i32, !fir.ref return } @@ -17,7 +17,7 @@ func.func @_QPmaxval1(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -28,7 +28,7 @@ func.func @_QPmaxval2(%arg0: !fir.box> {fir.bindc_name = "a" %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxval2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxval2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.maxval %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.maxval %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -56,7 +56,7 @@ func.func @_QPmaxval2(%arg0: !fir.box> {fir.bindc_name = "a" // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: fir.call @_FortranAMaxvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMaxvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] @@ -75,7 +75,7 @@ func.func @_QPmaxval3(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxval3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxval3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxval3Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.maxval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 + %3 = hlfir.maxval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -89,7 +89,7 @@ func.func @_QPmaxval3(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK_BOX:.*]] = fir.embox %[[MASK]]#1 : (!fir.ref>) -> !fir.box> // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -99,7 +99,7 @@ func.func @_QPmaxval4(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxval4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFmaxval4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxval4Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.maxval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 + %3 = hlfir.maxval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -112,7 +112,7 @@ func.func @_QPmaxval4(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]]#1 : (!fir.box>>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -144,7 +144,7 @@ func.func @_QPmaxval5(%arg0: !fir.ref> {fir.bindc_name = "s"}) %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFmaxval5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.maxval %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.maxval %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -175,14 +175,14 @@ func.func @_QPmaxval5(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY_BOX]] : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: fir.call @_FortranAMaxvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMaxvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // simple one argument maxval for character func.func @_QPmaxval6(%arg0: !fir.box>> {fir.bindc_name = "a"}, %arg1: !fir.boxchar<1> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxval6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref>, index) %2:2 = hlfir.declare %1#0 typeparams %1#1 {uniq_name = "_QFmaxval6Es"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) - %3 = hlfir.maxval %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> + %3 = hlfir.maxval %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> hlfir.assign %3 to %2#0 : !hlfir.expr>, !fir.boxchar<1> hlfir.destroy %3 : !hlfir.expr> return @@ -205,7 +205,7 @@ func.func @_QPmaxval6(%arg0: !fir.box>> {fir.bindc_n // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: fir.call @_FortranAMaxvalCharacter(%[[RET_ARG]], %[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMaxvalCharacter(%[[RET_ARG]], %[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_ELESIZE:.*]] = fir.box_elesize %[[RET]] @@ -238,3 +238,24 @@ func.func @_QPmaxval_opt_mask(%arg0: !fir.box> {fir.bindc_na // CHECK: %[[VAL_12:.*]] = arith.select %{{.*}}, %[[VAL_10]], %[[VAL_11]] : !fir.box> // CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_12]] : (!fir.box>) -> !fir.box // CHECK: %[[VAL_18:.*]] = fir.call @_FortranAMaxvalReal4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> f32 + +// floating point maxval +func.func @_QPmaxval_fp(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmaxval1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFmaxval1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2 = hlfir.maxval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %2 to %1#0 : f32, !fir.ref + return +} +// CHECK-LABEL: func.func @_QPmaxval_fp( +// CHECK: %[[ARG0:.*]]: !fir.box> +// CHECK: %[[ARG1:.*]]: !fir.ref +// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]] +// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box +// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box +// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box +// CHECK: %[[RET:.*]] = fir.call @_FortranAMaxvalReal4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> f32 +// CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } diff --git a/flang/test/HLFIR/minloc-elemental.fir b/flang/test/HLFIR/minloc-elemental.fir index 9453a335b4fbf..dc355b58c234b 100644 --- a/flang/test/HLFIR/minloc-elemental.fir +++ b/flang/test/HLFIR/minloc-elemental.fir @@ -16,7 +16,7 @@ func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"} %11 = fir.convert %10 : (i1) -> !fir.logical<4> hlfir.yield_element %11 : !fir.logical<4> } - %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> hlfir.destroy %7 : !hlfir.expr<1xi32> hlfir.destroy %6 : !hlfir.expr> @@ -89,7 +89,7 @@ func.func @_QPtest_kind2(%arg0: !fir.box> {fir.bindc_name = "a %11 = fir.convert %10 : (i1) -> !fir.logical<4> hlfir.yield_element %11 : !fir.logical<4> } - %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> hlfir.assign %7 to %1#0 : !hlfir.expr<1xi16>, !fir.box> hlfir.destroy %7 : !hlfir.expr<1xi16> hlfir.destroy %6 : !hlfir.expr> @@ -162,7 +162,7 @@ func.func @_QPtest_kind2_convert(%arg0: !fir.box> {fir.bindc_n %13 = fir.convert %12 : (i1) -> !fir.logical<4> hlfir.yield_element %13 : !fir.logical<4> } - %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> %8 = fir.shape %c1 : (index) -> !fir.shape<1> %9 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr { ^bb0(%arg3: index): @@ -348,7 +348,7 @@ func.func @_QFPtest_character(%arg0: !fir.box>> {fir.b %19 = fir.convert %18 : (i1) -> !fir.logical<4> hlfir.yield_element %19 : !fir.logical<4> } - %12 = hlfir.minloc %0#0 mask %11 {fastmath = #arith.fastmath} : (!fir.box>>, !hlfir.expr>) -> !hlfir.expr<1xi32> + %12 = hlfir.minloc %0#0 mask %11 {fastmath = #arith.fastmath} : (!fir.box>>, !hlfir.expr>) -> !hlfir.expr<1xi32> hlfir.assign %12 to %4#0 : !hlfir.expr<1xi32>, !fir.ref> hlfir.destroy %12 : !hlfir.expr<1xi32> hlfir.destroy %11 : !hlfir.expr> @@ -382,7 +382,7 @@ func.func @_QPtest_parts(%arg0: !fir.box> {fir.bindc_name = "x %14 = fir.convert %13 : (i1) -> !fir.logical<4> hlfir.yield_element %14 : !fir.logical<4> } - %7 = hlfir.minloc %3#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + %7 = hlfir.minloc %3#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> %8 = fir.shape %c1 : (index) -> !fir.shape<1> %9 = hlfir.designate %3#0 (%c5:%c5:%c1) shape %8 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> hlfir.assign %7 to %9 : !hlfir.expr<1xi32>, !fir.box> diff --git a/flang/test/HLFIR/minloc-lowering.fir b/flang/test/HLFIR/minloc-lowering.fir index 76d788812e24c..2c7c0928cf8af 100644 --- a/flang/test/HLFIR/minloc-lowering.fir +++ b/flang/test/HLFIR/minloc-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPminloc1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %2 = hlfir.minloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr + %2 = hlfir.minloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> hlfir.destroy %2 : !hlfir.expr return @@ -28,7 +28,7 @@ func.func @_QPminloc1(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -45,7 +45,7 @@ func.func @_QPminloc2(%arg0: !fir.box> {fir.bindc_name = "a" %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminloc2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.minloc %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.minloc %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -72,7 +72,7 @@ func.func @_QPminloc2(%arg0: !fir.box> {fir.bindc_name = "a" // CHECK: %[[V11:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V12:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V15:.*]] = fir.convert %[[V6]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V11]], %[[V12]], %[[C4]], %[[V5]], {{.*}}, {{.*}}, %[[V15]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V11]], %[[V12]], %[[C4]], %[[V5]], {{.*}}, {{.*}}, %[[V15]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V17:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V18:.*]]:3 = fir.box_dims %[[V17]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V19:.*]] = fir.box_addr %[[V17]] : (!fir.box>>) -> !fir.heap> @@ -89,7 +89,7 @@ func.func @_QPminloc3(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminloc3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminloc3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc3Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.minloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr + %3 = hlfir.minloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %3 : !hlfir.expr return @@ -114,7 +114,7 @@ func.func @_QPminloc3(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V9:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V10:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V13:.*]] = fir.convert %[[V4]] : (!fir.box>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V9]], %[[V10]], %[[C4]], {{.*}}, {{.*}}, %[[V13]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V9]], %[[V10]], %[[C4]], {{.*}}, {{.*}}, %[[V13]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V15:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V16:.*]]:3 = fir.box_dims %[[V15]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V15]] : (!fir.box>>) -> !fir.heap> @@ -131,7 +131,7 @@ func.func @_QPminloc4(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminloc4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminloc4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %3 = hlfir.minloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr + %3 = hlfir.minloc %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr hlfir.assign %3 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %3 : !hlfir.expr return @@ -155,7 +155,7 @@ func.func @_QPminloc4(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V2]]#1 : (!fir.box>>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocInteger4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -194,7 +194,7 @@ func.func @_QPminloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFminloc5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.minloc %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.minloc %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -226,7 +226,7 @@ func.func @_QPminloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK: %[[V15:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V16:.*]] = fir.convert %[[V8]] : (!fir.box>) -> !fir.box // CHECK: %[[V19:.*]] = fir.convert %[[V10]] : (!fir.box>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V15]], %[[V16]], %[[C4]], %[[C1]], {{.*}}, {{.*}}, %[[V19]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V15]], %[[V16]], %[[C4]], %[[C1]], {{.*}}, {{.*}}, %[[V19]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V21:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V22:.*]]:3 = fir.box_dims %[[V21]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V23:.*]] = fir.box_addr %[[V21]] : (!fir.box>>) -> !fir.heap> @@ -242,7 +242,7 @@ func.func @_QPminloc5(%arg0: !fir.ref> {fir.bindc_name = "s"}) func.func @_QPminloc6(%arg0: !fir.box>> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminloc6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc4Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) - %2 = hlfir.minloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr + %2 = hlfir.minloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> hlfir.destroy %2 : !hlfir.expr return @@ -265,7 +265,7 @@ func.func @_QPminloc6(%arg0: !fir.box>> {fir.bindc_n // CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> // CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>>) -> !fir.box // CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocCharacter(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocCharacter(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> // CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) // CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> @@ -285,7 +285,7 @@ func.func @_QPminloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, %3:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEm"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %4:2 = hlfir.declare %arg4 {uniq_name = "_QFFtestEs"} : (!fir.box>) -> (!fir.box>, !fir.box>) %5 = fir.load %2#0 : !fir.ref - %6 = hlfir.minloc %0#0 dim %5 mask %3#0 {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> i32 + %6 = hlfir.minloc %0#0 dim %5 mask %3#0 {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> i32 hlfir.assign %6 to %4#0 : i32, !fir.box> return } @@ -310,7 +310,7 @@ func.func @_QPminloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK: %[[V10:.*]] = fir.convert %[[V0]] : (!fir.ref>>) -> !fir.ref> // CHECK-NEXT: %[[V11:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box // CHECK: %[[V14:.*]] = fir.convert %[[V4]]#1 : (!fir.box>>) -> !fir.box -// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V10]], %[[V11]], %[[C4]], %[[V6]], {{.*}}, {{.*}}, %[[V14]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: fir.call @_FortranAMinlocDim(%[[V10]], %[[V11]], %[[C4]], %[[V6]], {{.*}}, {{.*}}, %[[V14]], %[[FALSE]]) : (!fir.ref>, !fir.box, i32, i32, !fir.ref, i32, !fir.box, i1) -> () // CHECK-NEXT: %[[V16:.*]] = fir.load %[[V0]] : !fir.ref>> // CHECK-NEXT: %[[V17:.*]] = fir.box_addr %[[V16]] : (!fir.box>) -> !fir.heap // CHECK-NEXT: %[[V18:.*]] = fir.load %[[V17]] : !fir.heap @@ -318,3 +318,39 @@ func.func @_QPminloc7(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-NEXT: hlfir.assign %[[V18]] to %[[V5]]#0 : i32, !fir.box> // CHECK-NEXT: return +// floating point minloc +func.func @_QPminloc8(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.minloc %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr + hlfir.assign %2 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPminloc8( +// CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"} +// CHECK: %[[ARG1:.*]]: !fir.box> {fir.bindc_name = "s"} +// CHECK-DAG: %[[TRUE:.*]] = arith.constant true +// CHECK-DAG: %[[FALSE:.*]] = arith.constant false +// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index +// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : i32 +// CHECK: %[[V0:.*]] = fir.alloca !fir.box>> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFminloc1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFminloc1Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V3:.*]] = fir.absent !fir.box +// CHECK-NEXT: %[[V4:.*]] = fir.zero_bits !fir.heap> +// CHECK-NEXT: %[[V5:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V6:.*]] = fir.embox %[[V4]](%[[V5]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK-NEXT: fir.store %[[V6]] to %[[V0]] : !fir.ref>>> +// CHECK: %[[V8:.*]] = fir.convert %[[V0]] : (!fir.ref>>>) -> !fir.ref> +// CHECK-NEXT: %[[V9:.*]] = fir.convert %[[V1]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[V12:.*]] = fir.convert %[[V3]] : (!fir.box) -> !fir.box +// CHECK-NEXT: fir.call @_FortranAMinlocReal4(%[[V8]], %[[V9]], %[[C4]], {{.*}}, {{.*}}, %[[V12]], %[[FALSE]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box, i1) -> () +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V0]] : !fir.ref>>> +// CHECK-NEXT: %[[V15:.*]]:3 = fir.box_dims %[[V14]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +// CHECK-NEXT: %[[V16:.*]] = fir.box_addr %[[V14]] : (!fir.box>>) -> !fir.heap> +// CHECK-NEXT: %[[V17:.*]] = fir.shape_shift %[[V15]]#0, %[[V15]]#1 : (index, index) -> !fir.shapeshift<1> +// CHECK-NEXT: %[[V18:.*]]:2 = hlfir.declare %[[V16]](%[[V17]]) {uniq_name = ".tmp.intrinsic_result"} : (!fir.heap>, !fir.shapeshift<1>) -> (!fir.box>, !fir.heap>) +// CHECK-NEXT: %[[V19:.*]] = hlfir.as_expr %[[V18]]#0 move %[[TRUE]] : (!fir.box>, i1) -> !hlfir.expr +// CHECK-NEXT: hlfir.assign %[[V19]] to %[[V2]]#0 : !hlfir.expr, !fir.box> +// CHECK-NEXT: hlfir.destroy %[[V19]] : !hlfir.expr diff --git a/flang/test/HLFIR/minval-elemental.fir b/flang/test/HLFIR/minval-elemental.fir index 8da1b1bdf515b..e6a4ad27d4b95 100644 --- a/flang/test/HLFIR/minval-elemental.fir +++ b/flang/test/HLFIR/minval-elemental.fir @@ -24,7 +24,7 @@ func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"} %12 = arith.subi %11, %10 : i32 hlfir.yield_element %12 : i32 } - %7 = hlfir.minval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 + %7 = hlfir.minval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 hlfir.assign %7 to %3#0 : i32, !fir.ref hlfir.destroy %6 : !hlfir.expr return diff --git a/flang/test/HLFIR/minval-lowering.fir b/flang/test/HLFIR/minval-lowering.fir index c9c78e3b2e446..519aa319d4069 100644 --- a/flang/test/HLFIR/minval-lowering.fir +++ b/flang/test/HLFIR/minval-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPminval1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminval1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %2 = hlfir.minval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 + %2 = hlfir.minval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 hlfir.assign %2 to %1#0 : i32, !fir.ref return } @@ -17,7 +17,7 @@ func.func @_QPminval1(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -28,7 +28,7 @@ func.func @_QPminval2(%arg0: !fir.box> {fir.bindc_name = "a" %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminval2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminval2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.minval %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.minval %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -56,7 +56,7 @@ func.func @_QPminval2(%arg0: !fir.box> {fir.bindc_name = "a" // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: fir.call @_FortranAMinvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMinvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] @@ -75,7 +75,7 @@ func.func @_QPminval3(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminval3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminval3Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.minval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 + %3 = hlfir.minval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -89,7 +89,7 @@ func.func @_QPminval3(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK_BOX:.*]] = fir.embox %[[MASK]]#1 : (!fir.ref>) -> !fir.box> // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -99,7 +99,7 @@ func.func @_QPminval4(%arg0: !fir.box> {fir.bindc_name = "a"}, %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminval4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminval4Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.minval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 + %3 = hlfir.minval %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -112,7 +112,7 @@ func.func @_QPminval4(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]]#1 : (!fir.box>>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -144,7 +144,7 @@ func.func @_QPminval5(%arg0: !fir.ref> {fir.bindc_name = "s"}) %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFminval5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.minval %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.minval %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -175,14 +175,14 @@ func.func @_QPminval5(%arg0: !fir.ref> {fir.bindc_name = "s"}) // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY_BOX]] : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: fir.call @_FortranAMinvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMinvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // simple one argument minval for character func.func @_QPminval6(%arg0: !fir.box>> {fir.bindc_name = "a"}, %arg1: !fir.boxchar<1> {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval6Ea"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %1:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref>, index) %2:2 = hlfir.declare %1#0 typeparams %1#1 {uniq_name = "_QFminval6Es"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) - %3 = hlfir.minval %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> + %3 = hlfir.minval %0#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> hlfir.assign %3 to %2#0 : !hlfir.expr>, !fir.boxchar<1> hlfir.destroy %3 : !hlfir.expr> return @@ -205,7 +205,7 @@ func.func @_QPminval6(%arg0: !fir.box>> {fir.bindc_n // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: fir.call @_FortranAMinvalCharacter(%[[RET_ARG]], %[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAMinvalCharacter(%[[RET_ARG]], %[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_ELESIZE:.*]] = fir.box_elesize %[[RET]] @@ -216,3 +216,24 @@ func.func @_QPminval6(%arg0: !fir.box>> {fir.bindc_n // CHECK: hlfir.destroy %[[ASEXPR]] // CHECK-NEXT: return // CHECK-NEXT: } + +// floating point minval +func.func @_QPminval_fp(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminval1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2 = hlfir.minval %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %2 to %1#0 : f32, !fir.ref + return +} +// CHECK-LABEL: func.func @_QPminval_fp( +// CHECK: %[[ARG0:.*]]: !fir.box> +// CHECK: %[[ARG1:.*]]: !fir.ref +// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]] +// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box +// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box +// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box +// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalReal4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> f32 +// CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } diff --git a/flang/test/HLFIR/product-lowering.fir b/flang/test/HLFIR/product-lowering.fir index 45ae1f7aeaf5a..cef1a99f1ef52 100644 --- a/flang/test/HLFIR/product-lowering.fir +++ b/flang/test/HLFIR/product-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPproduct1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFsum1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %2 = hlfir.product %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 + %2 = hlfir.product %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 hlfir.assign %2 to %1#0 : i32, !fir.ref return } @@ -18,7 +18,7 @@ func.func @_QPproduct1(%arg0: !fir.box> {fir.bindc_name = "a"} // CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -29,7 +29,7 @@ func.func @_QPproduct2(%arg0: !fir.box> {fir.bindc_name = "a %1:2 = hlfir.declare %arg2 {uniq_name = "_QFproduct2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFproduct2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.product %0#0 dim %3 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.product %0#0 dim %3 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -59,7 +59,7 @@ func.func @_QPproduct2(%arg0: !fir.box> {fir.bindc_name = "a // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]] // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] -// CHECK: fir.call @_FortranAProductDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAProductDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] // CHECK-NEXT: %[[ADDR:.*]] = fir.box_addr %[[RET]] @@ -76,7 +76,7 @@ func.func @_QPproduct3(%arg0: !fir.box> {fir.bindc_name = "a"} %0:2 = hlfir.declare %arg0 {uniq_name = "_QFproduct3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFproduct3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFproduct3Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.product %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 + %3 = hlfir.product %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -91,7 +91,7 @@ func.func @_QPproduct3(%arg0: !fir.box> {fir.bindc_name = "a"} // CHECK-DAG: %[[MASK_BOX:.*]] = fir.embox %[[MASK]]#1 : (!fir.ref>) -> !fir.box> // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -101,7 +101,7 @@ func.func @_QPproduct4(%arg0: !fir.box> {fir.bindc_name = "a"} %0:2 = hlfir.declare %arg0 {uniq_name = "_QFproduct4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFproduct4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFproduct4Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.product %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 + %3 = hlfir.product %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -115,7 +115,7 @@ func.func @_QPproduct4(%arg0: !fir.box> {fir.bindc_name = "a"} // CHECK-DAG: %[[MASK]]:2 = hlfir.declare %[[ARG2]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]]#1 : (!fir.box>>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranAProductInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -133,7 +133,7 @@ func.func @_QPproduct5(%arg0: !fir.ref> {fir.bindc_name = "s"} %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFproduct5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.product %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.product %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -165,4 +165,26 @@ func.func @_QPproduct5(%arg0: !fir.ref> {fir.bindc_name = "s"} // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY_BOX]] : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: fir.call @_FortranAProductDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranAProductDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () + +// floating point product +func.func @_QPproduct6(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFsum1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2 = hlfir.product %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %2 to %1#0 : f32, !fir.ref + return +} + +// CHECK-LABEL: func.func @_QPproduct6( +// CHECK: %[[ARG0:.*]]: !fir.box> +// CHECK: %[[ARG1:.*]]: !fir.ref +// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]] +// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box +// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box +// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box +// CHECK: %[[RET:.*]] = fir.call @_FortranAProductReal4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> f32 +// CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } diff --git a/flang/test/HLFIR/sum-lowering.fir b/flang/test/HLFIR/sum-lowering.fir index e34ac487e8f9b..2c566e920e49c 100644 --- a/flang/test/HLFIR/sum-lowering.fir +++ b/flang/test/HLFIR/sum-lowering.fir @@ -5,7 +5,7 @@ func.func @_QPsum1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum1Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg1 {uniq_name = "_QFsum1Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %2 = hlfir.sum %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 + %2 = hlfir.sum %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 hlfir.assign %2 to %1#0 : i32, !fir.ref return } @@ -17,7 +17,7 @@ func.func @_QPsum1(%arg0: !fir.box> {fir.bindc_name = "a"}, %a // CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -28,7 +28,7 @@ func.func @_QPsum2(%arg0: !fir.box> {fir.bindc_name = "a"}, %1:2 = hlfir.declare %arg2 {uniq_name = "_QFsum2Ed"} : (!fir.ref) -> (!fir.ref, !fir.ref) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFsum2Es"} : (!fir.box>) -> (!fir.box>, !fir.box>) %3 = fir.load %1#0 : !fir.ref - %4 = hlfir.sum %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr + %4 = hlfir.sum %0#0 dim %3#0 {fastmath = #arith.fastmath} : (!fir.box>, index) -> !hlfir.expr hlfir.assign %4 to %2#0 : !hlfir.expr, !fir.box> hlfir.destroy %4 : !hlfir.expr return @@ -56,7 +56,7 @@ func.func @_QPsum2(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box -// CHECK: fir.call @_FortranASumDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranASumDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () // CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]] // CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]] @@ -75,7 +75,7 @@ func.func @_QPsum3(%arg0: !fir.box> {fir.bindc_name = "a"}, %a %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum3Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFsum3Em"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFsum3Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.sum %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 + %3 = hlfir.sum %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -89,7 +89,7 @@ func.func @_QPsum3(%arg0: !fir.box> {fir.bindc_name = "a"}, %a // CHECK-DAG: %[[MASK_BOX:.*]] = fir.embox %[[MASK]]#1 : (!fir.ref>) -> !fir.box> // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -99,7 +99,7 @@ func.func @_QPsum4(%arg0: !fir.box> {fir.bindc_name = "a"}, %a %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum4Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) %1:2 = hlfir.declare %arg2 {uniq_name = "_QFsum4Em"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) %2:2 = hlfir.declare %arg1 {uniq_name = "_QFsum4Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) - %3 = hlfir.sum %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 + %3 = hlfir.sum %0#0 mask %1#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 hlfir.assign %3 to %2#0 : i32, !fir.ref return } @@ -112,7 +112,7 @@ func.func @_QPsum4(%arg0: !fir.box> {fir.bindc_name = "a"}, %a // CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]]#1 : (!fir.box>>) -> !fir.box -// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 +// CHECK: %[[RET:.*]] = fir.call @_FortranASumInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) : (!fir.box, !fir.ref, i32, i32, !fir.box) -> i32 // CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref // CHECK-NEXT: return // CHECK-NEXT: } @@ -144,7 +144,7 @@ func.func @_QPsum5(%arg0: !fir.ref> {fir.bindc_name = "s"}) { %4:2 = hlfir.declare %arg0(%3) {uniq_name = "_QFsum5Es"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %true = arith.constant true - %5 = hlfir.sum %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> + %5 = hlfir.sum %2#0 dim %c1_i32 mask %true {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> hlfir.assign %5 to %4#0 : !hlfir.expr<2xi32>, !fir.ref> hlfir.destroy %5 : !hlfir.expr<2xi32> return @@ -175,4 +175,25 @@ func.func @_QPsum5(%arg0: !fir.ref> {fir.bindc_name = "s"}) { // CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]] // CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY_BOX]] : (!fir.box>) -> !fir.box // CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK_BOX]] : (!fir.box>) -> !fir.box -// CHECK: fir.call @_FortranASumDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () +// CHECK: fir.call @_FortranASumDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) : (!fir.ref>, !fir.box, i32, !fir.ref, i32, !fir.box) -> () + +// floating point sum +func.func @_QPsum6(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFsum6Ea"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFsum6Es"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2 = hlfir.sum %0#0 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %2 to %1#0 : f32, !fir.ref + return +} +// CHECK-LABEL: func.func @_QPsum6( +// CHECK: %[[ARG0:.*]]: !fir.box> +// CHECK: %[[ARG1:.*]]: !fir.ref +// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] +// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]] +// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box +// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box>) -> !fir.box +// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box) -> !fir.box +// CHECK: %[[RET:.*]] = fir.call @_FortranASumReal4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath : (!fir.box, !fir.ref, i32, i32, !fir.box) -> f32 +// CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } diff --git a/flang/test/Lower/HLFIR/dot_product.f90 b/flang/test/Lower/HLFIR/dot_product.f90 index 2d3ee97b7e408..72a2db0541e73 100644 --- a/flang/test/Lower/HLFIR/dot_product.f90 +++ b/flang/test/Lower/HLFIR/dot_product.f90 @@ -13,7 +13,7 @@ subroutine dot_product1(lhs, rhs, res) ! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] ! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 : (!fir.box>, !fir.box>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -30,7 +30,7 @@ subroutine dot_product2(lhs, rhs, res) ! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] ! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !fir.logical<4> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 : (!fir.box>>, !fir.box>>) -> !fir.logical<4> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : !fir.logical<4>, !fir.ref> ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -47,7 +47,7 @@ subroutine dot_product3(lhs, rhs, res) ! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] ! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.ref>, !fir.ref>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 : (!fir.ref>, !fir.ref>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -66,7 +66,7 @@ subroutine dot_product4(lhs, rhs, res) ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] ! CHECK-NEXT: %[[LHS_LD:.*]] = fir.load %[[LHS_VAR]]#0 ! CHECK-NEXT: %[[RHS_LD:.*]] = fir.load %[[RHS_VAR]]#0 -! CHECK-NEXT: %[[PROD:.*]] = hlfir.dot_product %[[LHS_LD]] %[[RHS_LD]] {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> i32 +! CHECK-NEXT: %[[PROD:.*]] = hlfir.dot_product %[[LHS_LD]] %[[RHS_LD]] : (!fir.box>>, !fir.box>>) -> i32 ! CHECK-NEXT: hlfir.assign %[[PROD]] to %[[RES_VAR]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -76,9 +76,26 @@ subroutine dot_product4(lhs, rhs, res) ! CHECK: %[[C3:.*]] = arith.constant 3 : index ! CHECK: %[[RHS_SHAPE:.*]] = fir.shape %[[C3]] : (index) -> !fir.shape<1> ! CHECK: %[[RHS:.*]]:2 = hlfir.declare %{{.*}}(%[[RHS_SHAPE]]) dummy_scope %{{[0-9]+}} {uniq_name = "_QFdot_product5Erhs"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) -! CHECK: {{.*}} = hlfir.dot_product %[[LHS]]#0 %[[RHS]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 +! CHECK: {{.*}} = hlfir.dot_product %[[LHS]]#0 %[[RHS]]#0 : (!fir.box>, !fir.ref>) -> i32 subroutine dot_product5(lhs, rhs, res) integer :: lhs(:), rhs(3) integer :: res res = dot_product(lhs, rhs) endsubroutine + +! Floating point dot_product +subroutine dot_product6(lhs, rhs, res) + real lhs(:), rhs(:), res + res = DOT_PRODUCT(lhs,rhs) +end subroutine +! CHECK-LABEL: func.func @_QPdot_product6 +! CHECK: %[[LHS:.*]]: !fir.box> {fir.bindc_name = "lhs"} +! CHECK: %[[RHS:.*]]: !fir.box> {fir.bindc_name = "rhs"} +! CHECK: %[[RES:.*]]: !fir.ref {fir.bindc_name = "res"} +! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] +! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] +! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.dot_product %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> f32 +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : f32, !fir.ref +! CHECK-NEXT: return +! CHECK-NEXT: } diff --git a/flang/test/Lower/HLFIR/matmul.f90 b/flang/test/Lower/HLFIR/matmul.f90 index 298dd2b800636..4cb44e1ce40fc 100644 --- a/flang/test/Lower/HLFIR/matmul.f90 +++ b/flang/test/Lower/HLFIR/matmul.f90 @@ -12,7 +12,7 @@ subroutine matmul1(lhs, rhs, res) ! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] ! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.matmul %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.matmul %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 : (!fir.box>, !fir.box>) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -54,7 +54,7 @@ subroutine matmul2(c) ! CHECK-NEXT: %[[A_BOX:.*]] = fir.load %{{.*}} : !fir.ref>>> ! The shapes in these types are what is being tested: -! CHECK-NEXT: %[[MATMUL:.*]] = hlfir.matmul %[[A_BOX]] %[[ELEMENTAL]] {{.*}} : (!fir.box>>, !hlfir.expr) -> !hlfir.expr +! CHECK-NEXT: %[[MATMUL:.*]] = hlfir.matmul %[[A_BOX]] %[[ELEMENTAL]] {{.*}}: (!fir.box>>, !hlfir.expr) -> !hlfir.expr subroutine matmul3(lhs, rhs, res) integer, allocatable :: lhs(:,:), rhs(:,:), res(:,:) @@ -69,8 +69,26 @@ subroutine matmul3(lhs, rhs, res) ! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] ! CHECK-NEXT: %[[LHS_LD:.*]] = fir.load %[[LHS_VAR]]#0 ! CHECK-NEXT: %[[RHS_LD:.*]] = fir.load %[[RHS_VAR]]#0 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.matmul %[[LHS_LD]] %[[RHS_LD]] {fastmath = #arith.fastmath} : (!fir.box>>, !fir.box>>) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.matmul %[[LHS_LD]] %[[RHS_LD]] : (!fir.box>>, !fir.box>>) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 realloc : !hlfir.expr, !fir.ref>>> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return ! CHECK-NEXT: } + +! Floating point matmul +subroutine matmul4(lhs, rhs, res) + real :: lhs(:,:), rhs(:,:), res(:,:) + res = MATMUL(lhs, rhs) +endsubroutine +! CHECK-LABEL: func.func @_QPmatmul4 +! CHECK: %[[LHS:.*]]: !fir.box> {fir.bindc_name = "lhs"} +! CHECK: %[[RHS:.*]]: !fir.box> {fir.bindc_name = "rhs"} +! CHECK: %[[RES:.*]]: !fir.box> {fir.bindc_name = "res"} +! CHECK-DAG: %[[LHS_VAR:.*]]:2 = hlfir.declare %[[LHS]] +! CHECK-DAG: %[[RHS_VAR:.*]]:2 = hlfir.declare %[[RHS]] +! CHECK-DAG: %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]] +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.matmul %[[LHS_VAR]]#0 %[[RHS_VAR]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>) -> !hlfir.expr +! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES_VAR]]#0 : !hlfir.expr, !fir.box> +! CHECK-NEXT: hlfir.destroy %[[EXPR]] +! CHECK-NEXT: return +! CHECK-NEXT: } diff --git a/flang/test/Lower/HLFIR/maxloc.f90 b/flang/test/Lower/HLFIR/maxloc.f90 index 539affad2d7df..421832bd0bd4f 100644 --- a/flang/test/Lower/HLFIR/maxloc.f90 +++ b/flang/test/Lower/HLFIR/maxloc.f90 @@ -10,7 +10,7 @@ subroutine maxloc1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 : (!fir.box>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -27,7 +27,7 @@ subroutine maxloc2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -44,7 +44,7 @@ subroutine maxloc3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -61,7 +61,7 @@ subroutine maxloc4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -82,7 +82,7 @@ subroutine maxloc5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -98,7 +98,7 @@ subroutine maxloc_back(a, s) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[C1:.*]] = arith.constant true -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[C1]] {fastmath = #arith.fastmath} : (!fir.box>, i1) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[C1]] : (!fir.box>, i1) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -116,7 +116,7 @@ subroutine maxloc_back2(a, s, b) ! CHECK-DAG: %[[BACKD:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-NEXT: %[[BACK:.*]] = fir.load %[[BACKD]]#0 : !fir.ref> -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -142,7 +142,7 @@ subroutine maxloc_back3(a, s, b) ! CHECK-NEXT: %[[IFE:.*]] = fir.convert %false : (i1) -> !fir.logical<4> ! CHECK-NEXT: fir.result %[[IFE]] : !fir.logical<4> ! CHECK-NEXT: } -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 back %[[BACK]] : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -158,7 +158,7 @@ subroutine maxloc_kind(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi16> +! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 : (!fir.box>) -> !hlfir.expr<1xi16> ! CHECK: %[[ELM:.*]] = hlfir.elemental ! CHECK: hlfir.assign %[[ELM]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[ELM]] : !hlfir.expr @@ -199,7 +199,7 @@ subroutine maxloc7(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 : (!fir.box>>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -217,7 +217,7 @@ subroutine maxloc8(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -235,7 +235,7 @@ subroutine maxloc9(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>>, !fir.ref>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -342,7 +342,7 @@ end subroutine test_unknown_char_len_result ! CHECK-DAG: %[[C3_8:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[C3_9:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[ARRAY_REF:.*]] = hlfir.designate %[[ARRAY]]#0 (%[[C1]]:%[[C3_0]]:%[[C1_3]], %[[C1]]:%[[C3_1]]:%[[C1_5]]) substr %[[C1_7]], %[[C3_8]] shape %[[SHAPE]] typeparams %[[C3_9]] : (!fir.ref>>, index, index, index, index, index, index, index, index, !fir.shape<2>, index) -> !fir.ref>> -! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY_REF]] {fastmath = #arith.fastmath} : (!fir.ref>>) -> !hlfir.expr<2xi32> +! CHECK: %[[EXPR:.*]] = hlfir.maxloc %[[ARRAY_REF]] : (!fir.ref>>) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -365,7 +365,7 @@ subroutine scalar_dim1(a, d, m, b, s) ! CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[ARG4]] dummy_scope %[[DSCOPE]] ! CHECK-NEXT: %[[V5:.*]] = fir.load %[[V1]]#0 : !fir.ref> ! CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref -! CHECK-NEXT: %[[V7:.*]] = hlfir.maxloc %[[V0]]#0 dim %[[V6]] mask %[[V3]]#0 back %[[V5]] {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>, !fir.logical<4>) -> i16 +! CHECK-NEXT: %[[V7:.*]] = hlfir.maxloc %[[V0]]#0 dim %[[V6]] mask %[[V3]]#0 back %[[V5]] : (!fir.box>, i32, !fir.box>>, !fir.logical<4>) -> i16 ! CHECK-NEXT: %[[V8:.*]] = fir.convert %[[V7]] : (i16) -> i32 ! CHECK-NEXT: hlfir.assign %[[V8]] to %[[V4]]#0 : i32, !fir.box> ! CHECK-NEXT: return diff --git a/flang/test/Lower/HLFIR/maxval.f90 b/flang/test/Lower/HLFIR/maxval.f90 index 32e1a80417a27..a6a4d13d91391 100644 --- a/flang/test/Lower/HLFIR/maxval.f90 +++ b/flang/test/Lower/HLFIR/maxval.f90 @@ -10,7 +10,7 @@ subroutine maxval1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 : (!fir.box>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -26,7 +26,7 @@ subroutine maxval2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -43,7 +43,7 @@ subroutine maxval3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -59,7 +59,7 @@ subroutine maxval4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -79,7 +79,7 @@ subroutine maxval5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -117,7 +117,7 @@ subroutine maxval7(a, s) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[UNBOXED:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[UNBOXED]]#0 typeparams %[[UNBOXED]]#1 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 : (!fir.box>>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.boxchar<1> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -135,7 +135,7 @@ subroutine maxval8(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>>, i32) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.box>> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -153,7 +153,7 @@ subroutine maxval9(a, s, m) ! CHECK-DAG: %[[UNBOXED:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[UNBOXED]]#0 typeparams %[[UNBOXED]]#1 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.ref>) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>>, !fir.ref>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.boxchar<1> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -255,7 +255,7 @@ end subroutine test_unknown_char_len_result ! CHECK-DAG: %[[C3_8:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[C3_9:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[ARRAY_REF:.*]] = hlfir.designate %[[ARRAY]]#0 (%[[C1]]:%[[C3_0]]:%[[C1_3]], %[[C1]]:%[[C3_1]]:%[[C1_5]]) substr %[[C1_7]], %[[C3_8]] shape %[[SHAPE]] typeparams %[[C3_9]] : (!fir.ref>>, index, index, index, index, index, index, index, index, !fir.shape<2>, index) -> !fir.ref>> -! CHECK: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY_REF]] {fastmath = #arith.fastmath} : (!fir.ref>>) -> !hlfir.expr> +! CHECK: %[[EXPR:.*]] = hlfir.maxval %[[ARRAY_REF]] : (!fir.ref>>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES]]#0 : !hlfir.expr>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return diff --git a/flang/test/Lower/HLFIR/minloc.f90 b/flang/test/Lower/HLFIR/minloc.f90 index ce149ffcfb54f..b5fa506c71d33 100644 --- a/flang/test/Lower/HLFIR/minloc.f90 +++ b/flang/test/Lower/HLFIR/minloc.f90 @@ -10,7 +10,7 @@ subroutine minloc1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 : (!fir.box>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -27,7 +27,7 @@ subroutine minloc2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -44,7 +44,7 @@ subroutine minloc3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -61,7 +61,7 @@ subroutine minloc4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -82,7 +82,7 @@ subroutine minloc5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -98,7 +98,7 @@ subroutine minloc_back(a, s) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[C1:.*]] = arith.constant true -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[C1]] {fastmath = #arith.fastmath} : (!fir.box>, i1) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[C1]] : (!fir.box>, i1) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -116,7 +116,7 @@ subroutine minloc_back2(a, s, b) ! CHECK-DAG: %[[BACKD:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-NEXT: %[[BACK:.*]] = fir.load %[[BACKD]]#0 : !fir.ref> -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[BACK]] : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -142,7 +142,7 @@ subroutine minloc_back3(a, s, b) ! CHECK-NEXT: %[[IFE:.*]] = fir.convert %false : (i1) -> !fir.logical<4> ! CHECK-NEXT: fir.result %[[IFE]] : !fir.logical<4> ! CHECK-NEXT: } -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[BACK]] {fastmath = #arith.fastmath} : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 back %[[BACK]] : (!fir.box>, !fir.logical<4>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<1xi32> ! CHECK-NEXT: return @@ -158,7 +158,7 @@ subroutine minloc_kind(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> !hlfir.expr<1xi16> +! CHECK: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 : (!fir.box>) -> !hlfir.expr<1xi16> ! CHECK: %[[ELM:.*]] = hlfir.elemental ! CHECK: hlfir.assign %[[ELM]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[ELM]] : !hlfir.expr @@ -199,7 +199,7 @@ subroutine minloc7(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.box> ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 : (!fir.box>>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -217,7 +217,7 @@ subroutine minloc8(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -235,7 +235,7 @@ subroutine minloc9(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.ref>) -> !hlfir.expr<1xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>>, !fir.ref>) -> !hlfir.expr<1xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<1xi32>, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -342,7 +342,7 @@ end subroutine test_unknown_char_len_result ! CHECK-DAG: %[[C3_8:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[C3_9:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[ARRAY_REF:.*]] = hlfir.designate %[[ARRAY]]#0 (%[[C1]]:%[[C3_0]]:%[[C1_3]], %[[C1]]:%[[C3_1]]:%[[C1_5]]) substr %[[C1_7]], %[[C3_8]] shape %[[SHAPE]] typeparams %[[C3_9]] : (!fir.ref>>, index, index, index, index, index, index, index, index, !fir.shape<2>, index) -> !fir.ref>> -! CHECK: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY_REF]] {fastmath = #arith.fastmath} : (!fir.ref>>) -> !hlfir.expr<2xi32> +! CHECK: %[[EXPR:.*]] = hlfir.minloc %[[ARRAY_REF]] : (!fir.ref>>) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -365,7 +365,7 @@ subroutine scalar_dim1(a, d, m, b, s) ! CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[ARG4]] dummy_scope %[[DSCOPE]] ! CHECK-NEXT: %[[V5:.*]] = fir.load %[[V1]]#0 : !fir.ref> ! CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref -! CHECK-NEXT: %[[V7:.*]] = hlfir.minloc %[[V0]]#0 dim %[[V6]] mask %[[V3]]#0 back %[[V5]] {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>, !fir.logical<4>) -> i16 +! CHECK-NEXT: %[[V7:.*]] = hlfir.minloc %[[V0]]#0 dim %[[V6]] mask %[[V3]]#0 back %[[V5]] : (!fir.box>, i32, !fir.box>>, !fir.logical<4>) -> i16 ! CHECK-NEXT: %[[V8:.*]] = fir.convert %[[V7]] : (i16) -> i32 ! CHECK-NEXT: hlfir.assign %[[V8]] to %[[V4]]#0 : i32, !fir.box> ! CHECK-NEXT: return diff --git a/flang/test/Lower/HLFIR/minval.f90 b/flang/test/Lower/HLFIR/minval.f90 index 2ac9aba850b6f..352111318c3c8 100644 --- a/flang/test/Lower/HLFIR/minval.f90 +++ b/flang/test/Lower/HLFIR/minval.f90 @@ -10,7 +10,7 @@ subroutine minval1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 : (!fir.box>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -26,7 +26,7 @@ subroutine minval2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -43,7 +43,7 @@ subroutine minval3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -59,7 +59,7 @@ subroutine minval4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -79,7 +79,7 @@ subroutine minval5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -117,7 +117,7 @@ subroutine minval7(a, s) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[UNBOXED:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[UNBOXED]]#0 typeparams %[[UNBOXED]]#1 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>>) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 : (!fir.box>>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.boxchar<1> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -135,7 +135,7 @@ subroutine minval8(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>>, i32) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>>, i32) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.box>> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -153,7 +153,7 @@ subroutine minval9(a, s, m) ! CHECK-DAG: %[[UNBOXED:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[UNBOXED]]#0 typeparams %[[UNBOXED]]#1 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>>, !fir.ref>) -> !hlfir.expr> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.minval %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>>, !fir.ref>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr>, !fir.boxchar<1> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -255,7 +255,7 @@ end subroutine test_unknown_char_len_result ! CHECK-DAG: %[[C3_8:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[C3_9:.*]] = arith.constant 3 : index ! CHECK-DAG: %[[ARRAY_REF:.*]] = hlfir.designate %[[ARRAY]]#0 (%[[C1]]:%[[C3_0]]:%[[C1_3]], %[[C1]]:%[[C3_1]]:%[[C1_5]]) substr %[[C1_7]], %[[C3_8]] shape %[[SHAPE]] typeparams %[[C3_9]] : (!fir.ref>>, index, index, index, index, index, index, index, index, !fir.shape<2>, index) -> !fir.ref>> -! CHECK: %[[EXPR:.*]] = hlfir.minval %[[ARRAY_REF]] {fastmath = #arith.fastmath} : (!fir.ref>>) -> !hlfir.expr> +! CHECK: %[[EXPR:.*]] = hlfir.minval %[[ARRAY_REF]] : (!fir.ref>>) -> !hlfir.expr> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[RES]]#0 : !hlfir.expr>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -294,7 +294,7 @@ function test_type_mismatch ! CHECK: hlfir.yield_element %[[VAL_21]] : !hlfir.expr> ! CHECK: } ! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_23:.*]] = hlfir.minval %[[VAL_17]] dim %[[VAL_22]] {fastmath = {{.*}}} : (!hlfir.expr<3x4x!fir.char<1,?>>, i32) -> !hlfir.expr<4x!fir.char<1,4>> +! CHECK: %[[VAL_23:.*]] = hlfir.minval %[[VAL_17]] dim %[[VAL_22]] : (!hlfir.expr<3x4x!fir.char<1,?>>, i32) -> !hlfir.expr<4x!fir.char<1,4>> ! CHECK: hlfir.assign %[[VAL_23]] to %[[VAL_12]]#0 realloc : !hlfir.expr<4x!fir.char<1,4>>, !fir.ref>>>> ! CHECK: hlfir.destroy %[[VAL_23]] : !hlfir.expr<4x!fir.char<1,4>> ! CHECK: hlfir.destroy %[[VAL_17]] : !hlfir.expr<3x4x!fir.char<1,?>> diff --git a/flang/test/Lower/HLFIR/product.f90 b/flang/test/Lower/HLFIR/product.f90 index 41c0c89777d8f..65bf6e8166c84 100644 --- a/flang/test/Lower/HLFIR/product.f90 +++ b/flang/test/Lower/HLFIR/product.f90 @@ -10,7 +10,7 @@ subroutine product1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 : (!fir.box>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -26,7 +26,7 @@ subroutine product2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -43,7 +43,7 @@ subroutine product3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -59,7 +59,7 @@ subroutine product4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -79,7 +79,7 @@ subroutine product5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -100,7 +100,7 @@ subroutine product6(a, s, d) ! CHECK-NEXT: %[[DIM_ADDR:.*]] = fir.box_addr %[[DIM_BOX]] : (!fir.box>) -> !fir.ptr ! CHECK-NEXT: %[[DIM0:.*]] = fir.load %[[DIM_ADDR]] : !fir.ptr ! CHECK-NEXT: %[[DIM1:.*]] = hlfir.no_reassoc %[[DIM0]] : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[DIM1]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.product %[[ARRAY]]#0 dim %[[DIM1]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -171,4 +171,4 @@ function testOptionalScalar(array, mask) ! CHECK: hlfir.assign %[[RES]] to %[[RET_VAR]]#0 ! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref ! CHECK: return %[[RET]] : i32 -! CHECK: } \ No newline at end of file +! CHECK: } diff --git a/flang/test/Lower/HLFIR/sum.f90 b/flang/test/Lower/HLFIR/sum.f90 index 339582088b032..ec4fca9ce93e1 100644 --- a/flang/test/Lower/HLFIR/sum.f90 +++ b/flang/test/Lower/HLFIR/sum.f90 @@ -10,7 +10,7 @@ subroutine sum1(a, s) ! CHECK: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 {fastmath = #arith.fastmath} : (!fir.box>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 : (!fir.box>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -26,7 +26,7 @@ subroutine sum2(a, s, d) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[DIM_REF:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK-NEXT: %[[DIM:.*]] = fir.load %[[DIM_REF]]#0 : !fir.ref -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[DIM]] {fastmath = #arith.fastmath} : (!fir.box>, i32) -> !hlfir.expr +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[DIM]] : (!fir.box>, i32) -> !hlfir.expr ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr, !fir.box> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return @@ -43,7 +43,7 @@ subroutine sum3(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.ref>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -59,7 +59,7 @@ subroutine sum4(a, s, m) ! CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK-DAG: %[[MASK:.*]]:2 = hlfir.declare %[[ARG2]] -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 {fastmath = #arith.fastmath} : (!fir.box>, !fir.box>>) -> i32 +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 mask %[[MASK]]#0 : (!fir.box>, !fir.box>>) -> i32 ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : i32, !fir.ref ! CHECK-NEXT: return ! CHECK-NEXT: } @@ -79,7 +79,7 @@ subroutine sum5(s) ! CHECK-DAG: %[[OUT:.*]]:2 = hlfir.declare %[[ARG0]](%[[OUT_SHAPE]]) ! CHECK-DAG: %[[TRUE:.*]] = arith.constant true ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32 -! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] {fastmath = #arith.fastmath} : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> +! CHECK-NEXT: %[[EXPR:.*]] = hlfir.sum %[[ARRAY]]#0 dim %[[C1]] mask %[[TRUE]] : (!fir.ref>, i32, i1) -> !hlfir.expr<2xi32> ! CHECK-NEXT: hlfir.assign %[[EXPR]] to %[[OUT]]#0 : !hlfir.expr<2xi32>, !fir.ref> ! CHECK-NEXT: hlfir.destroy %[[EXPR]] : !hlfir.expr<2xi32> ! CHECK-NEXT: return @@ -174,4 +174,4 @@ function testOptionalScalar(array, mask) ! CHECK: hlfir.assign %[[RES]] to %[[RET_VAR]]#0 ! CHECK: %[[RET:.*]] = fir.load %[[RET_VAR]]#1 : !fir.ref ! CHECK: return %[[RET]] : i32 -! CHECK: } \ No newline at end of file +! CHECK: } diff --git a/flang/test/Lower/HLFIR/vector-subscript-lhs.f90 b/flang/test/Lower/HLFIR/vector-subscript-lhs.f90 index 74236b39ebf4f..823348fdf9d8e 100644 --- a/flang/test/Lower/HLFIR/vector-subscript-lhs.f90 +++ b/flang/test/Lower/HLFIR/vector-subscript-lhs.f90 @@ -38,7 +38,7 @@ subroutine test_cleanup(x, vector, matrix) ! CHECK: %[[VAL_11:.*]] = arith.constant 4.200000e+01 : f32 ! CHECK: hlfir.yield %[[VAL_11]] : f32 ! CHECK: } to { -! CHECK: %[[VAL_12:.*]] = hlfir.matmul %[[VAL_9]]#0 %[[VAL_6]]#0 {fastmath = #arith.fastmath} : (!fir.ref>, !fir.ref>) -> !hlfir.expr<5xi64> +! CHECK: %[[VAL_12:.*]] = hlfir.matmul %[[VAL_9]]#0 %[[VAL_6]]#0 : (!fir.ref>, !fir.ref>) -> !hlfir.expr<5xi64> ! CHECK: %[[VAL_13:.*]] = arith.constant 5 : index ! CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> ! CHECK: hlfir.elemental_addr %[[VAL_14]] unordered : !fir.shape<1> { diff --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td index ea9b0f6509b80..bd5e05977b909 100644 --- a/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td +++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOps.td @@ -1545,6 +1545,17 @@ def Arith_CmpFOp : Arith_CompareOp<"cmpf", let hasCanonicalizer = 1; let assemblyFormat = [{ $predicate `,` $lhs `,` $rhs (`fastmath` `` $fastmath^)? attr-dict `:` type($lhs)}]; + + let extraClassDeclaration = [{ + /// Always allow FastMathFlags on arith.cmpf. + /// It does not produce a floating point result, but + /// LLVM is currently relying on fast-math flags attached + /// to floating point comparison. + /// This can be removed whenever LLVM stops doing it. + bool isArithFastMathApplicable() { + return true; + } + }]; } //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.td b/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.td index 82d6c9ad6b03d..446563a23d104 100644 --- a/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.td +++ b/mlir/include/mlir/Dialect/Arith/IR/ArithOpsInterfaces.td @@ -22,31 +22,63 @@ def ArithFastMathInterface : OpInterface<"ArithFastMathInterface"> { let cppNamespace = "::mlir::arith"; - let methods = [ - InterfaceMethod< - /*desc=*/ "Returns a FastMathFlagsAttr attribute for the operation", - /*returnType=*/ "FastMathFlagsAttr", - /*methodName=*/ "getFastMathFlagsAttr", - /*args=*/ (ins), - /*methodBody=*/ [{}], - /*defaultImpl=*/ [{ + let methods = + [InterfaceMethod< + /*desc=*/"Returns a FastMathFlagsAttr attribute for the operation", + /*returnType=*/"FastMathFlagsAttr", + /*methodName=*/"getFastMathFlagsAttr", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ ConcreteOp op = cast(this->getOperation()); return op.getFastmathAttr(); - }] - >, - StaticInterfaceMethod< - /*desc=*/ [{Returns the name of the FastMathFlagsAttr attribute + }]>, + StaticInterfaceMethod< + /*desc=*/[{Returns the name of the FastMathFlagsAttr attribute for the operation}], - /*returnType=*/ "StringRef", - /*methodName=*/ "getFastMathAttrName", - /*args=*/ (ins), - /*methodBody=*/ [{}], - /*defaultImpl=*/ [{ + /*returnType=*/"StringRef", + /*methodName=*/"getFastMathAttrName", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ return "fastmath"; - }] - > + }]>, + InterfaceMethod< + /*desc=*/[{Returns true iff FastMathFlagsAttr attribute + is applicable to the operation that supports + ArithFastMathInterface. If it returns false, + then the FastMathFlagsAttr of the operation + must be nullptr or have 'none' value}], + /*returnType=*/"bool", + /*methodName=*/"isArithFastMathApplicable", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ + return ::mlir::cast<::mlir::arith::ArithFastMathInterface>(this->getOperation()).isApplicableImpl(); + }]>]; - ]; + let extraClassDeclaration = [{ + /// Returns true iff the given type is a floating point type + /// or contains one. + static bool isCompatibleType(::mlir::Type); + + /// Default implementation of isArithFastMathApplicable(). + /// It returns true iff any of the results of the operations + /// has a type that is compatible with fast-math. + bool isApplicableImpl(); + }]; + + let verify = [{ + auto fmi = ::mlir::cast<::mlir::arith::ArithFastMathInterface>($_op); + auto attr = fmi.getFastMathFlagsAttr(); + if (attr && attr.getValue() != ::mlir::arith::FastMathFlags::none && + !fmi.isArithFastMathApplicable()) + return $_op->emitOpError() + << "has flag(s) `" << stringifyEnum(attr.getValue()) + << "`, but fast-math flags are not applicable " + "(`isArithFastMathApplicable()` returns false)"; + return ::mlir::success(); + }]; } def ArithIntegerOverflowFlagsInterface : OpInterface<"ArithIntegerOverflowFlagsInterface"> { diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td index 5ccddef158d9c..b63cbb5c362cf 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td @@ -22,30 +22,63 @@ def FastmathFlagsInterface : OpInterface<"FastmathFlagsInterface"> { let cppNamespace = "::mlir::LLVM"; - let methods = [ - InterfaceMethod< - /*desc=*/ "Returns a FastmathFlagsAttr attribute for the operation", - /*returnType=*/ "::mlir::LLVM::FastmathFlagsAttr", - /*methodName=*/ "getFastmathAttr", - /*args=*/ (ins), - /*methodBody=*/ [{}], - /*defaultImpl=*/ [{ + let methods = + [InterfaceMethod< + /*desc=*/"Returns a FastmathFlagsAttr attribute for the operation", + /*returnType=*/"::mlir::LLVM::FastmathFlagsAttr", + /*methodName=*/"getFastmathAttr", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ auto op = cast(this->getOperation()); return op.getFastmathFlagsAttr(); - }] - >, - StaticInterfaceMethod< - /*desc=*/ [{Returns the name of the FastmathFlagsAttr attribute + }]>, + StaticInterfaceMethod< + /*desc=*/[{Returns the name of the FastmathFlagsAttr attribute for the operation}], - /*returnType=*/ "::llvm::StringRef", - /*methodName=*/ "getFastmathAttrName", - /*args=*/ (ins), - /*methodBody=*/ [{}], - /*defaultImpl=*/ [{ + /*returnType=*/"::llvm::StringRef", + /*methodName=*/"getFastmathAttrName", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ return "fastmathFlags"; - }] - > - ]; + }]>, + InterfaceMethod< + /*desc=*/[{Returns true iff FastmathFlagsAttr attribute + is applicable to the operation that supports + FastmathInterface. If it returns false, + then the FastmathFlagsAttr of the operation + must be nullptr or have 'none' value}], + /*returnType=*/"bool", + /*methodName=*/"isFastmathApplicable", + /*args=*/(ins), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ + return ::mlir::cast<::mlir::LLVM::FastmathFlagsInterface>(this->getOperation()).isApplicableImpl(); + }]>]; + + let extraClassDeclaration = [{ + /// Returns true iff the given type is a floating point type + /// or contains one. + static bool isCompatibleType(::mlir::Type); + + /// Default implementation of isFastmathApplicable(). + /// It returns true iff any of the results of the operations + /// has a type that is compatible with fast-math. + bool isApplicableImpl(); + }]; + + let verify = [{ + auto fmi = ::mlir::cast<::mlir::LLVM::FastmathFlagsInterface>($_op); + auto attr = fmi.getFastmathAttr(); + if (attr && attr.getValue() != ::mlir::LLVM::FastmathFlags::none && + !fmi.isFastmathApplicable()) + return $_op->emitOpError() + << "has flag(s) `" << stringifyEnum(attr.getValue()) + << "`, but fast-math flags are not applicable " + "(`isFastmathApplicable()` returns false)"; + return ::mlir::success(); + }]; } def IntegerOverflowFlagsInterface : OpInterface<"IntegerOverflowFlagsInterface"> { diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index ee6e10efed4f1..17267efc17a3a 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -225,6 +225,17 @@ def LLVM_FCmpOp : LLVM_ArithmeticCmpOp<"fcmp", [ // Set the $predicate index to -1 to indicate there is no matching operand // and decrement the following indices. list llvmArgIndices = [-1, 0, 1, 2]; + + let extraClassDeclaration = [{ + /// Always allow FastmathFlags on llvm.fcmp. + /// It does not produce a floating point result, but + /// LLVM is currently relying on fast-math flags attached + /// to floating point comparison. + /// This can be removed whenever LLVM stops doing it. + bool isFastmathApplicable() { + return true; + } + }]; } // Floating point binary operations. diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp index 042acf6100900..4123d88d57551 100644 --- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp +++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp @@ -12,6 +12,7 @@ #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" #include "mlir/Dialect/UB/IR/UBOps.h" #include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinTypeInterfaces.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/Interfaces/ValueBoundsOpInterface.h" #include "mlir/Transforms/InliningUtils.h" @@ -66,3 +67,30 @@ Operation *arith::ArithDialect::materializeConstant(OpBuilder &builder, return ConstantOp::materialize(builder, value, type, loc); } + +/// Return true if the type is compatible with fast math, i.e. +/// it is a float type or contains a float type. +bool arith::ArithFastMathInterface::isCompatibleType(Type type) { + if (isa(type) || isa(type)) + return true; + + // ShapeType's with ValueSemantics represent containers + // passed around as values (not references), so look inside + // them to see if the element type is compatible with FastMath. + if (type.hasTrait()) + if (auto shapedType = dyn_cast(type)) + return isCompatibleType(shapedType.getElementType()); + + return false; +} + +/// Return true if any of the results of the operation +/// has a type compatible with fast math, i.e. it is a float type +/// or contains a float type. +bool arith::ArithFastMathInterface::isApplicableImpl() { + Operation *op = getOperation(); + if (llvm::any_of(op->getResults(), + [](Value v) { return isCompatibleType(v.getType()); })) + return true; + return false; +} diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index a6e996f3fb810..07d26a089317b 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -3783,3 +3783,43 @@ bool mlir::LLVM::satisfiesLLVMModule(Operation *op) { return op->hasTrait() && op->hasTrait(); } + +/// Return true if the type is compatible with fast math, i.e. +/// it is a float type or contains a float type. +bool mlir::LLVM::FastmathFlagsInterface::isCompatibleType(Type type) { + if (auto structType = dyn_cast(type)) { + if (structType.isIdentified()) + return false; + ArrayRef elementTypes = structType.getBody(); + if (elementTypes.empty() || !llvm::all_equal(elementTypes)) + return false; + + type = elementTypes[0]; + } else if (auto arrayType = dyn_cast(type)) { + do { + type = arrayType.getElementType(); + } while ((arrayType = dyn_cast(type))); + } + + if (isa(type)) + return true; + + type = + TypeSwitch(type) + .Case( + [](auto containerType) { return containerType.getElementType(); }) + .Default(type); + + return isa(type); +} + +/// Return true if any of the results of the operation +/// has a type compatible with fast math, i.e. it is a float type +/// or contains a float type. +bool mlir::LLVM::FastmathFlagsInterface::isApplicableImpl() { + Operation *op = getOperation(); + if (llvm::any_of(op->getResults(), + [](Value v) { return isCompatibleType(v.getType()); })) + return true; + return false; +} diff --git a/mlir/test/Dialect/LLVMIR/inlining.mlir b/mlir/test/Dialect/LLVMIR/inlining.mlir index eb249a4771753..cf88c5d1d78ec 100644 --- a/mlir/test/Dialect/LLVMIR/inlining.mlir +++ b/mlir/test/Dialect/LLVMIR/inlining.mlir @@ -74,18 +74,18 @@ func.func @llvm_ret(%arg0 : i32) -> i32 { // ----- // Include all function attributes that don't prevent inlining -llvm.func internal fastcc @callee() -> (i32) attributes { function_entry_count = 42 : i64, dso_local } { - %0 = llvm.mlir.constant(42 : i32) : i32 - llvm.return %0 : i32 +llvm.func internal fastcc @callee() -> (f32) attributes { function_entry_count = 42 : i64, dso_local } { + %0 = llvm.mlir.constant(42.0 : f32) : f32 + llvm.return %0 : f32 } // CHECK-LABEL: llvm.func @caller // CHECK-NEXT: %[[CST:.+]] = llvm.mlir.constant // CHECK-NEXT: llvm.return %[[CST]] -llvm.func @caller() -> (i32) { +llvm.func @caller() -> (f32) { // Include all call attributes that don't prevent inlining. - %0 = llvm.call fastcc @callee() { fastmathFlags = #llvm.fastmath, branch_weights = dense<42> : vector<1xi32> } : () -> (i32) - llvm.return %0 : i32 + %0 = llvm.call fastcc @callee() { fastmathFlags = #llvm.fastmath, branch_weights = dense<42> : vector<1xi32> } : () -> (f32) + llvm.return %0 : f32 } // ----- diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir index 5c939318fe3ed..fab48a89dbb1d 100644 --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1703,3 +1703,11 @@ llvm.func @wrong_number_of_bundle_tags() { } : (i32, i32) -> () llvm.return } + +// ----- + +func.func @call_invalid_fastmath(%callee : !llvm.ptr) { + // expected-error@+1 {{has flag(s) `nsz, afn`, but fast-math flags are not applicable (`isFastmathApplicable()` returns false)}} + llvm.call %callee() {fastmathFlags = #llvm.fastmath} : !llvm.ptr, () -> i32 + llvm.return +} diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir index 88660ce598f3c..0f49539267c6d 100644 --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -102,15 +102,15 @@ func.func @ops(%arg0: i32, %arg1: f32, // Variadic calls // CHECK: llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func) : (i32, i32) -> () -// CHECK: llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : (i32, i32) -> () -// CHECK: %[[VARIADIC_FUNC:.*]] = llvm.mlir.addressof @vararg_func : !llvm.ptr -// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func) : !llvm.ptr, (i32, i32) -> () -// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : !llvm.ptr, (i32, i32) -> () +// CHECK: llvm.call @vararg_func_f32(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : (i32, i32) -> f32 +// CHECK: %[[VARIADIC_FUNC:.*]] = llvm.mlir.addressof @vararg_func_f32 : !llvm.ptr +// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func) : !llvm.ptr, (i32, i32) -> f32 +// CHECK: llvm.call %[[VARIADIC_FUNC]](%[[I32]], %[[I32]]) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : !llvm.ptr, (i32, i32) -> f32 llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func) : (i32, i32) -> () - llvm.call @vararg_func(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : (i32, i32) -> () - %variadic_func = llvm.mlir.addressof @vararg_func : !llvm.ptr - llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func) : !llvm.ptr, (i32, i32) -> () - llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : !llvm.ptr, (i32, i32) -> () + %tmp1 = llvm.call @vararg_func_f32(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : (i32, i32) -> f32 + %variadic_func = llvm.mlir.addressof @vararg_func_f32 : !llvm.ptr + llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func) : !llvm.ptr, (i32, i32) -> f32 + %tmp2 = llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func) {fastmathFlags = #llvm.fastmath} : !llvm.ptr, (i32, i32) -> f32 // Function call attributes // CHECK: llvm.call @baz() {convergent} : () -> () @@ -618,6 +618,9 @@ llvm.func @useInlineAsm(%arg0: i32) { llvm.return } +// CHECK-LABEL: @fastmathStructReturn +llvm.func @fastmathStructReturn(%arg0: i32) -> !llvm.struct<(f32, f32)> + // CHECK-LABEL: @fastmathFlags func.func @fastmathFlags(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: vector<2 x f32>, %arg4: vector<2 x f32>) { // CHECK: {{.*}} = llvm.fadd %arg0, %arg1 {fastmathFlags = #llvm.fastmath} : f32 @@ -643,8 +646,8 @@ func.func @fastmathFlags(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: vector<2 x f // CHECK: {{.*}} = llvm.fneg %arg0 {fastmathFlags = #llvm.fastmath} : f32 %6 = llvm.fneg %arg0 {fastmathFlags = #llvm.fastmath} : f32 -// CHECK: {{.*}} = llvm.call @foo(%arg2) {fastmathFlags = #llvm.fastmath} : (i32) -> !llvm.struct<(i32, f64, i32)> - %7 = llvm.call @foo(%arg2) {fastmathFlags = #llvm.fastmath} : (i32) -> !llvm.struct<(i32, f64, i32)> +// CHECK: {{.*}} = llvm.call @fastmathStructReturn(%arg2) {fastmathFlags = #llvm.fastmath} : (i32) -> !llvm.struct<(f32, f32)> + %7 = llvm.call @fastmathStructReturn(%arg2) {fastmathFlags = #llvm.fastmath} : (i32) -> !llvm.struct<(f32, f32)> // CHECK: {{.*}} = llvm.fadd %arg0, %arg1 : f32 %8 = llvm.fadd %arg0, %arg1 {fastmathFlags = #llvm.fastmath} : f32 @@ -700,6 +703,9 @@ llvm.func @invariant_group_intrinsics(%p: !llvm.ptr) { llvm.return } +// CHECK-LABEL: @vararg_func_f32 +llvm.func @vararg_func_f32(%arg0: i32, ...) -> f32 + // CHECK-LABEL: @vararg_func llvm.func @vararg_func(%arg0: i32, ...) { // CHECK: %[[C:.*]] = llvm.mlir.constant(1 : i32) diff --git a/mlir/test/Target/LLVMIR/omptarget-depend.mlir b/mlir/test/Target/LLVMIR/omptarget-depend.mlir index 71fecd0fa5fd0..723246c323f2c 100644 --- a/mlir/test/Target/LLVMIR/omptarget-depend.mlir +++ b/mlir/test/Target/LLVMIR/omptarget-depend.mlir @@ -113,9 +113,9 @@ module attributes {omp.is_target_device = false, omp.target_triples = ["amdgcn-a llvm.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 { %0 = llvm.mlir.constant(0 : i32) : i32 %1 = llvm.mlir.zero : !llvm.ptr - llvm.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %1) {fastmathFlags = #llvm.fastmath} : (i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> () - llvm.call @_QQmain() {fastmathFlags = #llvm.fastmath} : () -> () - llvm.call @_FortranAProgramEndStatement() {fastmathFlags = #llvm.fastmath} : () -> () + llvm.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %1) : (i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> () + llvm.call @_QQmain() : () -> () + llvm.call @_FortranAProgramEndStatement() : () -> () llvm.return %0 : i32 } }