diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index dd2e90c3b1a1fd..6e8064a63b7ae0 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2538,12 +2538,18 @@ def fir_NegcOp : ComplexUnaryArithmeticOp<"negc">; class ComplexArithmeticOp traits = []> : fir_ArithmeticOp, - Arguments<(ins fir_ComplexType:$lhs, fir_ComplexType:$rhs)>; - -def fir_AddcOp : ComplexArithmeticOp<"addc", [Commutative]>; -def fir_SubcOp : ComplexArithmeticOp<"subc">; -def fir_MulcOp : ComplexArithmeticOp<"mulc", [Commutative]>; -def fir_DivcOp : ComplexArithmeticOp<"divc">; + Arguments<(ins fir_ComplexType:$lhs, fir_ComplexType:$rhs, + DefaultValuedAttr:$fastmath)>; + +def fir_AddcOp : ComplexArithmeticOp<"addc", + [Commutative, DeclareOpInterfaceMethods]>; +def fir_SubcOp : ComplexArithmeticOp<"subc", + [DeclareOpInterfaceMethods]>; +def fir_MulcOp : ComplexArithmeticOp<"mulc", + [Commutative, DeclareOpInterfaceMethods]>; +def fir_DivcOp : ComplexArithmeticOp<"divc", + [DeclareOpInterfaceMethods]>; // Pow is a builtin call and not a primitive def fir_CmpcOp : fir_Op<"cmpc", diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 0f85f89f1a4813..9eabacdc818f6f 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -33,6 +33,7 @@ #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h" #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h" #include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h" +#include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/LLVMIR/Transforms/AddComdats.h" #include "mlir/Dialect/OpenACC/OpenACC.h" @@ -44,6 +45,7 @@ #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/TypeSwitch.h" +#include namespace fir { #define GEN_PASS_DEF_FIRTOLLVMLOWERING @@ -3496,12 +3498,20 @@ struct AbsentOpConversion : public FIROpConversion { // Primitive operations on Complex types // +template +static inline mlir::LLVM::FastmathFlagsAttr getLLVMFMFAttr(OPTY op) { + return mlir::LLVM::FastmathFlagsAttr::get( + op.getContext(), + mlir::arith::convertArithFastMathFlagsToLLVM(op.getFastmath())); +} + /// Generate inline code for complex addition/subtraction template static mlir::LLVM::InsertValueOp complexSum(OPTY sumop, mlir::ValueRange opnds, mlir::ConversionPatternRewriter &rewriter, const fir::LLVMTypeConverter &lowering) { + mlir::LLVM::FastmathFlagsAttr fmf = getLLVMFMFAttr(sumop); mlir::Value a = opnds[0]; mlir::Value b = opnds[1]; auto loc = sumop.getLoc(); @@ -3511,8 +3521,8 @@ complexSum(OPTY sumop, mlir::ValueRange opnds, auto y0 = rewriter.create(loc, a, 1); auto x1 = rewriter.create(loc, b, 0); auto y1 = rewriter.create(loc, b, 1); - auto rx = rewriter.create(loc, eleTy, x0, x1); - auto ry = rewriter.create(loc, eleTy, y0, y1); + auto rx = rewriter.create(loc, eleTy, x0, x1, fmf); + auto ry = rewriter.create(loc, eleTy, y0, y1, fmf); auto r0 = rewriter.create(loc, ty); auto r1 = rewriter.create(loc, r0, rx, 0); return rewriter.create(loc, r1, ry, 1); @@ -3560,6 +3570,7 @@ struct MulcOpConversion : public FIROpConversion { // TODO: Can we use a call to __muldc3 ? // given: (x + iy) * (x' + iy') // result: (xx'-yy')+i(xy'+yx') + mlir::LLVM::FastmathFlagsAttr fmf = getLLVMFMFAttr(mulc); mlir::Value a = adaptor.getOperands()[0]; mlir::Value b = adaptor.getOperands()[1]; auto loc = mulc.getLoc(); @@ -3569,12 +3580,12 @@ struct MulcOpConversion : public FIROpConversion { auto y0 = rewriter.create(loc, a, 1); auto x1 = rewriter.create(loc, b, 0); auto y1 = rewriter.create(loc, b, 1); - auto xx = rewriter.create(loc, eleTy, x0, x1); - auto yx = rewriter.create(loc, eleTy, y0, x1); - auto xy = rewriter.create(loc, eleTy, x0, y1); - auto ri = rewriter.create(loc, eleTy, xy, yx); - auto yy = rewriter.create(loc, eleTy, y0, y1); - auto rr = rewriter.create(loc, eleTy, xx, yy); + auto xx = rewriter.create(loc, eleTy, x0, x1, fmf); + auto yx = rewriter.create(loc, eleTy, y0, x1, fmf); + auto xy = rewriter.create(loc, eleTy, x0, y1, fmf); + auto ri = rewriter.create(loc, eleTy, xy, yx, fmf); + auto yy = rewriter.create(loc, eleTy, y0, y1, fmf); + auto rr = rewriter.create(loc, eleTy, xx, yy, fmf); auto ra = rewriter.create(loc, ty); auto r1 = rewriter.create(loc, ra, rr, 0); auto r0 = rewriter.create(loc, r1, ri, 1); @@ -3594,6 +3605,7 @@ struct DivcOpConversion : public FIROpConversion { // Just generate inline code for now. // given: (x + iy) / (x' + iy') // result: ((xx'+yy')/d) + i((yx'-xy')/d) where d = x'x' + y'y' + mlir::LLVM::FastmathFlagsAttr fmf = getLLVMFMFAttr(divc); mlir::Value a = adaptor.getOperands()[0]; mlir::Value b = adaptor.getOperands()[1]; auto loc = divc.getLoc(); @@ -3603,17 +3615,17 @@ struct DivcOpConversion : public FIROpConversion { auto y0 = rewriter.create(loc, a, 1); auto x1 = rewriter.create(loc, b, 0); auto y1 = rewriter.create(loc, b, 1); - auto xx = rewriter.create(loc, eleTy, x0, x1); - auto x1x1 = rewriter.create(loc, eleTy, x1, x1); - auto yx = rewriter.create(loc, eleTy, y0, x1); - auto xy = rewriter.create(loc, eleTy, x0, y1); - auto yy = rewriter.create(loc, eleTy, y0, y1); - auto y1y1 = rewriter.create(loc, eleTy, y1, y1); - auto d = rewriter.create(loc, eleTy, x1x1, y1y1); - auto rrn = rewriter.create(loc, eleTy, xx, yy); - auto rin = rewriter.create(loc, eleTy, yx, xy); - auto rr = rewriter.create(loc, eleTy, rrn, d); - auto ri = rewriter.create(loc, eleTy, rin, d); + auto xx = rewriter.create(loc, eleTy, x0, x1, fmf); + auto x1x1 = rewriter.create(loc, eleTy, x1, x1, fmf); + auto yx = rewriter.create(loc, eleTy, y0, x1, fmf); + auto xy = rewriter.create(loc, eleTy, x0, y1, fmf); + auto yy = rewriter.create(loc, eleTy, y0, y1, fmf); + auto y1y1 = rewriter.create(loc, eleTy, y1, y1, fmf); + auto d = rewriter.create(loc, eleTy, x1x1, y1y1, fmf); + auto rrn = rewriter.create(loc, eleTy, xx, yy, fmf); + auto rin = rewriter.create(loc, eleTy, yx, xy, fmf); + auto rr = rewriter.create(loc, eleTy, rrn, d, fmf); + auto ri = rewriter.create(loc, eleTy, rin, d, fmf); auto ra = rewriter.create(loc, ty); auto r1 = rewriter.create(loc, ra, rr, 0); auto r0 = rewriter.create(loc, r1, ri, 1); diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir index cecfbff7eac228..c9a44914b98705 100644 --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -507,7 +507,7 @@ func.func @test_call_return_val() -> i32 { // result: (x + x') + i(y + y') func.func @fir_complex_add(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.complex<16> { - %c = fir.addc %a, %b : !fir.complex<16> + %c = fir.addc %a, %b {fastmath = #arith.fastmath} : !fir.complex<16> return %c : !fir.complex<16> } @@ -518,8 +518,8 @@ func.func @fir_complex_add(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)> // CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)> // CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)> -// CHECK: %[[ADD_X0_X1:.*]] = llvm.fadd %[[X0]], %[[X1]] : f128 -// CHECK: %[[ADD_Y0_Y1:.*]] = llvm.fadd %[[Y0]], %[[Y1]] : f128 +// CHECK: %[[ADD_X0_X1:.*]] = llvm.fadd %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[ADD_Y0_Y1:.*]] = llvm.fadd %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 // CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[ADD_X0_X1]], %{{.*}}[0] : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[ADD_Y0_Y1]], %{{.*}}[1] : !llvm.struct<(f128, f128)> @@ -532,7 +532,7 @@ func.func @fir_complex_add(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // result: (x - x') + i(y - y') func.func @fir_complex_sub(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.complex<16> { - %c = fir.subc %a, %b : !fir.complex<16> + %c = fir.subc %a, %b {fastmath = #arith.fastmath} : !fir.complex<16> return %c : !fir.complex<16> } @@ -543,8 +543,8 @@ func.func @fir_complex_sub(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)> // CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)> // CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)> -// CHECK: %[[SUB_X0_X1:.*]] = llvm.fsub %[[X0]], %[[X1]] : f128 -// CHECK: %[[SUB_Y0_Y1:.*]] = llvm.fsub %[[Y0]], %[[Y1]] : f128 +// CHECK: %[[SUB_X0_X1:.*]] = llvm.fsub %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[SUB_Y0_Y1:.*]] = llvm.fsub %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 // CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[SUB_X0_X1]], %{{.*}}[0] : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[SUB_Y0_Y1]], %{{.*}}[1] : !llvm.struct<(f128, f128)> @@ -557,7 +557,7 @@ func.func @fir_complex_sub(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // result: (xx'-yy')+i(xy'+yx') func.func @fir_complex_mul(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.complex<16> { - %c = fir.mulc %a, %b : !fir.complex<16> + %c = fir.mulc %a, %b {fastmath = #arith.fastmath} : !fir.complex<16> return %c : !fir.complex<16> } @@ -568,12 +568,12 @@ func.func @fir_complex_mul(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)> // CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)> // CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)> -// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] : f128 -// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] : f128 -// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] : f128 -// CHECK: %[[ADD:.*]] = llvm.fadd %[[MUL_X0_Y1]], %[[MUL_Y0_X1]] : f128 -// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] : f128 -// CHECK: %[[SUB:.*]] = llvm.fsub %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] : f128 +// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[ADD:.*]] = llvm.fadd %[[MUL_X0_Y1]], %[[MUL_Y0_X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[SUB:.*]] = llvm.fsub %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] {fastmathFlags = #llvm.fastmath} : f128 // CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[SUB]], %{{.*}}[0] : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[ADD]], %{{.*}}[1] : !llvm.struct<(f128, f128)> @@ -586,7 +586,7 @@ func.func @fir_complex_mul(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // result: ((xx'+yy')/d) + i((yx'-xy')/d) where d = x'x' + y'y' func.func @fir_complex_div(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.complex<16> { - %c = fir.divc %a, %b : !fir.complex<16> + %c = fir.divc %a, %b {fastmath = #arith.fastmath} : !fir.complex<16> return %c : !fir.complex<16> } @@ -597,17 +597,17 @@ func.func @fir_complex_div(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c // CHECK: %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)> // CHECK: %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)> // CHECK: %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)> -// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] : f128 -// CHECK: %[[MUL_X1_X1:.*]] = llvm.fmul %[[X1]], %[[X1]] : f128 -// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] : f128 -// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] : f128 -// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] : f128 -// CHECK: %[[MUL_Y1_Y1:.*]] = llvm.fmul %[[Y1]], %[[Y1]] : f128 -// CHECK: %[[ADD_X1X1_Y1Y1:.*]] = llvm.fadd %[[MUL_X1_X1]], %[[MUL_Y1_Y1]] : f128 -// CHECK: %[[ADD_X0X1_Y0Y1:.*]] = llvm.fadd %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] : f128 -// CHECK: %[[SUB_Y0X1_X0Y1:.*]] = llvm.fsub %[[MUL_Y0_X1]], %[[MUL_X0_Y1]] : f128 -// CHECK: %[[DIV0:.*]] = llvm.fdiv %[[ADD_X0X1_Y0Y1]], %[[ADD_X1X1_Y1Y1]] : f128 -// CHECK: %[[DIV1:.*]] = llvm.fdiv %[[SUB_Y0X1_X0Y1]], %[[ADD_X1X1_Y1Y1]] : f128 +// CHECK: %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_X1_X1:.*]] = llvm.fmul %[[X1]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[MUL_Y1_Y1:.*]] = llvm.fmul %[[Y1]], %[[Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[ADD_X1X1_Y1Y1:.*]] = llvm.fadd %[[MUL_X1_X1]], %[[MUL_Y1_Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[ADD_X0X1_Y0Y1:.*]] = llvm.fadd %[[MUL_X0_X1]], %[[MUL_Y0_Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[SUB_Y0X1_X0Y1:.*]] = llvm.fsub %[[MUL_Y0_X1]], %[[MUL_X0_Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[DIV0:.*]] = llvm.fdiv %[[ADD_X0X1_Y0Y1]], %[[ADD_X1X1_Y1Y1]] {fastmathFlags = #llvm.fastmath} : f128 +// CHECK: %[[DIV1:.*]] = llvm.fdiv %[[SUB_Y0X1_X0Y1]], %[[ADD_X1X1_Y1Y1]] {fastmathFlags = #llvm.fastmath} : f128 // CHECK: %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[DIV0]], %{{.*}}[0] : !llvm.struct<(f128, f128)> // CHECK: %{{.*}} = llvm.insertvalue %[[DIV1]], %{{.*}}[1] : !llvm.struct<(f128, f128)> diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90 index 8db6da3de81b29..6b89577cc54581 100644 --- a/flang/test/Lower/HLFIR/binary-ops.f90 +++ b/flang/test/Lower/HLFIR/binary-ops.f90 @@ -32,7 +32,7 @@ subroutine complex_add(x, y, z) ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref> ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref> -! CHECK: %[[VAL_8:.*]] = fir.addc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4> +! CHECK: %[[VAL_8:.*]] = fir.addc %[[VAL_6]], %[[VAL_7]] {fastmath = #arith.fastmath} : !fir.complex<4> subroutine int_sub(x, y, z) integer :: x, y, z @@ -65,7 +65,7 @@ subroutine complex_sub(x, y, z) ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref> ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref> -! CHECK: %[[VAL_8:.*]] = fir.subc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4> +! CHECK: %[[VAL_8:.*]] = fir.subc %[[VAL_6]], %[[VAL_7]] {fastmath = #arith.fastmath} : !fir.complex<4> subroutine int_mul(x, y, z) integer :: x, y, z @@ -98,7 +98,7 @@ subroutine complex_mul(x, y, z) ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref> ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref> -! CHECK: %[[VAL_8:.*]] = fir.mulc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4> +! CHECK: %[[VAL_8:.*]] = fir.mulc %[[VAL_6]], %[[VAL_7]] {fastmath = #arith.fastmath} : !fir.complex<4> subroutine int_div(x, y, z) integer :: x, y, z diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 index b874d5219625df..8671c280c2fb31 100644 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -163,7 +163,7 @@ ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): ! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> ! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[COMBINED:.*]] = fir.mulc %[[LOAD0]], %[[LOAD1]] : !fir.complex<4> +! CHECK: %[[COMBINED:.*]] = fir.mulc %[[LOAD0]], %[[LOAD1]] {fastmath = #arith.fastmath} : !fir.complex<4> ! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref> ! CHECK: acc.yield %[[ARG0]] : !fir.ref> ! CHECK: } @@ -183,7 +183,7 @@ ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): ! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> ! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[COMBINED:.*]] = fir.addc %[[LOAD0]], %[[LOAD1]] : !fir.complex<4> +! CHECK: %[[COMBINED:.*]] = fir.addc %[[LOAD0]], %[[LOAD1]] {fastmath = #arith.fastmath} : !fir.complex<4> ! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref> ! CHECK: acc.yield %[[ARG0]] : !fir.ref> ! CHECK: } diff --git a/flang/test/Lower/array-elemental-calls-2.f90 b/flang/test/Lower/array-elemental-calls-2.f90 index 94e24a9910bc26..0d6e34c6391c3d 100644 --- a/flang/test/Lower/array-elemental-calls-2.f90 +++ b/flang/test/Lower/array-elemental-calls-2.f90 @@ -144,7 +144,7 @@ subroutine check_cmplx_part() ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref> ! CHECK: fir.do_loop ! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.complex<8>>, index) -> !fir.complex<8> -! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] : !fir.complex<8> +! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] {fastmath = #arith.fastmath} : !fir.complex<8> ! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (!fir.complex<8>) -> f64 ! CHECK: fir.call @_QPelem_func_real(%[[VAL_25]]) {{.*}}: (f64) -> i32 end subroutine diff --git a/flang/test/Lower/assignment.f90 b/flang/test/Lower/assignment.f90 index 9b5039e3ea88eb..058842828d2687 100644 --- a/flang/test/Lower/assignment.f90 +++ b/flang/test/Lower/assignment.f90 @@ -203,7 +203,7 @@ real function divf(a, b) ! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4> ! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref> ! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref> -! CHECK: %[[ADD:.*]] = fir.addc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4> +! CHECK: %[[ADD:.*]] = fir.addc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath} : !fir.complex<4> ! CHECK: fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref> ! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref> ! CHECK: return %[[RET]] : !fir.complex<4> @@ -219,7 +219,7 @@ real function divf(a, b) ! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4> ! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref> ! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref> -! CHECK: %[[SUB:.*]] = fir.subc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4> +! CHECK: %[[SUB:.*]] = fir.subc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath} : !fir.complex<4> ! CHECK: fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref> ! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref> ! CHECK: return %[[RET]] : !fir.complex<4> @@ -235,7 +235,7 @@ real function divf(a, b) ! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4> ! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref> ! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref> -! CHECK: %[[MUL:.*]] = fir.mulc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4> +! CHECK: %[[MUL:.*]] = fir.mulc %[[A_VAL]], %[[B_VAL]] {fastmath = #arith.fastmath} : !fir.complex<4> ! CHECK: fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref> ! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref> ! CHECK: return %[[RET]] : !fir.complex<4>