From c4727f207910ea02e14a27b8faaad63d89ac588c Mon Sep 17 00:00:00 2001 From: Adam Nemet Date: Thu, 20 Apr 2017 17:09:35 +0000 Subject: [PATCH] Don't pass FPOpFusion::Strict to the backend This restores the behavior prior to D31167 where the code-gen default was FPC_On which mapped to FPOpFusion::Standard. After merging the FE state (on/off) and the code-gen state (on/fast/off), the default became off to match the front-end. In other words, the front-end controls when to fuse along the language standards and the backend shouldn't override this by splitting fused intrinsics as FPOpFusion::Strict would imply. Differential Revision: https://reviews.llvm.org/D32301 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300858 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/BackendUtil.cpp | 4 +++- test/CodeGen/fp-contract-on-asm.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/fp-contract-on-asm.c diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 3f957403fb..20059d922f 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -369,7 +369,9 @@ static void initTargetOptions(llvm::TargetOptions &Options, // Set FP fusion mode. switch (LangOpts.getDefaultFPContractMode()) { case LangOptions::FPC_Off: - Options.AllowFPOpFusion = llvm::FPOpFusion::Strict; + // Preserve any contraction performed by the front-end. (Strict performs + // splitting of the muladd instrinsic in the backend.) + Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; break; case LangOptions::FPC_On: Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; diff --git a/test/CodeGen/fp-contract-on-asm.c b/test/CodeGen/fp-contract-on-asm.c new file mode 100644 index 0000000000..01a1bd14a0 --- /dev/null +++ b/test/CodeGen/fp-contract-on-asm.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -O3 -triple=aarch64-apple-ios -S -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target + +float fma_test1(float a, float b, float c) { +#pragma STDC FP_CONTRACT ON +// CHECK-LABEL: fma_test1: +// CHECK: fmadd + float x = a * b + c; + return x; +} + +float fma_test2(float a, float b, float c) { +// CHECK-LABEL: fma_test2: +// CHECK: fmul +// CHECK: fadd + float x = a * b + c; + return x; +}