Reapply "Add support for #pragma float_control" with buildbot fixes
Add support for #pragma float_control

Reviewers: rjmccall, erichkeane, sepavloff

Differential Revision: https://reviews.llvm.org/D72841

This reverts commit fce82c0ed310174fe48e2402ac731b6340098389.
diff --git a/clang/test/CodeGen/builtins-nvptx.c b/clang/test/CodeGen/builtins-nvptx.c
index 31c3ecd..1f7a8c6 100644
--- a/clang/test/CodeGen/builtins-nvptx.c
+++ b/clang/test/CodeGen/builtins-nvptx.c
@@ -1,11 +1,11 @@
 // REQUIRES: nvptx-registered-target
-// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_60 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu sm_60 \
 // RUN:            -fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP32 %s
-// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_60 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_60 \
 // RUN:            -fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s
-// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_61 \
+// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_61 \
 // RUN:            -fcuda-is-device -S -emit-llvm -o - -x cuda %s \
 // RUN:   | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s
 // RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_53 \
diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c
index b22cfe6..fe303eb 100644
--- a/clang/test/CodeGen/constrained-math-builtins.c
+++ b/clang/test/CodeGen/constrained-math-builtins.c
@@ -154,9 +154,9 @@
   (double)f * f - f;
   (long double)-f * f + f;
 
-// CHECK: call float @llvm.experimental.constrained.fmuladd.f32
-// CHECK: fneg
-// CHECK: call double @llvm.experimental.constrained.fmuladd.f64
-// CHECK: fneg
-// CHECK: call x86_fp80 @llvm.experimental.constrained.fmuladd.f80
+  // CHECK: call contract float @llvm.experimental.constrained.fmuladd.f32
+  // CHECK: fneg
+  // CHECK: call contract double @llvm.experimental.constrained.fmuladd.f64
+  // CHECK: fneg
+  // CHECK: call contract x86_fp80 @llvm.experimental.constrained.fmuladd.f80
 };
diff --git a/clang/test/CodeGen/fast-math.c b/clang/test/CodeGen/fast-math.c
index 6f98b84..6ebd65a 100644
--- a/clang/test/CodeGen/fast-math.c
+++ b/clang/test/CodeGen/fast-math.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s
 float f0, f1, f2;
 
 void foo(void) {
diff --git a/clang/test/CodeGen/fp-contract-on-pragma.cpp b/clang/test/CodeGen/fp-contract-on-pragma.cpp
index 812a717..5f74636 100644
--- a/clang/test/CodeGen/fp-contract-on-pragma.cpp
+++ b/clang/test/CodeGen/fp-contract-on-pragma.cpp
@@ -3,7 +3,7 @@
 // Is FP_CONTRACT honored in a simple case?
 float fp_contract_1(float a, float b, float c) {
 // CHECK: _Z13fp_contract_1fff
-// CHECK: tail call float @llvm.fmuladd
+// CHECK: tail call contract float @llvm.fmuladd
 #pragma clang fp contract(on)
   return a * b + c;
 }
@@ -31,7 +31,7 @@
 
 float fp_contract_3(float a, float b, float c) {
   // CHECK: _Z13fp_contract_3fff
-  // CHECK: tail call float @llvm.fmuladd
+  // CHECK: tail call contract float @llvm.fmuladd
   return template_muladd<float>(a, b, c);
 }
 
@@ -45,13 +45,13 @@
 
 template class fp_contract_4<int>;
 // CHECK: _ZN13fp_contract_4IiE6methodEfff
-// CHECK: tail call float @llvm.fmuladd
+// CHECK: tail call contract float @llvm.fmuladd
 
 // Check file-scoped FP_CONTRACT
 #pragma clang fp contract(on)
 float fp_contract_5(float a, float b, float c) {
   // CHECK: _Z13fp_contract_5fff
-  // CHECK: tail call float @llvm.fmuladd
+  // CHECK: tail call contract float @llvm.fmuladd
   return a * b + c;
 }
 
@@ -69,8 +69,8 @@
 
 float fp_contract_7(float a, float b, float c) {
 // CHECK: _Z13fp_contract_7fff
-// CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
-// CHECK-NEXT: fsub float %[[M]], %c
+// CHECK:  %[[M:.+]] = fmul contract float %b, 2.000000e+00
+// CHECK-NEXT: fsub contract float %[[M]], %c
 #pragma clang fp contract(on)
   return (a = 2 * b) - c;
 }
diff --git a/clang/test/CodeGen/fp-contract-pragma.cpp b/clang/test/CodeGen/fp-contract-pragma.cpp
index 805cc5d..3a861ab 100644
--- a/clang/test/CodeGen/fp-contract-pragma.cpp
+++ b/clang/test/CodeGen/fp-contract-pragma.cpp
@@ -2,9 +2,9 @@
 
 // Is FP_CONTRACT honored in a simple case?
 float fp_contract_1(float a, float b, float c) {
-// CHECK: _Z13fp_contract_1fff
-// CHECK: tail call float @llvm.fmuladd
-  #pragma STDC FP_CONTRACT ON
+  // CHECK: _Z13fp_contract_1fff
+  // CHECK: tail call contract float @llvm.fmuladd
+#pragma STDC FP_CONTRACT ON
   return a * b + c;
 }
 
@@ -30,8 +30,8 @@
 }
 
 float fp_contract_3(float a, float b, float c) {
-// CHECK: _Z13fp_contract_3fff
-// CHECK: tail call float @llvm.fmuladd
+  // CHECK: _Z13fp_contract_3fff
+  // CHECK: tail call contract float @llvm.fmuladd
   return template_muladd<float>(a, b, c);
 }
 
