Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir][flang] add fast math attribute to fcmp #74315

Merged
merged 2 commits into from
Dec 6, 2023

Conversation

tblah
Copy link
Contributor

@tblah tblah commented Dec 4, 2023

llvm.fcmp does support fast math attributes therefore so should arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath<contract> by default on all operations that support the fast math interface. Downstream users of MLIR should not be so effected.

This was requested in #74263

llvm.fcmp does support fast math attributes therefore so should
arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath<contract>
by default on all operations that support the fast math interface.
Downstream users of MLIR should not be so effected.

This was requested in llvm#74263
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 4, 2023

@llvm/pr-subscribers-flang-codegen

@llvm/pr-subscribers-mlir

Author: Tom Eccles (tblah)

Changes

llvm.fcmp does support fast math attributes therefore so should arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath&lt;contract&gt; by default on all operations that support the fast math interface. Downstream users of MLIR should not be so effected.

This was requested in #74263


Patch is 49.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74315.diff

27 Files Affected:

  • (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+6-2)
  • (modified) flang/test/Fir/convert-to-llvm.fir (+7-7)
  • (modified) flang/test/Fir/fir-ops.fir (+16-16)
  • (modified) flang/test/HLFIR/call_with_poly_dummy.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/binary-ops.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/bessel_jn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/bessel_yn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/dim.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/min.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/modulo.f90 (+3-3)
  • (modified) flang/test/Lower/Intrinsics/nearest.f90 (+5-5)
  • (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+7-7)
  • (modified) flang/test/Lower/arithmetic-goto.f90 (+2-2)
  • (modified) flang/test/Lower/array-elemental-calls-2.f90 (+1-1)
  • (modified) flang/test/Lower/array-expression-slice-1.f90 (+9-9)
  • (modified) flang/test/Lower/array-user-def-assignments.f90 (+3-3)
  • (modified) flang/test/Lower/forall/forall-construct.f90 (+1-1)
  • (modified) flang/test/Lower/forall/forall-where.f90 (+1-1)
  • (modified) flang/test/Lower/host-associated.f90 (+1-1)
  • (modified) flang/test/Lower/real-operations-2.f90 (+6-6)
  • (modified) flang/test/Lower/where.f90 (+3-3)
  • (modified) flang/test/Transforms/simplifyintrinsics.fir (+2-2)
  • (modified) mlir/include/mlir/Dialect/Arith/IR/ArithOps.td (+16-2)
  • (modified) mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp (+5-2)
  • (modified) mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir (+3)
  • (modified) mlir/test/Dialect/Arith/ops.mlir (+2)
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 14a3879906186..fcecc605dfa5c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2553,14 +2553,18 @@ def fir_DivcOp : ComplexArithmeticOp<"divc",
 // Pow is a builtin call and not a primitive
 
 def fir_CmpcOp : fir_Op<"cmpc",
-    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape]> {
+    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape,
+    DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
   let summary = "complex floating-point comparison operator";
 
   let description = [{
     A complex comparison to handle complex types found in FIR.
   }];
 
-  let arguments = (ins fir_ComplexType:$lhs, fir_ComplexType:$rhs);
+  let arguments = (ins
+      fir_ComplexType:$lhs,
+      fir_ComplexType:$rhs,
+      DefaultValuedAttr<Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath);
 
   let results = (outs AnyLogicalLike);
 
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index c9a44914b9870..e2cce1814d73b 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -650,13 +650,13 @@ func.func @compare_complex_eq(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] {fastmath = {{.*}}} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] {fastmath = {{.*}}} : f64
 // CHECK: [[RES:%.*]] = llvm.and [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "une", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "une", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -667,13 +667,13 @@ func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] {fastmath = #llvm.fastmath<fast>} : f64
 // CHECK: [[RES:%.*]] = llvm.or [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "ogt", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "ogt", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -682,7 +682,7 @@ func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) ->
 // CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
-// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] : f64
+// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>}} : f64
 // CHECK: return [[RESR]] : i1
 
 // -----
diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index dd0fbb3be36c4..3c4095b9fdb14 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -464,37 +464,37 @@ fir.type_info @test_type_info noinit nodestroy nofinal extends !fir.type<parent{
 // CHECK-SAME: [[VAL_151:%.*]]: !fir.complex<16>, [[VAL_152:%.*]]: !fir.complex<16>) {
 func.func @compare_complex(%a : !fir.complex<16>, %b : !fir.complex<16>) {
 
-// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %d0 = fir.cmpc "false", %a, %b : !fir.complex<16>
   %d1 = fir.cmpc "oeq", %a, %b : !fir.complex<16>
   %d2 = fir.cmpc "ogt", %a, %b : !fir.complex<16>
   %d3 = fir.cmpc "oge", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %a0 = fir.cmpc "olt", %a, %b : !fir.complex<16>
   %a1 = fir.cmpc "ole", %a, %b : !fir.complex<16>
   %a2 = fir.cmpc "one", %a, %b : !fir.complex<16>
   %a3 = fir.cmpc "ord", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %b0 = fir.cmpc "ueq", %a, %b : !fir.complex<16>
   %b1 = fir.cmpc "ugt", %a, %b : !fir.complex<16>
   %b2 = fir.cmpc "uge", %a, %b : !fir.complex<16>
   %b3 = fir.cmpc "ult", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %c0 = fir.cmpc "ule", %a, %b : !fir.complex<16>
   %c1 = fir.cmpc "une", %a, %b : !fir.complex<16>
   %c2 = fir.cmpc "uno", %a, %b : !fir.complex<16>
diff --git a/flang/test/HLFIR/call_with_poly_dummy.f90 b/flang/test/HLFIR/call_with_poly_dummy.f90
index c4b98fbe5f557..af6876e26603e 100644
--- a/flang/test/HLFIR/call_with_poly_dummy.f90
+++ b/flang/test/HLFIR/call_with_poly_dummy.f90
@@ -25,7 +25,7 @@ end subroutine test1
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
 ! CHECK:           %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] : f32
+! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] {{.*}} : f32
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
 ! CHECK:           %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
 ! CHECK:           %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0 : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
index 6b89577cc5458..e0af9258cda32 100644
--- a/flang/test/Lower/HLFIR/binary-ops.f90
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -246,7 +246,7 @@ subroutine cmp_real(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] : f32
+! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] {{.*}} : f32
 
 subroutine cmp_real_2(l, x, y)
   logical :: l
