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
}
}