@@ -44,13 +44,13 @@
 
 template class fp_contract_4<int>;
 // CHECK: _ZN13fp_contract_4IiE6methodEfff
-// CHECK: tail call float @llvm.fmuladd
+// CHECK: tail call contract float @llvm.fmuladd
 
 // Check file-scoped FP_CONTRACT
 #pragma STDC FP_CONTRACT ON
 float fp_contract_5(float a, float b, float c) {
-// CHECK: _Z13fp_contract_5fff
-// CHECK: tail call float @llvm.fmuladd
+  // CHECK: _Z13fp_contract_5fff
+  // CHECK: tail call contract float @llvm.fmuladd
   return a * b + c;
 }
 
@@ -67,25 +67,25 @@
 // https://llvm.org/bugs/show_bug.cgi?id=25719
 
 float fp_contract_7(float a, float b, float c) {
-// CHECK: _Z13fp_contract_7fff
-// CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
-// CHECK-NEXT: fsub float %[[M]], %c
-  #pragma STDC FP_CONTRACT ON
+  // CHECK: _Z13fp_contract_7fff
+  // CHECK:  %[[M:.+]] = fmul contract float %b, 2.000000e+00
+  // CHECK-NEXT: fsub contract float %[[M]], %c
+#pragma STDC FP_CONTRACT ON
   return (a = 2 * b) - c;
 }
 
 float fp_contract_8(float a, float b, float c) {
-// CHECK: _Z13fp_contract_8fff
-// CHECK: fneg float %c
-// CHECK: tail call float @llvm.fmuladd
-  #pragma STDC FP_CONTRACT ON
+  // CHECK: _Z13fp_contract_8fff
+  // CHECK: fneg contract float %c
+  // CHECK: tail call contract float @llvm.fmuladd
+#pragma STDC FP_CONTRACT ON
   return a * b - c;
 }
 
 float fp_contract_9(float a, float b, float c) {
-// CHECK: _Z13fp_contract_9fff
-// CHECK: fneg float %a
-// CHECK: tail call float @llvm.fmuladd
-  #pragma STDC FP_CONTRACT ON
+  // CHECK: _Z13fp_contract_9fff
+  // CHECK: fneg contract float %a
+  // CHECK: tail call contract float @llvm.fmuladd
+#pragma STDC FP_CONTRACT ON
   return c - a * b;
 }