@@ -273,7 +273,7 @@ subroutine cmp_cmplx(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
-! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] {{.*}} : !fir.complex<4>
 
 subroutine cmp_char(l, x, y)
   logical :: l
diff --git a/flang/test/Lower/HLFIR/user-defined-assignment.f90 b/flang/test/Lower/HLFIR/user-defined-assignment.f90
index a41044a60fd89..6f887cb00de31 100644
--- a/flang/test/Lower/HLFIR/user-defined-assignment.f90
+++ b/flang/test/Lower/HLFIR/user-defined-assignment.f90
@@ -101,7 +101,7 @@ subroutine test_non_elemental_array(x)
 ! CHECK:      ^bb0(%[[VAL_7:.*]]: index):
 ! CHECK:        %[[VAL_8:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_7]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
 ! CHECK:        %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<f32>
-! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] : f32
+! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] {{.*}} : f32
 ! CHECK:        %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i1) -> !fir.logical<4>
 ! CHECK:        hlfir.yield_element %[[VAL_11]] : !fir.logical<4>
 ! CHECK:      }
diff --git a/flang/test/Lower/Intrinsics/bessel_jn.f90 b/flang/test/Lower/Intrinsics/bessel_jn.f90
index 3fdef7446100d..428733d547d7b 100644
--- a/flang/test/Lower/Intrinsics/bessel_jn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_jn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/bessel_yn.f90 b/flang/test/Lower/Intrinsics/bessel_yn.f90
index 9f4fbfbb89d31..ac77e4db5614d 100644
--- a/flang/test/Lower/Intrinsics/bessel_yn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_yn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/dim.f90 b/flang/test/Lower/Intrinsics/dim.f90
index 6b6d2179fad9f..fb1a496570ca1 100644
--- a/flang/test/Lower/Intrinsics/dim.f90
+++ b/flang/test/Lower/Intrinsics/dim.f90
@@ -8,7 +8,7 @@ subroutine dim_testr(x, y, z)
 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<f32>
 ! CHECK: %[[VAL_5:.*]] = arith.constant 0.000000e+00 : f32
 ! CHECK: %[[VAL_6:.*]] = arith.subf %[[VAL_3]], %[[VAL_4]] {{.*}}: f32
-! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] {{.*}} : f32
 ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : f32
 ! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<f32>
 ! CHECK: return
diff --git a/flang/test/Lower/Intrinsics/min.f90 b/flang/test/Lower/Intrinsics/min.f90
index 40e6d96db6e53..c9744cf33d827 100644
--- a/flang/test/Lower/Intrinsics/min.f90
+++ b/flang/test/Lower/Intrinsics/min.f90
@@ -18,11 +18,11 @@ real function test(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_10:.*]] = fir.is_present %[[VAL_5]]#0 : (!fir.ref<f32>) -> i1
-! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] : f32
+! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] {{.*}} : f32
 ! CHECK:           %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_8]], %[[VAL_9]] : f32
 ! CHECK:           %[[VAL_13:.*]] = fir.if %[[VAL_10]] -> (f32) {
 ! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] : f32
+! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] {{.*}} : f32
 ! CHECK:             %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_12]], %[[VAL_14]] : f32
 ! CHECK:             fir.result %[[VAL_16]] : f32
 ! CHECK:           } else {
diff --git a/flang/test/Lower/Intrinsics/modulo.f90 b/flang/test/Lower/Intrinsics/modulo.f90
index 4c8c1ff4da3b0..64a6607a09ccd 100644
--- a/flang/test/Lower/Intrinsics/modulo.f90
+++ b/flang/test/Lower/Intrinsics/modulo.f90
@@ -8,9 +8,9 @@ subroutine modulo_testr(r, a, p)
     ! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
     ! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
     ! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] : f64
-    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] : f64
-    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] : f64
+    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
     ! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
     ! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
     ! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
