From 46b5b8838759324c25affab9e6d0285898d9ae0a Mon Sep 17 00:00:00 2001 From: Sjoerd Meijer Date: Wed, 31 Aug 2016 14:17:38 +0000 Subject: [PATCH] Clang patch r280064 introduced ways to set the FP exceptions and denormal types. This is the LLVM counterpart and it adds options that map onto FP exceptions and denormal build attributes allowing better fp math library selections. Differential Revision: https://reviews.llvm.org/D24070 llvm-svn: 280246 --- llvm/include/llvm/CodeGen/CommandFlags.h | 22 +++++++++++++++++ llvm/include/llvm/Target/TargetOptions.h | 22 +++++++++++++++++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 41 +++++++++++++++++++++++-------- llvm/lib/Target/TargetMachine.cpp | 10 ++++++++ llvm/test/CodeGen/ARM/build-attributes.ll | 11 +++++++++ 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h index 4c05e7f..6821ec0 100644 --- a/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/llvm/include/llvm/CodeGen/CommandFlags.h @@ -150,6 +150,26 @@ EnableNoNaNsFPMath("enable-no-nans-fp-math", cl::init(false)); cl::opt +EnableNoTrappingFPMath("enable-no-trapping-fp-math", + cl::desc("Enable setting the FP exceptions build " + "attribute not to use exceptions"), + cl::init(false)); + +cl::opt +DenormalType("denormal-fp-math", + cl::desc("Select which denormal numbers the code is permitted to require"), + cl::init(FPDenormal::IEEE), + cl::values( + clEnumValN(FPDenormal::IEEE, "ieee", + "IEEE 754 denormal numbers"), + clEnumValN(FPDenormal::PreserveSign, "preserve-sign", + "the sign of a flushed-to-zero number is preserved " + "in the sign of 0"), + clEnumValN(FPDenormal::PositiveZero, "positive-zero", + "denormals are flushed to positive zero"), + clEnumValEnd)); + +cl::opt EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math", cl::Hidden, cl::desc("Force codegen to assume rounding mode can change dynamically"), @@ -289,6 +309,8 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { Options.UnsafeFPMath = EnableUnsafeFPMath; Options.NoInfsFPMath = EnableNoInfsFPMath; Options.NoNaNsFPMath = EnableNoNaNsFPMath; + Options.NoTrappingFPMath = EnableNoTrappingFPMath; + Options.FPDenormalType = DenormalType; Options.HonorSignDependentRoundingFPMathOption = EnableHonorSignDependentRoundingFPMath; if (FloatABIForCalls != FloatABI::Default) diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index b1e938e..07906e3 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -56,6 +56,15 @@ namespace llvm { }; } + namespace FPDenormal { + enum DenormalType { + IEEE, // IEEE 754 denormal numbers + PreserveSign, // the sign of a flushed-to-zero number is preserved in + // the sign of 0 + PositiveZero // denormals are flushed to positive zero + }; + } + enum class EABI { Unknown, Default, // Default means not specified @@ -93,6 +102,7 @@ namespace llvm { TargetOptions() : PrintMachineCode(false), LessPreciseFPMADOption(false), UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false), + NoTrappingFPMath(false), HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), GuaranteedTailCallOpt(false), StackAlignmentOverride(0), StackSymbolOrdering(true), EnableFastISel(false), UseInitArray(false), @@ -104,6 +114,7 @@ namespace llvm { AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX), EABIVersion(EABI::Default), DebuggerTuning(DebuggerKind::Default), + FPDenormalType(FPDenormal::IEEE), ExceptionModel(ExceptionHandling::None) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -143,6 +154,11 @@ namespace llvm { /// assume the FP arithmetic arguments and results are never NaNs. unsigned NoNaNsFPMath : 1; + /// NoTrappingFPMath - This flag is enabled when the + /// -enable-no-trapping-fp-math is specified on the command line. This + /// specifies that there are no trap handlers to handle exceptions. + unsigned NoTrappingFPMath : 1; + /// HonorSignDependentRoundingFPMath - This returns true when the /// -enable-sign-dependent-rounding-fp-math is specified. If this returns /// false (the default), the code generator is allowed to assume that the @@ -253,6 +269,10 @@ namespace llvm { /// Which debugger to tune for. DebuggerKind DebuggerTuning; + /// FPDenormalType - This flags specificies which denormal numbers the code + /// is permitted to require. + FPDenormal::DenormalType FPDenormalType; + /// What exception model to use ExceptionHandling ExceptionModel; @@ -270,6 +290,7 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(UnsafeFPMath) && ARE_EQUAL(NoInfsFPMath) && ARE_EQUAL(NoNaNsFPMath) && + ARE_EQUAL(NoTrappingFPMath) && ARE_EQUAL(HonorSignDependentRoundingFPMathOption) && ARE_EQUAL(NoZerosInBSS) && ARE_EQUAL(GuaranteedTailCallOpt) && @@ -285,6 +306,7 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(ThreadModel) && ARE_EQUAL(EABIVersion) && ARE_EQUAL(DebuggerTuning) && + ARE_EQUAL(FPDenormalType) && ARE_EQUAL(ExceptionModel) && ARE_EQUAL(MCOptions) && ARE_EQUAL(EnableIPRA); diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 53b2c3d..9e3d1ee 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -451,8 +451,16 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer->EmitAssemblerFlag(MCAF_SyntaxUnified); // Emit ARM Build Attributes - if (TT.isOSBinFormatELF()) + if (TT.isOSBinFormatELF()) { + if (!M.empty()) { + // FIXME: this is a hack, but it is not more broken than + // resetTargetOptions already was. The purpose of reading the target + // options here is to read function attributes denormal and trapping-math + // that we want to map onto build attributes. + TM.resetTargetOptions(*M.begin()); + } emitAttributes(); + } // Use the triple's architecture and subarchitecture to determine // if we're thumb for the purposes of the top level code16 assembler @@ -750,17 +758,17 @@ void ARMAsmPrinter::emitAttributes() { ARMBuildAttrs::AddressDirect); } - // Signal various FP modes. - if (!TM.Options.UnsafeFPMath) { + // Set FP Denormals. + if (TM.Options.FPDenormalType == FPDenormal::PreserveSign) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, + ARMBuildAttrs::PreserveFPSign); + else if (TM.Options.FPDenormalType == FPDenormal::PositiveZero) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, + ARMBuildAttrs::PositiveZero); + else if (!TM.Options.UnsafeFPMath) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::IEEEDenormals); - ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed); - - // If the user has permitted this code to choose the IEEE 754 - // rounding at run-time, emit the rounding attribute. - if (TM.Options.HonorSignDependentRoundingFPMathOption) - ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed); - } else { + else { if (!STI.hasVFP2()) { // When the target doesn't have an FPU (by design or // intention), the assumptions made on the software support @@ -786,6 +794,19 @@ void ARMAsmPrinter::emitAttributes() { // absence of its emission implies zero). } + // Set FP exceptions and rounding + if (TM.Options.NoTrappingFPMath) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, + ARMBuildAttrs::Not_Allowed); + else if (!TM.Options.UnsafeFPMath) { + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed); + + // If the user has permitted this code to choose the IEEE 754 + // rounding at run-time, emit the rounding attribute. + if (TM.Options.HonorSignDependentRoundingFPMathOption) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed); + } + // TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath is the // equivalent of GCC's -ffinite-math-only flag. if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath) diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 82c6850..60505f4 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -77,6 +77,16 @@ void TargetMachine::resetTargetOptions(const Function &F) const { RESET_OPTION(UnsafeFPMath, "unsafe-fp-math"); RESET_OPTION(NoInfsFPMath, "no-infs-fp-math"); RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math"); + RESET_OPTION(NoTrappingFPMath, "no-trapping-math"); + + StringRef Denormal = + F.getFnAttribute("denormal-fp-math").getValueAsString(); + if (Denormal == "ieee") + Options.FPDenormalType = FPDenormal::IEEE; + else if (Denormal == "preserve-sign") + Options.FPDenormalType = FPDenormal::PreserveSign; + else if (Denormal == "positive-zero") + Options.FPDenormalType = FPDenormal::PositiveZero; } /// Returns the code generation relocation model. The choices are static, PIC, diff --git a/llvm/test/CodeGen/ARM/build-attributes.ll b/llvm/test/CodeGen/ARM/build-attributes.ll index 53b8fc3..bd0ad02 100644 --- a/llvm/test/CodeGen/ARM/build-attributes.ll +++ b/llvm/test/CodeGen/ARM/build-attributes.ll @@ -61,6 +61,11 @@ ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-A17-NOFPU ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A17-NOFPU-FAST +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -enable-no-trapping-fp-math | FileCheck %s --check-prefix=NO-TRAPPING-MATH +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -denormal-fp-math=ieee | FileCheck %s --check-prefix=DENORMAL-IEEE +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -denormal-fp-math=preserve-sign | FileCheck %s --check-prefix=DENORMAL-PRESERVE-SIGN +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -denormal-fp-math=positive-zero | FileCheck %s --check-prefix=DENORMAL-POSITIVE-ZERO + ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3-FP16 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+d16,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3-D16-FP16 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+fp-only-sp,+d16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3XD @@ -846,6 +851,12 @@ ; CORTEX-A17-NOFPU-FAST-NOT: .eabi_attribute 22 ; CORTEX-A17-NOFPU-FAST: .eabi_attribute 23, 1 +; Test flags -enable-no-trapping-fp-math and -denormal-fp-math: +; NO-TRAPPING-MATH: .eabi_attribute 21, 0 +; DENORMAL-IEEE: .eabi_attribute 20, 1 +; DENORMAL-PRESERVE-SIGN: .eabi_attribute 20, 2 +; DENORMAL-POSITIVE-ZERO: .eabi_attribute 20, 0 + ; CORTEX-M0: .cpu cortex-m0 ; CORTEX-M0: .eabi_attribute 6, 12 ; CORTEX-M0-NOT: .eabi_attribute 7 -- 2.7.4