diff --git a/clang/test/CodeGen/fp-floatcontrol-class.cpp b/clang/test/CodeGen/fp-floatcontrol-class.cpp
new file mode 100644
index 0000000..ce4e0eb
--- /dev/null
+++ b/clang/test/CodeGen/fp-floatcontrol-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -ffp-contract=on -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -ffp-contract=on -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -ffp-contract=on -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// Verify that float_control does not pertain to initializer expressions
+
+float y();
+float z();
+#pragma float_control(except, on)
+class ON {
+  float w = 2 + y() * z();
+  // CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
+  //CHECK: call contract float {{.*}}llvm.fmuladd
+};
+ON on;
+#pragma float_control(except, off)
+class OFF {
+  float w = 2 + y() * z();
+  // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
+  //CHECK: call contract float {{.*}}llvm.fmuladd
+};
+OFF off;
diff --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
new file mode 100644
index 0000000..caaab3c
--- /dev/null
+++ b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+float fff(float x, float y) {
+// CHECK-LABEL: define float @_Z3fffff{{.*}}
+// CHECK: entry
+#pragma float_control(except, on)
+  float z;
+  z = z * z;
+  //CHECK: llvm.experimental.constrained.fmul{{.*}}
+  {
+    z = x * y;
+    //CHECK: llvm.experimental.constrained.fmul{{.*}}
+  }
+  {
+// This pragma has no effect since if there are any fp intrin in the
+// function then all the operations need to be fp intrin
+#pragma float_control(except, off)
+    z = z + x * y;
+    //CHECK: llvm.experimental.constrained.fmul{{.*}}
+  }
+  z = z * z;
+  //CHECK: llvm.experimental.constrained.fmul{{.*}}
+  return z;
+}
+float check_precise(float x, float y) {
+  // CHECK-LABEL: define float @_Z13check_preciseff{{.*}}
+  float z;
+  {
+#pragma float_control(precise, on)
+    z = x * y + z;
+    //CHECK: llvm.fmuladd{{.*}}
+  }
+  {
+#pragma float_control(precise, off)
+    z = x * y + z;
+    //CHECK: fmul fast float
+    //CHECK: fadd fast float
+  }
+  return z;
+}
+float fma_test1(float a, float b, float c) {
+// CHECK-LABEL define float @_Z9fma_test1fff{{.*}}
+#pragma float_control(precise, on)
+  float x = a * b + c;
+  //CHECK: fmuladd
+  return x;
+}
diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp
new file mode 100644
index 0000000..18ec0d4
--- /dev/null
+++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp
@@ -0,0 +1,253 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s
+
+#define FUN(n) \
+  (float z) { return n * z + n; }
+
+float fun_default FUN(1)
+//CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+// Note that backend wants constrained intrinsics used
+// throughout the function if they are needed anywhere in the function.
+// In that case, operations are built with constrained intrinsics operator
+// but using default settings for exception behavior and rounding mode.
+//CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(push)
+#ifndef FAST
+// Rule: precise must be enabled
+#pragma float_control(except, on)
+#endif
+    float exc_on FUN(2)
+//CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: nnan ninf contract float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
+#endif
+#if FAST
+//Not possible to enable float_control(except) in FAST mode.
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(pop)
+        float exc_pop FUN(5)
+//CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(except, off)
+            float exc_off FUN(5)
+//CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: call contract float @llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(precise, on, push)
+                float precise_on FUN(3)
+//CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+// If precise is pushed then all fast-math should be off!
+//CHECK-NOHONOR: call contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+
+#pragma float_control(pop)
+                    float precise_pop FUN(3)
+//CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+#pragma float_control(precise, off)
+                        float precise_off FUN(4)
+//CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}}
+#if DEFAULT
+// Note: precise_off enables fp_contract=fast and the instructions
+// generated do not include the contract flag, although it was enabled
+// in IRBuilder.
+//CHECK-DDEFAULT: fmul fast float
+//CHECK-DDEFAULT: fadd fast float
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: fmul fast float
+//CHECK-DEBSTRICT: fadd fast float
+#endif
+#if NOHONOR
+// fast math should be enabled, and contract should be fast
+//CHECK-NOHONOR: fmul fast float
+//CHECK-NOHONOR: fadd fast float
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(precise, on)
+                            float precise_on2 FUN(3)
+//CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+// fast math should be off, and contract should be on
+//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+
+#pragma float_control(push)
+                                float precise_push FUN(3)
+//CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+
+#pragma float_control(precise, off)
+                                    float precise_off2 FUN(4)
+//CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: fmul fast float
+//CHECK-DDEFAULT: fadd fast float
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: fmul fast float
+//CHECK-DEBSTRICT: fadd fast float
+#endif
+#if NOHONOR
+// fast math settings since precise is off
+//CHECK-NOHONOR: fmul fast float
+//CHECK-NOHONOR: fadd fast float
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+
+#pragma float_control(pop)
+                                        float precise_pop2 FUN(3)
+//CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: llvm.fmuladd{{.*}}
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}}
+#endif
+
+#ifndef FAST
+// Rule: precise must be enabled
+#pragma float_control(except, on)
+#endif
+                                            float y();
+class ON {
+  // Settings for top level class initializer revert to command line
+  // source pragma's do not pertain.
+  float z = 2 + y() * 7;
+//CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd
+#endif
+#if EBSTRICT
+//Currently, same as default [command line options not considered]
+//CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+};
+ON on;
+#pragma float_control(except, off)
+class OFF {
+  float w = 2 + y() * 7;
+//CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
+#if DEFAULT
+//CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd
+#endif
+#if EBSTRICT
+//CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd
+#endif
+#if NOHONOR
+//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}}
+#endif
+#if FAST
+//CHECK-FAST: fmul fast float
+//CHECK-FAST: fadd fast float
+#endif
+};
+OFF off;
diff --git a/clang/test/CodeGen/fpconstrained.c b/clang/test/CodeGen/fpconstrained.c
index 0a890e2..902d6b5 100644
--- a/clang/test/CodeGen/fpconstrained.c
+++ b/clang/test/CodeGen/fpconstrained.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -ftrapping-math -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT

 // RUN: %clang_cc1 -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE

 // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

-// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

+// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT

 // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

 // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT

 // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP

@@ -17,6 +17,7 @@
   // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore")

   // PRECISE: fadd contract float %{{.*}}, %{{.*}}

   // FAST: fadd fast

+  // FASTNOCONTRACT: fadd reassoc nnan ninf nsz arcp afn float

   f0 = f1 + f2;

 

   // CHECK: ret

diff --git a/clang/test/CodeGen/fpconstrained.cpp b/clang/test/CodeGen/fpconstrained.cpp
index 7aa34c9..e914abc 100644
--- a/clang/test/CodeGen/fpconstrained.cpp
+++ b/clang/test/CodeGen/fpconstrained.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -x c++ -ftrapping-math -fexceptions -fcxx-exceptions -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT

 // RUN: %clang_cc1 -x c++ -ffp-contract=fast -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE

 // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

-// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

+// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT

 // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST

 // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT

 // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP

@@ -20,16 +20,17 @@
   // CHECK-LABEL: define {{.*}}void @_ZN4aaaaIiED2Ev{{.*}}

 

   } catch (...) {

-  // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap")

-  // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")

-  // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")

-  // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")

-  // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore")

-  // PRECISE: fadd contract float %{{.*}}, %{{.*}}

-  // FAST: fadd fast

-  f0 = f1 + f2;

+    // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap")

+    // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")

+    // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")

+    // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")

+    // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore")

+    // PRECISE: fadd contract float %{{.*}}, %{{.*}}

+    // FAST: fadd fast

+    // FASTNOCONTRACT: fadd reassoc nnan ninf nsz arcp afn float

+    f0 = f1 + f2;

 

-  // CHECK: ret void

+    // CHECK: ret void

   }

   }