Abe updated this revision to Diff 72103.
Abe added a comment.

Combined "fp-contract-pragma___on-by-default___-O0___aarch64-backend.c" and 
"fp-contract-pragma___on-by-default___-O1...3___aarch64-backend.c" into a 
single file ["fp-contract-pragma___on-by-default.c"].


https://reviews.llvm.org/D24481

Files:
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/aarch64-neon-fma.c
  clang/test/CodeGen/aarch64-scalar-fma.c
  clang/test/CodeGen/fp-contract-pragma.cpp
  clang/test/CodeGen/fp-contract-pragma___on-by-default.c
  clang/test/Driver/clang_f_opts.c

Index: clang/test/Driver/clang_f_opts.c
===================================================================
--- clang/test/Driver/clang_f_opts.c
+++ clang/test/Driver/clang_f_opts.c
@@ -34,10 +34,13 @@
 // DEPRECATED-OFF-CHECK-NOT: -fdeprecated-macro
 
 // RUN: %clang -### -S -ffp-contract=fast %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-FAST-CHECK %s
-// RUN: %clang -### -S -ffast-math %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-FAST-CHECK %s
-// RUN: %clang -### -S -ffp-contract=off %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-OFF-CHECK %s
+// RUN: %clang -### -S -ffast-math        %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-FAST-CHECK %s
+// RUN: %clang -### -S -ffp-contract=off  %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-OFF-CHECK  %s
+// RUN: %clang -### -S -ffp-contract=on   %s 2>&1 | FileCheck -check-prefix=FP-CONTRACT-ON-CHECK   %s
+
 // FP-CONTRACT-FAST-CHECK: -ffp-contract=fast
-// FP-CONTRACT-OFF-CHECK: -ffp-contract=off
+// FP-CONTRACT-OFF-CHECK:  -ffp-contract=off
+// FP-CONTRACT-ON-CHECK:   -ffp-contract=on
 
 // RUN: %clang -### -S -funroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-UNROLL-LOOPS %s
 // RUN: %clang -### -S -fno-unroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-NO-UNROLL-LOOPS %s
Index: clang/test/CodeGen/fp-contract-pragma___on-by-default.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/fp-contract-pragma___on-by-default.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple aarch64 -O0 -S -o - %s | FileCheck %s --check-prefix   ALL_BUILDS
+// RUN: %clang_cc1 -triple aarch64 -O1 -S -o - %s | FileCheck %s --check-prefixes ALL_BUILDS,NON_O0
+// RUN: %clang_cc1 -triple aarch64 -O2 -S -o - %s | FileCheck %s --check-prefixes ALL_BUILDS,NON_O0
+// RUN: %clang_cc1 -triple aarch64 -O3 -S -o - %s | FileCheck %s --check-prefixes ALL_BUILDS,NON_O0
+
+// REQUIRES: aarch64-registered-target
+
+// ALL_BUILDS-LABEL: fmadd_double:
+// ALL_BUILDS: fmadd d0, d{{[0-7]}}, d{{[0-7]}}, d{{[0-7]}}
+// NON_O0-NEXT: ret
+double fmadd_double(double a, double b, double c) {
+  return a*b+c;
+}
+
+// ALL_BUILDS: fmadd_single:
+// ALL_BUILDS: fmadd s0, s{{[0-7]}}, s{{[0-7]}}, s{{[0-7]}}
+// NON_O0-NEXT: ret
+float  fmadd_single(float  a, float  b, float  c) {
+  return a*b+c;
+}
+
Index: clang/test/CodeGen/fp-contract-pragma.cpp
===================================================================
--- clang/test/CodeGen/fp-contract-pragma.cpp
+++ clang/test/CodeGen/fp-contract-pragma.cpp
@@ -1,27 +1,25 @@
 // RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
-// Is FP_CONTRACT honored in a simple case?
-float fp_contract_1(float a, float b, float c) {
-// CHECK: _Z13fp_contract_1fff
+// Is FP_CONTRACT on by default, at least at -O3?
+float fp_contract_8(float a, float b, float c) {
+// CHECK: _Z13fp_contract_8fff
 // CHECK: tail call float @llvm.fmuladd
-  #pragma STDC FP_CONTRACT ON
   return a * b + c;
 }
 
 // Is FP_CONTRACT state cleared on exiting compound statements?
 float fp_contract_2(float a, float b, float c) {
 // CHECK: _Z13fp_contract_2fff
 // CHECK: %[[M:.+]] = fmul float %a, %b
 // CHECK-NEXT: fadd float %[[M]], %c
+  #pragma STDC FP_CONTRACT OFF
   {
     #pragma STDC FP_CONTRACT ON
   }
   return a * b + c;  
 }
 
 // Does FP_CONTRACT survive template instantiation?
-class Foo {};
-Foo operator+(Foo, Foo);
 
 template <typename T>
 T template_muladd(T a, T b, T c) {
@@ -62,15 +60,23 @@
   return a * b + c;
 }
 
+// Does FP_CONTRACT inside a function override the same in the file scope?
+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
+  return a * b + c;
+}
+
+
 // If the multiply has multiple uses, don't produce fmuladd.
 // This used to assert (PR25719):
 // https://llvm.org/bugs/show_bug.cgi?id=25719
 