diff --git a/flang/test/Lower/Intrinsics/nearest.f90 b/flang/test/Lower/Intrinsics/nearest.f90
index 02ded4919dd7e..a023fa8cd804e 100644
--- a/flang/test/Lower/Intrinsics/nearest.f90
+++ b/flang/test/Lower/Intrinsics/nearest.f90
@@ -7,7 +7,7 @@ subroutine nearest_test1(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f32>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest4(%[[x]], %[[pos]]) {{.*}}: (f32, i1) -> f32
@@ -21,7 +21,7 @@ subroutine nearest_test2(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f64>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f64>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f64
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f64
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest8(%[[x]], %[[pos]]) {{.*}}: (f64, i1) -> f64
@@ -35,7 +35,7 @@ subroutine nearest_test3(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f80>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f80>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f80
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f80
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f80
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest10(%[[x]], %[[pos]]) {{.*}}: (f80, i1) -> f80
@@ -49,7 +49,7 @@ subroutine nearest_test4(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f128>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f128>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f128
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f128
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f128
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
@@ -64,7 +64,7 @@ subroutine nearest_test5(x, s)
     real :: s
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 98fef6a2d2f29..9db63c10c1f85 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reductio...
[truncated]

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 4, 2023

@llvm/pr-subscribers-mlir-arith

Author: Tom Eccles (tblah)

Changes

llvm.fcmp does support fast math attributes therefore so should arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath&lt;contract&gt; by default on all operations that support the fast math interface. Downstream users of MLIR should not be so effected.

This was requested in #74263


Patch is 49.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74315.diff

27 Files Affected:

  • (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+6-2)
  • (modified) flang/test/Fir/convert-to-llvm.fir (+7-7)
  • (modified) flang/test/Fir/fir-ops.fir (+16-16)
  • (modified) flang/test/HLFIR/call_with_poly_dummy.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/binary-ops.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/bessel_jn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/bessel_yn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/dim.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/min.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/modulo.f90 (+3-3)
  • (modified) flang/test/Lower/Intrinsics/nearest.f90 (+5-5)
  • (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+7-7)
  • (modified) flang/test/Lower/arithmetic-goto.f90 (+2-2)
  • (modified) flang/test/Lower/array-elemental-calls-2.f90 (+1-1)
  • (modified) flang/test/Lower/array-expression-slice-1.f90 (+9-9)
  • (modified) flang/test/Lower/array-user-def-assignments.f90 (+3-3)
  • (modified) flang/test/Lower/forall/forall-construct.f90 (+1-1)
  • (modified) flang/test/Lower/forall/forall-where.f90 (+1-1)
  • (modified) flang/test/Lower/host-associated.f90 (+1-1)
  • (modified) flang/test/Lower/real-operations-2.f90 (+6-6)
  • (modified) flang/test/Lower/where.f90 (+3-3)
  • (modified) flang/test/Transforms/simplifyintrinsics.fir (+2-2)
  • (modified) mlir/include/mlir/Dialect/Arith/IR/ArithOps.td (+16-2)
  • (modified) mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp (+5-2)
  • (modified) mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir (+3)
  • (modified) mlir/test/Dialect/Arith/ops.mlir (+2)
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 14a3879906186..fcecc605dfa5c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2553,14 +2553,18 @@ def fir_DivcOp : ComplexArithmeticOp<"divc",
 // Pow is a builtin call and not a primitive
 
 def fir_CmpcOp : fir_Op<"cmpc",
-    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape]> {
+    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape,
+    DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
   let summary = "complex floating-point comparison operator";
 
   let description = [{
     A complex comparison to handle complex types found in FIR.
   }];
 
-  let arguments = (ins fir_ComplexType:$lhs, fir_ComplexType:$rhs);
+  let arguments = (ins
+      fir_ComplexType:$lhs,
+      fir_ComplexType:$rhs,
+      DefaultValuedAttr<Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath);
 
   let results = (outs AnyLogicalLike);
 
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index c9a44914b9870..e2cce1814d73b 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -650,13 +650,13 @@ func.func @compare_complex_eq(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] {fastmath = {{.*}}} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] {fastmath = {{.*}}} : f64
 // CHECK: [[RES:%.*]] = llvm.and [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "une", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "une", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -667,13 +667,13 @@ func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] {fastmath = #llvm.fastmath<fast>} : f64
 // CHECK: [[RES:%.*]] = llvm.or [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "ogt", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "ogt", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -682,7 +682,7 @@ func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) ->
 // CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
-// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] : f64
+// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>}} : f64
 // CHECK: return [[RESR]] : i1
 
 // -----
diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index dd0fbb3be36c4..3c4095b9fdb14 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -464,37 +464,37 @@ fir.type_info @test_type_info noinit nodestroy nofinal extends !fir.type<parent{
 // CHECK-SAME: [[VAL_151:%.*]]: !fir.complex<16>, [[VAL_152:%.*]]: !fir.complex<16>) {
 func.func @compare_complex(%a : !fir.complex<16>, %b : !fir.complex<16>) {
 
-// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %d0 = fir.cmpc "false", %a, %b : !fir.complex<16>
   %d1 = fir.cmpc "oeq", %a, %b : !fir.complex<16>
   %d2 = fir.cmpc "ogt", %a, %b : !fir.complex<16>
   %d3 = fir.cmpc "oge", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %a0 = fir.cmpc "olt", %a, %b : !fir.complex<16>
   %a1 = fir.cmpc "ole", %a, %b : !fir.complex<16>
   %a2 = fir.cmpc "one", %a, %b : !fir.complex<16>
   %a3 = fir.cmpc "ord", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %b0 = fir.cmpc "ueq", %a, %b : !fir.complex<16>
   %b1 = fir.cmpc "ugt", %a, %b : !fir.complex<16>
   %b2 = fir.cmpc "uge", %a, %b : !fir.complex<16>
   %b3 = fir.cmpc "ult", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %c0 = fir.cmpc "ule", %a, %b : !fir.complex<16>
   %c1 = fir.cmpc "une", %a, %b : !fir.complex<16>
   %c2 = fir.cmpc "uno", %a, %b : !fir.complex<16>
diff --git a/flang/test/HLFIR/call_with_poly_dummy.f90 b/flang/test/HLFIR/call_with_poly_dummy.f90
index c4b98fbe5f557..af6876e26603e 100644
--- a/flang/test/HLFIR/call_with_poly_dummy.f90
+++ b/flang/test/HLFIR/call_with_poly_dummy.f90
@@ -25,7 +25,7 @@ end subroutine test1
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
 ! CHECK:           %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] : f32
+! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] {{.*}} : f32
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
 ! CHECK:           %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
 ! CHECK:           %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0 : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
index 6b89577cc5458..e0af9258cda32 100644
--- a/flang/test/Lower/HLFIR/binary-ops.f90
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -246,7 +246,7 @@ subroutine cmp_real(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] : f32
+! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] {{.*}} : f32
 
 subroutine cmp_real_2(l, x, y)
   logical :: l
@@ -273,7 +273,7 @@ subroutine cmp_cmplx(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
-! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] {{.*}} : !fir.complex<4>
 
 subroutine cmp_char(l, x, y)
   logical :: l
diff --git a/flang/test/Lower/HLFIR/user-defined-assignment.f90 b/flang/test/Lower/HLFIR/user-defined-assignment.f90
index a41044a60fd89..6f887cb00de31 100644
--- a/flang/test/Lower/HLFIR/user-defined-assignment.f90
+++ b/flang/test/Lower/HLFIR/user-defined-assignment.f90
@@ -101,7 +101,7 @@ subroutine test_non_elemental_array(x)
 ! CHECK:      ^bb0(%[[VAL_7:.*]]: index):
 ! CHECK:        %[[VAL_8:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_7]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
 ! CHECK:        %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<f32>
-! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] : f32
+! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] {{.*}} : f32
 ! CHECK:        %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i1) -> !fir.logical<4>
 ! CHECK:        hlfir.yield_element %[[VAL_11]] : !fir.logical<4>
 ! CHECK:      }
diff --git a/flang/test/Lower/Intrinsics/bessel_jn.f90 b/flang/test/Lower/Intrinsics/bessel_jn.f90
index 3fdef7446100d..428733d547d7b 100644
--- a/flang/test/Lower/Intrinsics/bessel_jn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_jn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/bessel_yn.f90 b/flang/test/Lower/Intrinsics/bessel_yn.f90
index 9f4fbfbb89d31..ac77e4db5614d 100644
--- a/flang/test/Lower/Intrinsics/bessel_yn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_yn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/dim.f90 b/flang/test/Lower/Intrinsics/dim.f90
index 6b6d2179fad9f..fb1a496570ca1 100644
--- a/flang/test/Lower/Intrinsics/dim.f90
+++ b/flang/test/Lower/Intrinsics/dim.f90
@@ -8,7 +8,7 @@ subroutine dim_testr(x, y, z)
 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<f32>
 ! CHECK: %[[VAL_5:.*]] = arith.constant 0.000000e+00 : f32
 ! CHECK: %[[VAL_6:.*]] = arith.subf %[[VAL_3]], %[[VAL_4]] {{.*}}: f32
-! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] {{.*}} : f32
 ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : f32
 ! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<f32>
 ! CHECK: return
diff --git a/flang/test/Lower/Intrinsics/min.f90 b/flang/test/Lower/Intrinsics/min.f90
index 40e6d96db6e53..c9744cf33d827 100644
--- a/flang/test/Lower/Intrinsics/min.f90
+++ b/flang/test/Lower/Intrinsics/min.f90
@@ -18,11 +18,11 @@ real function test(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_10:.*]] = fir.is_present %[[VAL_5]]#0 : (!fir.ref<f32>) -> i1
-! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] : f32
+! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] {{.*}} : f32
 ! CHECK:           %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_8]], %[[VAL_9]] : f32
 ! CHECK:           %[[VAL_13:.*]] = fir.if %[[VAL_10]] -> (f32) {
 ! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] : f32
+! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] {{.*}} : f32
 ! CHECK:             %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_12]], %[[VAL_14]] : f32
 ! CHECK:             fir.result %[[VAL_16]] : f32
 ! CHECK:           } else {
diff --git a/flang/test/Lower/Intrinsics/modulo.f90 b/flang/test/Lower/Intrinsics/modulo.f90
index 4c8c1ff4da3b0..64a6607a09ccd 100644
--- a/flang/test/Lower/Intrinsics/modulo.f90
+++ b/flang/test/Lower/Intrinsics/modulo.f90
@@ -8,9 +8,9 @@ subroutine modulo_testr(r, a, p)
     ! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
     ! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
     ! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] : f64
-    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] : f64
-    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] : f64
+    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
     ! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
     ! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
     ! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
diff --git a/flang/test/Lower/Intrinsics/nearest.f90 b/flang/test/Lower/Intrinsics/nearest.f90
index 02ded4919dd7e..a023fa8cd804e 100644
--- a/flang/test/Lower/Intrinsics/nearest.f90
+++ b/flang/test/Lower/Intrinsics/nearest.f90
@@ -7,7 +7,7 @@ subroutine nearest_test1(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f32>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest4(%[[x]], %[[pos]]) {{.*}}: (f32, i1) -> f32
@@ -21,7 +21,7 @@ subroutine nearest_test2(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f64>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f64>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f64
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f64
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest8(%[[x]], %[[pos]]) {{.*}}: (f64, i1) -> f64
@@ -35,7 +35,7 @@ subroutine nearest_test3(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f80>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f80>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f80
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f80
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f80
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest10(%[[x]], %[[pos]]) {{.*}}: (f80, i1) -> f80
@@ -49,7 +49,7 @@ subroutine nearest_test4(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f128>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f128>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f128
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f128
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f128
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
@@ -64,7 +64,7 @@ subroutine nearest_test5(x, s)
     real :: s
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 98fef6a2d2f29..9db63c10c1f85 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reductio...
[truncated]

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 4, 2023

@llvm/pr-subscribers-openacc

Author: Tom Eccles (tblah)

Changes

llvm.fcmp does support fast math attributes therefore so should arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath&lt;contract&gt; by default on all operations that support the fast math interface. Downstream users of MLIR should not be so effected.

This was requested in #74263


Patch is 49.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74315.diff

27 Files Affected:

  • (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+6-2)
  • (modified) flang/test/Fir/convert-to-llvm.fir (+7-7)
  • (modified) flang/test/Fir/fir-ops.fir (+16-16)
  • (modified) flang/test/HLFIR/call_with_poly_dummy.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/binary-ops.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/bessel_jn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/bessel_yn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/dim.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/min.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/modulo.f90 (+3-3)
  • (modified) flang/test/Lower/Intrinsics/nearest.f90 (+5-5)
  • (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+7-7)
  • (modified) flang/test/Lower/arithmetic-goto.f90 (+2-2)
  • (modified) flang/test/Lower/array-elemental-calls-2.f90 (+1-1)
  • (modified) flang/test/Lower/array-expression-slice-1.f90 (+9-9)
  • (modified) flang/test/Lower/array-user-def-assignments.f90 (+3-3)
  • (modified) flang/test/Lower/forall/forall-construct.f90 (+1-1)
  • (modified) flang/test/Lower/forall/forall-where.f90 (+1-1)
  • (modified) flang/test/Lower/host-associated.f90 (+1-1)
  • (modified) flang/test/Lower/real-operations-2.f90 (+6-6)
  • (modified) flang/test/Lower/where.f90 (+3-3)
  • (modified) flang/test/Transforms/simplifyintrinsics.fir (+2-2)
  • (modified) mlir/include/mlir/Dialect/Arith/IR/ArithOps.td (+16-2)
  • (modified) mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp (+5-2)
  • (modified) mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir (+3)
  • (modified) mlir/test/Dialect/Arith/ops.mlir (+2)
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 14a3879906186..fcecc605dfa5c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2553,14 +2553,18 @@ def fir_DivcOp : ComplexArithmeticOp<"divc",
 // Pow is a builtin call and not a primitive
 
 def fir_CmpcOp : fir_Op<"cmpc",
-    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape]> {
+    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape,
+    DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
   let summary = "complex floating-point comparison operator";
 
   let description = [{
     A complex comparison to handle complex types found in FIR.
   }];
 
-  let arguments = (ins fir_ComplexType:$lhs, fir_ComplexType:$rhs);
+  let arguments = (ins
+      fir_ComplexType:$lhs,
+      fir_ComplexType:$rhs,
+      DefaultValuedAttr<Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath);
 
   let results = (outs AnyLogicalLike);
 
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index c9a44914b9870..e2cce1814d73b 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -650,13 +650,13 @@ func.func @compare_complex_eq(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] {fastmath = {{.*}}} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] {fastmath = {{.*}}} : f64
 // CHECK: [[RES:%.*]] = llvm.and [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "une", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "une", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -667,13 +667,13 @@ func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] {fastmath = #llvm.fastmath<fast>} : f64
 // CHECK: [[RES:%.*]] = llvm.or [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "ogt", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "ogt", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -682,7 +682,7 @@ func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) ->
 // CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
-// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] : f64
+// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>}} : f64
 // CHECK: return [[RESR]] : i1
 
 // -----
diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index dd0fbb3be36c4..3c4095b9fdb14 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -464,37 +464,37 @@ fir.type_info @test_type_info noinit nodestroy nofinal extends !fir.type<parent{
 // CHECK-SAME: [[VAL_151:%.*]]: !fir.complex<16>, [[VAL_152:%.*]]: !fir.complex<16>) {
 func.func @compare_complex(%a : !fir.complex<16>, %b : !fir.complex<16>) {
 
-// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %d0 = fir.cmpc "false", %a, %b : !fir.complex<16>
   %d1 = fir.cmpc "oeq", %a, %b : !fir.complex<16>
   %d2 = fir.cmpc "ogt", %a, %b : !fir.complex<16>
   %d3 = fir.cmpc "oge", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %a0 = fir.cmpc "olt", %a, %b : !fir.complex<16>
   %a1 = fir.cmpc "ole", %a, %b : !fir.complex<16>
   %a2 = fir.cmpc "one", %a, %b : !fir.complex<16>
   %a3 = fir.cmpc "ord", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %b0 = fir.cmpc "ueq", %a, %b : !fir.complex<16>
   %b1 = fir.cmpc "ugt", %a, %b : !fir.complex<16>
   %b2 = fir.cmpc "uge", %a, %b : !fir.complex<16>
   %b3 = fir.cmpc "ult", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %c0 = fir.cmpc "ule", %a, %b : !fir.complex<16>
   %c1 = fir.cmpc "une", %a, %b : !fir.complex<16>
   %c2 = fir.cmpc "uno", %a, %b : !fir.complex<16>
diff --git a/flang/test/HLFIR/call_with_poly_dummy.f90 b/flang/test/HLFIR/call_with_poly_dummy.f90
index c4b98fbe5f557..af6876e26603e 100644
--- a/flang/test/HLFIR/call_with_poly_dummy.f90
+++ b/flang/test/HLFIR/call_with_poly_dummy.f90
@@ -25,7 +25,7 @@ end subroutine test1
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
 ! CHECK:           %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] : f32
+! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] {{.*}} : f32
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
 ! CHECK:           %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
 ! CHECK:           %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0 : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
index 6b89577cc5458..e0af9258cda32 100644
--- a/flang/test/Lower/HLFIR/binary-ops.f90
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -246,7 +246,7 @@ subroutine cmp_real(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] : f32
+! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] {{.*}} : f32
 
 subroutine cmp_real_2(l, x, y)
   logical :: l
@@ -273,7 +273,7 @@ subroutine cmp_cmplx(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
-! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] {{.*}} : !fir.complex<4>
 
 subroutine cmp_char(l, x, y)
   logical :: l
diff --git a/flang/test/Lower/HLFIR/user-defined-assignment.f90 b/flang/test/Lower/HLFIR/user-defined-assignment.f90
index a41044a60fd89..6f887cb00de31 100644
--- a/flang/test/Lower/HLFIR/user-defined-assignment.f90
+++ b/flang/test/Lower/HLFIR/user-defined-assignment.f90
@@ -101,7 +101,7 @@ subroutine test_non_elemental_array(x)
 ! CHECK:      ^bb0(%[[VAL_7:.*]]: index):
 ! CHECK:        %[[VAL_8:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_7]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
 ! CHECK:        %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<f32>
-! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] : f32
+! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] {{.*}} : f32
 ! CHECK:        %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i1) -> !fir.logical<4>
 ! CHECK:        hlfir.yield_element %[[VAL_11]] : !fir.logical<4>
 ! CHECK:      }
