From 3701450b06cb6698a4af0b225be7679d31acfc31 Mon Sep 17 00:00:00 2001 From: Pekka Jaaskelainen Date: Wed, 10 Dec 2014 16:41:14 +0000 Subject: [PATCH] OpenCL C: Add support for a set of floating point arithmetic relaxation flags: -cl-no-signed-zeros -cl-unsafe-math-optimizations -cl-finite-math-only -cl-fast-relaxed-math Propagate the info to FP instruction flags as well as function attributes where they are available. llvm-svn: 223928 --- clang/include/clang/Driver/CC1Options.td | 2 ++ .../include/clang/Frontend/CodeGenOptions.def | 1 + clang/lib/CodeGen/CodeGenFunction.cpp | 6 ++++ clang/lib/Frontend/CompilerInvocation.cpp | 13 ++++--- clang/test/CodeGenOpenCL/relaxed-fpmath.cl | 36 +++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGenOpenCL/relaxed-fpmath.cl diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 10bda46012dd..d31672a592de 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -578,6 +578,8 @@ def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, HelpText<"OpenCL only. Generate kernel argument metadata.">; +def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, + HelpText<"OpenCL only. Allow optimizations to ignore the signedness of the floating-point zero.">; def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">; def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def index 8e0c78a7bd71..6cfe19193182 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.def +++ b/clang/include/clang/Frontend/CodeGenOptions.def @@ -78,6 +78,7 @@ CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. +CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. ///< Disables use of the inline keyword. CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index df9c1d6d1720..4e97f9bfe39f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -63,6 +63,12 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) FMF.setNoNaNs(); FMF.setNoInfs(); } + if (CGM.getCodeGenOpts().NoNaNsFPMath) { + FMF.setNoNaNs(); + } + if (CGM.getCodeGenOpts().NoSignedZeros) { + FMF.setNoSignedZeros(); + } Builder.SetFastMathFlags(FMF); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 59095941a83c..610bfffc7eae 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -417,11 +417,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || - Args.hasArg(OPT_cl_finite_math_only)|| + Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) || - Args.hasArg(OPT_cl_finite_math_only)|| + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); + Opts.NoSignedZeros = Args.hasArg(OPT_cl_no_signed_zeros); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); @@ -1598,8 +1600,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // inlining enabled. Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline); - Opts.FastMath = Args.hasArg(OPT_ffast_math); - Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only); + Opts.FastMath = Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); Opts.RetainCommentsFromSystemHeaders = Args.hasArg(OPT_fretain_comments_from_system_headers); diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl new file mode 100644 index 000000000000..4222ea9c74b5 --- /dev/null +++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL +// RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST +// RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE +// RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE +// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSZ + +typedef __attribute__(( ext_vector_type(4) )) float float4; + +float spscalardiv(float a, float b) { + // CHECK: @spscalardiv( + + // NORMAL: fdiv float + // FAST: fdiv fast float + // FINITE: fdiv nnan ninf float + // UNSAFE: fdiv nnan float + // NOSZ: fdiv nsz float + return a / b; +} +// CHECK: attributes + +// NORMAL: "no-infs-fp-math"="false" +// NORMAL: "no-nans-fp-math"="false" +// NORMAL: "unsafe-fp-math"="false" + +// FAST: "no-infs-fp-math"="true" +// FAST: "no-nans-fp-math"="true" +// FAST: "unsafe-fp-math"="true" + +// FINITE: "no-infs-fp-math"="true" +// FINITE: "no-nans-fp-math"="true" +// FINITE: "unsafe-fp-math"="false" + +// UNSAFE: "no-infs-fp-math"="false" +// UNSAFE: "no-nans-fp-math"="true" +// UNSAFE: "unsafe-fp-math"="true" +