-float fp_contract_7(float a, float b, float c) {
+float fp_contract_7(float a, float b, float c, float& d_passed_by_ref) {
 // CHECK: _Z13fp_contract_7fff
 // CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
-// CHECK-NEXT: fsub float %[[M]], %c
   #pragma STDC FP_CONTRACT ON
-  return (a = 2 * b) - c;
+  return (d_passed_by_ref = 2 * b) - c;
 }
 
Index: clang/test/CodeGen/aarch64-scalar-fma.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aarch64-scalar-fma.c
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -triple=aarch64-unknown -Os -ffp-contract=fast -S -o - %s | FileCheck -check-prefix=CHECK-FAST -check-prefix=CHECK-ALL %s
+// RUN: %clang_cc1 -triple=aarch64-unknown -Os -ffp-contract=on -S -o - %s | FileCheck -check-prefix=CHECK-ON -check-prefix=CHECK-ALL %s
+// RUN: %clang_cc1 -triple=aarch64-unknown -Os -ffp-contract=off -S -o - %s | FileCheck -check-prefix=CHECK-OFF -check-prefix=CHECK-ALL %s
+// RUN: %clang_cc1 -triple=aarch64-unknown -Os -S -o - %s | FileCheck -check-prefix=CHECK-ON -check-prefix=CHECK-ALL %s
+// REQUIRES: aarch64-registered-target
+
+float test1(float x, float y, float z) {
+  return x*y + z;
+  // CHECK-ALL-LABEL: test1:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test2(double x, double y, double z) {
+  z -= x*y;
+  return z;
+  // CHECK-ALL-LABEL: test2:
+  // CHECK-FAST: fmsub
+  // CHECK-ON: fmsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+float test3(float x, float y, float z) {
+  float tmp = x*y;
+  return tmp + z;
+  // CHECK-ALL-LABEL: test3:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test4(double x, double y, double z) {
+  double tmp = x*y;
+  return tmp - z;
+  // CHECK-ALL-LABEL: test4:
+  // CHECK-FAST: fnmsub
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+#pragma STDC FP_CONTRACT ON
+
+float test5(float x, float y, float z) {
+  return x*y + z;
+  // CHECK-ALL-LABEL: test5:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test6(double x, double y, double z) {
+  z -= x*y;
+  return z;
+  // CHECK-ALL-LABEL: test6:
+  // CHECK-FAST: fmsub
+  // CHECK-ON: fmsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+float test7(float x, float y, float z) {
+  float tmp = x*y;
+  return tmp + z;
+  // CHECK-ALL-LABEL: test7:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test8(double x, double y, double z) {
+  double tmp = x*y;
+  return tmp - z;
+  // CHECK-ALL-LABEL: test8:
+  // CHECK-FAST: fnmsub
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+#pragma STDC FP_CONTRACT OFF
+
+float test9(float x, float y, float z) {
+  return x*y + z;
+  // CHECK-ALL-LABEL: test9:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test10(double x, double y, double z) {
+  z -= x*y;
+  return z;
+  // CHECK-ALL-LABEL: test10:
+  // CHECK-FAST: fmsub
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+float test11(float x, float y, float z) {
+  float tmp = x*y;
+  return tmp + z;
+  // CHECK-ALL-LABEL: test11:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test12(double x, double y, double z) {
+  double tmp = x*y;
+  return tmp - z;
+  // CHECK-ALL-LABEL: test12:
+  // CHECK-FAST: fnmsub
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+#pragma STDC FP_CONTRACT DEFAULT
+
+float test17(float x, float y, float z) {
+  return x*y + z;
+  // CHECK-ALL-LABEL: test17:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test18(double x, double y, double z) {
+  z -= x*y;
+  return z;
+  // CHECK-ALL-LABEL: test18:
+  // CHECK-FAST: fmsub
+  // CHECK-ON: fmsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
+
+float test19(float x, float y, float z) {
+  float tmp = x*y;
+  return tmp + z;
+  // CHECK-ALL-LABEL: test19:
+  // CHECK-FAST: fmadd
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fadd
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fadd
+}
+
+double test20(double x, double y, double z) {
+  double tmp = x*y;
+  return tmp - z;
+  // CHECK-ALL-LABEL: test20:
+  // CHECK-FAST: fnmsub
+  // CHECK-ON: fmul
+  // CHECK-ON-NEXT: fsub
+  // CHECK-OFF: fmul
+  // CHECK-OFF-NEXT: fsub
+}
Index: clang/test/CodeGen/aarch64-neon-fma.c
===================================================================
--- clang/test/CodeGen/aarch64-neon-fma.c
+++ clang/test/CodeGen/aarch64-neon-fma.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -ffp-contract=off -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
 
 // Test new aarch64 intrinsics and types
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2437,6 +2437,12 @@
   if (Arch == llvm::Triple::spir || Arch == llvm::Triple::spir64) {
     Res.getDiagnosticOpts().Warnings.push_back("spir-compat");
   }
+
+  if (    (LangOpts.C11 || LangOpts.C99 || LangOpts.CPlusPlus)
+       && ( CodeGenOptions::FPC_On == Res.getCodeGenOpts().getFPContractMode() )
+       && ! LangOpts.CUDA)
+    LangOpts.DefaultFPContract = 1;
+
   return Success;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to