diff --git a/flang/test/Lower/Intrinsics/bessel_jn.f90 b/flang/test/Lower/Intrinsics/bessel_jn.f90
index 3fdef7446100d..428733d547d7b 100644
--- a/flang/test/Lower/Intrinsics/bessel_jn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_jn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/bessel_yn.f90 b/flang/test/Lower/Intrinsics/bessel_yn.f90
index 9f4fbfbb89d31..ac77e4db5614d 100644
--- a/flang/test/Lower/Intrinsics/bessel_yn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_yn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/dim.f90 b/flang/test/Lower/Intrinsics/dim.f90
index 6b6d2179fad9f..fb1a496570ca1 100644
--- a/flang/test/Lower/Intrinsics/dim.f90
+++ b/flang/test/Lower/Intrinsics/dim.f90
@@ -8,7 +8,7 @@ subroutine dim_testr(x, y, z)
 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<f32>
 ! CHECK: %[[VAL_5:.*]] = arith.constant 0.000000e+00 : f32
 ! CHECK: %[[VAL_6:.*]] = arith.subf %[[VAL_3]], %[[VAL_4]] {{.*}}: f32
-! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] {{.*}} : f32
 ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : f32
 ! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<f32>
 ! CHECK: return
diff --git a/flang/test/Lower/Intrinsics/min.f90 b/flang/test/Lower/Intrinsics/min.f90
index 40e6d96db6e53..c9744cf33d827 100644
--- a/flang/test/Lower/Intrinsics/min.f90
+++ b/flang/test/Lower/Intrinsics/min.f90
@@ -18,11 +18,11 @@ real function test(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_10:.*]] = fir.is_present %[[VAL_5]]#0 : (!fir.ref<f32>) -> i1
-! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] : f32
+! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] {{.*}} : f32
 ! CHECK:           %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_8]], %[[VAL_9]] : f32
 ! CHECK:           %[[VAL_13:.*]] = fir.if %[[VAL_10]] -> (f32) {
 ! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] : f32
+! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] {{.*}} : f32
 ! CHECK:             %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_12]], %[[VAL_14]] : f32
 ! CHECK:             fir.result %[[VAL_16]] : f32
 ! CHECK:           } else {
diff --git a/flang/test/Lower/Intrinsics/modulo.f90 b/flang/test/Lower/Intrinsics/modulo.f90
index 4c8c1ff4da3b0..64a6607a09ccd 100644
--- a/flang/test/Lower/Intrinsics/modulo.f90
+++ b/flang/test/Lower/Intrinsics/modulo.f90
@@ -8,9 +8,9 @@ subroutine modulo_testr(r, a, p)
     ! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
     ! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
     ! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] : f64
-    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] : f64
-    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] : f64
+    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
     ! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
     ! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
     ! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
diff --git a/flang/test/Lower/Intrinsics/nearest.f90 b/flang/test/Lower/Intrinsics/nearest.f90
index 02ded4919dd7e..a023fa8cd804e 100644
--- a/flang/test/Lower/Intrinsics/nearest.f90
+++ b/flang/test/Lower/Intrinsics/nearest.f90
@@ -7,7 +7,7 @@ subroutine nearest_test1(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f32>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest4(%[[x]], %[[pos]]) {{.*}}: (f32, i1) -> f32
@@ -21,7 +21,7 @@ subroutine nearest_test2(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f64>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f64>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f64
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f64
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest8(%[[x]], %[[pos]]) {{.*}}: (f64, i1) -> f64
@@ -35,7 +35,7 @@ subroutine nearest_test3(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f80>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f80>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f80
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f80
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f80
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest10(%[[x]], %[[pos]]) {{.*}}: (f80, i1) -> f80
@@ -49,7 +49,7 @@ subroutine nearest_test4(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f128>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f128>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f128
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f128
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f128
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
@@ -64,7 +64,7 @@ subroutine nearest_test5(x, s)
     real :: s
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 98fef6a2d2f29..9db63c10c1f85 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reductio...
[truncated]

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 4, 2023

@llvm/pr-subscribers-flang-fir-hlfir

Author: Tom Eccles (tblah)

Changes

llvm.fcmp does support fast math attributes therefore so should arith.cmpf.

The heavy churn in flang tests are because flang sets fastmath&lt;contract&gt; by default on all operations that support the fast math interface. Downstream users of MLIR should not be so effected.

This was requested in #74263


Patch is 49.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74315.diff

27 Files Affected:

  • (modified) flang/include/flang/Optimizer/Dialect/FIROps.td (+6-2)
  • (modified) flang/test/Fir/convert-to-llvm.fir (+7-7)
  • (modified) flang/test/Fir/fir-ops.fir (+16-16)
  • (modified) flang/test/HLFIR/call_with_poly_dummy.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/binary-ops.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/bessel_jn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/bessel_yn.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/dim.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/min.f90 (+2-2)
  • (modified) flang/test/Lower/Intrinsics/modulo.f90 (+3-3)
  • (modified) flang/test/Lower/Intrinsics/nearest.f90 (+5-5)
  • (modified) flang/test/Lower/OpenACC/acc-reduction.f90 (+7-7)
  • (modified) flang/test/Lower/arithmetic-goto.f90 (+2-2)
  • (modified) flang/test/Lower/array-elemental-calls-2.f90 (+1-1)
  • (modified) flang/test/Lower/array-expression-slice-1.f90 (+9-9)
  • (modified) flang/test/Lower/array-user-def-assignments.f90 (+3-3)
  • (modified) flang/test/Lower/forall/forall-construct.f90 (+1-1)
  • (modified) flang/test/Lower/forall/forall-where.f90 (+1-1)
  • (modified) flang/test/Lower/host-associated.f90 (+1-1)
  • (modified) flang/test/Lower/real-operations-2.f90 (+6-6)
  • (modified) flang/test/Lower/where.f90 (+3-3)
  • (modified) flang/test/Transforms/simplifyintrinsics.fir (+2-2)
  • (modified) mlir/include/mlir/Dialect/Arith/IR/ArithOps.td (+16-2)
  • (modified) mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp (+5-2)
  • (modified) mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mlir (+3)
  • (modified) mlir/test/Dialect/Arith/ops.mlir (+2)
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 14a3879906186..fcecc605dfa5c 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2553,14 +2553,18 @@ def fir_DivcOp : ComplexArithmeticOp<"divc",
 // Pow is a builtin call and not a primitive
 
 def fir_CmpcOp : fir_Op<"cmpc",
-    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape]> {
+    [NoMemoryEffect, SameTypeOperands, SameOperandsAndResultShape,
+    DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
   let summary = "complex floating-point comparison operator";
 
   let description = [{
     A complex comparison to handle complex types found in FIR.
   }];
 
-  let arguments = (ins fir_ComplexType:$lhs, fir_ComplexType:$rhs);
+  let arguments = (ins
+      fir_ComplexType:$lhs,
+      fir_ComplexType:$rhs,
+      DefaultValuedAttr<Arith_FastMathAttr, "::mlir::arith::FastMathFlags::none">:$fastmath);
 
   let results = (outs AnyLogicalLike);
 
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index c9a44914b9870..e2cce1814d73b 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -650,13 +650,13 @@ func.func @compare_complex_eq(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "oeq" [[RA]], [[RB]] {fastmath = {{.*}}} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "oeq" [[IA]], [[IB]] {fastmath = {{.*}}} : f64
 // CHECK: [[RES:%.*]] = llvm.and [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "une", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "une", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -667,13 +667,13 @@ func.func @compare_complex_ne(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1
 // CHECK-DAG: [[IA:%.*]] = llvm.extractvalue [[A]][1] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[IB:%.*]] = llvm.extractvalue [[B]][1] : !llvm.struct<(f64, f64)>
-// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] : f64
-// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] : f64
+// CHECK-DAG: [[RESR:%.*]] = llvm.fcmp "une" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>} : f64
+// CHECK-DAG: [[RESI:%.*]] = llvm.fcmp "une" [[IA]], [[IB]] {fastmath = #llvm.fastmath<fast>} : f64
 // CHECK: [[RES:%.*]] = llvm.or [[RESR]], [[RESI]] : i1
 // CHECK: return [[RES]] : i1
 
 func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) -> i1 {
-  %r = fir.cmpc "ogt", %a, %b : !fir.complex<8>
+  %r = fir.cmpc "ogt", %a, %b {fastmath = #arith.fastmath<fast>} : !fir.complex<8>
   return %r : i1
 }
 
@@ -682,7 +682,7 @@ func.func @compare_complex_other(%a : !fir.complex<8>, %b : !fir.complex<8>) ->
 // CHECK-SAME: [[B:%.*]]: !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RA:%.*]] = llvm.extractvalue [[A]][0] : !llvm.struct<(f64, f64)>
 // CHECK-DAG: [[RB:%.*]] = llvm.extractvalue [[B]][0] : !llvm.struct<(f64, f64)>
-// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] : f64
+// CHECK: [[RESR:%.*]] = llvm.fcmp "ogt" [[RA]], [[RB]] {fastmath = #llvm.fastmath<fast>}} : f64
 // CHECK: return [[RESR]] : i1
 
 // -----
diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index dd0fbb3be36c4..3c4095b9fdb14 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -464,37 +464,37 @@ fir.type_info @test_type_info noinit nodestroy nofinal extends !fir.type<parent{
 // CHECK-SAME: [[VAL_151:%.*]]: !fir.complex<16>, [[VAL_152:%.*]]: !fir.complex<16>) {
 func.func @compare_complex(%a : !fir.complex<16>, %b : !fir.complex<16>) {
 
-// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_153:%.*]] = fir.cmpc "false", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_154:%.*]] = fir.cmpc "oeq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_155:%.*]] = fir.cmpc "ogt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_156:%.*]] = fir.cmpc "oge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %d0 = fir.cmpc "false", %a, %b : !fir.complex<16>
   %d1 = fir.cmpc "oeq", %a, %b : !fir.complex<16>
   %d2 = fir.cmpc "ogt", %a, %b : !fir.complex<16>
   %d3 = fir.cmpc "oge", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_157:%.*]] = fir.cmpc "olt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_158:%.*]] = fir.cmpc "ole", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_159:%.*]] = fir.cmpc "one", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_160:%.*]] = fir.cmpc "ord", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %a0 = fir.cmpc "olt", %a, %b : !fir.complex<16>
   %a1 = fir.cmpc "ole", %a, %b : !fir.complex<16>
   %a2 = fir.cmpc "one", %a, %b : !fir.complex<16>
   %a3 = fir.cmpc "ord", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_161:%.*]] = fir.cmpc "ueq", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_162:%.*]] = fir.cmpc "ugt", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_163:%.*]] = fir.cmpc "uge", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_164:%.*]] = fir.cmpc "ult", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %b0 = fir.cmpc "ueq", %a, %b : !fir.complex<16>
   %b1 = fir.cmpc "ugt", %a, %b : !fir.complex<16>
   %b2 = fir.cmpc "uge", %a, %b : !fir.complex<16>
   %b3 = fir.cmpc "ult", %a, %b : !fir.complex<16>
 
-// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
-// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] : !fir.complex<16>
+// CHECK: [[VAL_165:%.*]] = fir.cmpc "ule", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_166:%.*]] = fir.cmpc "une", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_167:%.*]] = fir.cmpc "uno", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
+// CHECK: [[VAL_168:%.*]] = fir.cmpc "true", [[VAL_151]], [[VAL_152]] {fastmath = {{.*}}} : !fir.complex<16>
   %c0 = fir.cmpc "ule", %a, %b : !fir.complex<16>
   %c1 = fir.cmpc "une", %a, %b : !fir.complex<16>
   %c2 = fir.cmpc "uno", %a, %b : !fir.complex<16>
diff --git a/flang/test/HLFIR/call_with_poly_dummy.f90 b/flang/test/HLFIR/call_with_poly_dummy.f90
index c4b98fbe5f557..af6876e26603e 100644
--- a/flang/test/HLFIR/call_with_poly_dummy.f90
+++ b/flang/test/HLFIR/call_with_poly_dummy.f90
@@ -25,7 +25,7 @@ end subroutine test1
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
 ! CHECK:           %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] : f32
+! CHECK:           %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] {{.*}} : f32
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
 ! CHECK:           %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {adapt.valuebyref} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
 ! CHECK:           %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0 : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
index 6b89577cc5458..e0af9258cda32 100644
--- a/flang/test/Lower/HLFIR/binary-ops.f90
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -246,7 +246,7 @@ subroutine cmp_real(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] : f32
+! CHECK:  %[[VAL_8:.*]] = arith.cmpf oeq, %[[VAL_6]], %[[VAL_7]] {{.*}} : f32
 
 subroutine cmp_real_2(l, x, y)
   logical :: l
@@ -273,7 +273,7 @@ subroutine cmp_cmplx(l, x, y)
 ! CHECK:  %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}y"
 ! CHECK:  %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
 ! CHECK:  %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
-! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+! CHECK:  %[[VAL_8:.*]] = fir.cmpc "oeq", %[[VAL_6]], %[[VAL_7]] {{.*}} : !fir.complex<4>
 
 subroutine cmp_char(l, x, y)
   logical :: l
diff --git a/flang/test/Lower/HLFIR/user-defined-assignment.f90 b/flang/test/Lower/HLFIR/user-defined-assignment.f90
index a41044a60fd89..6f887cb00de31 100644
--- a/flang/test/Lower/HLFIR/user-defined-assignment.f90
+++ b/flang/test/Lower/HLFIR/user-defined-assignment.f90
@@ -101,7 +101,7 @@ subroutine test_non_elemental_array(x)
 ! CHECK:      ^bb0(%[[VAL_7:.*]]: index):
 ! CHECK:        %[[VAL_8:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_7]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
 ! CHECK:        %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref<f32>
-! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] : f32
+! CHECK:        %[[VAL_10:.*]] = arith.cmpf olt, %[[VAL_9]], %[[VAL_2]] {{.*}} : f32
 ! CHECK:        %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i1) -> !fir.logical<4>
 ! CHECK:        hlfir.yield_element %[[VAL_11]] : !fir.logical<4>
 ! CHECK:      }
diff --git a/flang/test/Lower/Intrinsics/bessel_jn.f90 b/flang/test/Lower/Intrinsics/bessel_jn.f90
index 3fdef7446100d..428733d547d7b 100644
--- a/flang/test/Lower/Intrinsics/bessel_jn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_jn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/bessel_yn.f90 b/flang/test/Lower/Intrinsics/bessel_yn.f90
index 9f4fbfbb89d31..ac77e4db5614d 100644
--- a/flang/test/Lower/Intrinsics/bessel_yn.f90
+++ b/flang/test/Lower/Intrinsics/bessel_yn.f90
@@ -42,7 +42,7 @@ subroutine test_transformational_real4(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f32>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f32
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f32
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
@@ -85,7 +85,7 @@ subroutine test_transformational_real8(x, n1, n2, r)
   ! ALL-DAG: %[[x:.*]] = fir.load %[[argx]] : !fir.ref<f64>
   ! ALL-DAG: %[[n1:.*]] = fir.load %[[argn1]] : !fir.ref<i32>
   ! ALL-DAG: %[[n2:.*]] = fir.load %[[argn2]] : !fir.ref<i32>
-  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] : f64
+  ! ALL-DAG: %[[xeq0:.*]] = arith.cmpf ueq, %[[x]], %[[zero]] {{.*}} : f64
   ! ALL-DAG: %[[n1ltn2:.*]] = arith.cmpi slt, %[[n1]], %[[n2]] : i32
   ! ALL-DAG: %[[n1eqn2:.*]] = arith.cmpi eq, %[[n1]], %[[n2]] : i32
   ! ALL: fir.if %[[xeq0]] {
diff --git a/flang/test/Lower/Intrinsics/dim.f90 b/flang/test/Lower/Intrinsics/dim.f90
index 6b6d2179fad9f..fb1a496570ca1 100644
--- a/flang/test/Lower/Intrinsics/dim.f90
+++ b/flang/test/Lower/Intrinsics/dim.f90
@@ -8,7 +8,7 @@ subroutine dim_testr(x, y, z)
 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<f32>
 ! CHECK: %[[VAL_5:.*]] = arith.constant 0.000000e+00 : f32
 ! CHECK: %[[VAL_6:.*]] = arith.subf %[[VAL_3]], %[[VAL_4]] {{.*}}: f32
-! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] {{.*}} : f32
 ! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : f32
 ! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<f32>
 ! CHECK: return
diff --git a/flang/test/Lower/Intrinsics/min.f90 b/flang/test/Lower/Intrinsics/min.f90
index 40e6d96db6e53..c9744cf33d827 100644
--- a/flang/test/Lower/Intrinsics/min.f90
+++ b/flang/test/Lower/Intrinsics/min.f90
@@ -18,11 +18,11 @@ real function test(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_9:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
 ! CHECK:           %[[VAL_10:.*]] = fir.is_present %[[VAL_5]]#0 : (!fir.ref<f32>) -> i1
-! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] : f32
+! CHECK:           %[[VAL_11:.*]] = arith.cmpf olt, %[[VAL_8]], %[[VAL_9]] {{.*}} : f32
 ! CHECK:           %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_8]], %[[VAL_9]] : f32
 ! CHECK:           %[[VAL_13:.*]] = fir.if %[[VAL_10]] -> (f32) {
 ! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
-! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] : f32
+! CHECK:             %[[VAL_15:.*]] = arith.cmpf olt, %[[VAL_12]], %[[VAL_14]] {{.*}} : f32
 ! CHECK:             %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_12]], %[[VAL_14]] : f32
 ! CHECK:             fir.result %[[VAL_16]] : f32
 ! CHECK:           } else {
diff --git a/flang/test/Lower/Intrinsics/modulo.f90 b/flang/test/Lower/Intrinsics/modulo.f90
index 4c8c1ff4da3b0..64a6607a09ccd 100644
--- a/flang/test/Lower/Intrinsics/modulo.f90
+++ b/flang/test/Lower/Intrinsics/modulo.f90
@@ -8,9 +8,9 @@ subroutine modulo_testr(r, a, p)
     ! CHECK-DAG: %[[p:.*]] = fir.load %[[arg2]] : !fir.ref<f64>
     ! CHECK-DAG: %[[rem:.*]] = arith.remf %[[a]], %[[p]] {{.*}}: f64
     ! CHECK-DAG: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] : f64
-    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] : f64
-    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] : f64
+    ! CHECK-DAG: %[[remNotZero:.*]] = arith.cmpf une, %[[rem]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[aNeg:.*]] = arith.cmpf olt, %[[a]], %[[zero]] {{.*}} : f64
+    ! CHECK-DAG: %[[pNeg:.*]] = arith.cmpf olt, %[[p]], %[[zero]] {{.*}} : f64
     ! CHECK-DAG: %[[signDifferent:.*]] = arith.xori %[[aNeg]], %[[pNeg]] : i1
     ! CHECK-DAG: %[[mustAddP:.*]] = arith.andi %[[remNotZero]], %[[signDifferent]] : i1
     ! CHECK-DAG: %[[remPlusP:.*]] = arith.addf %[[rem]], %[[p]] {{.*}}: f64
diff --git a/flang/test/Lower/Intrinsics/nearest.f90 b/flang/test/Lower/Intrinsics/nearest.f90
index 02ded4919dd7e..a023fa8cd804e 100644
--- a/flang/test/Lower/Intrinsics/nearest.f90
+++ b/flang/test/Lower/Intrinsics/nearest.f90
@@ -7,7 +7,7 @@ subroutine nearest_test1(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f32>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest4(%[[x]], %[[pos]]) {{.*}}: (f32, i1) -> f32
@@ -21,7 +21,7 @@ subroutine nearest_test2(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f64>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f64>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f64
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f64
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f64
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest8(%[[x]], %[[pos]]) {{.*}}: (f64, i1) -> f64
@@ -35,7 +35,7 @@ subroutine nearest_test3(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f80>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f80>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f80
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f80
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f80
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest10(%[[x]], %[[pos]]) {{.*}}: (f80, i1) -> f80
@@ -49,7 +49,7 @@ subroutine nearest_test4(x, s)
   ! CHECK: %[[x:.*]] = fir.load %arg0 : !fir.ref<f128>
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f128>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f128
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f128
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f128
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
@@ -64,7 +64,7 @@ subroutine nearest_test5(x, s)
     real :: s
   ! CHECK: %[[s:.*]] = fir.load %arg1 : !fir.ref<f32>
   ! CHECK: %[[zero:.*]] = arith.constant 0.000000e+00 : f32
-  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] : f32
+  ! CHECK: %[[cmp:.*]] = arith.cmpf ogt, %[[s]], %[[zero]] {{.*}} : f32
   ! CHECK: %[[pos:.*]] = arith.select %[[cmp]], %true, %false : i1
     res = nearest(x, s)
   ! CHECK: %[[tmp:.*]] = fir.call @_FortranANearest16(%[[x]], %[[pos]]) {{.*}}: (f128, i1) -> f128
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 98fef6a2d2f29..9db63c10c1f85 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reductio...
[truncated]

@kiranchandramohan
Copy link
Contributor

@tblah There was a discussion about this in the following thread.
https://discourse.llvm.org/t/no-fastmath-attribute-on-arith-cmpfop/67206

@tblah tblah requested a review from arsenm December 4, 2023 12:47
Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch looks good to me, but given the discourse thread you should wait for a green light from the MLIR community.

@tblah tblah merged commit fcd06d7 into llvm:main Dec 6, 2023
5 checks passed
tblah added a commit that referenced this pull request Dec 6, 2023
These tests were broken after
#74315

Fixing them to ignore the fastmath attribute on fcmp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:codegen flang:fir-hlfir flang Flang issues not falling into any other category mlir:arith mlir openacc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants