Author: spatel Date: Fri Apr 27 07:22:48 2018 New Revision: 331041 URL: http://llvm.org/viewvc/llvm-project?rev=331041&view=rev Log: [Driver, CodeGen] add options to enable/disable an FP cast optimization
As discussed in the post-commit thread for: rL330437 ( http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20180423/545906.html ) We need a way to opt-out of a float-to-int-to-float cast optimization because too much existing code relies on the platform-specific undefined result of those casts when the float-to-int overflows. The LLVM changes associated with adding this function attribute are here: rL330947 rL330950 rL330951 Also as suggested, I changed the LLVM doc to mention the specific sanitizer flag that catches this problem: rL330958 Differential Revision: https://reviews.llvm.org/D46135 Added: cfe/trunk/test/CodeGen/no-junk-ftrunc.c Modified: cfe/trunk/docs/UsersManual.rst cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/Driver/ToolChains/Clang.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/Driver/fast-math.c Modified: cfe/trunk/docs/UsersManual.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/docs/UsersManual.rst (original) +++ cfe/trunk/docs/UsersManual.rst Fri Apr 27 07:22:48 2018 @@ -1255,6 +1255,16 @@ are listed below. flushed-to-zero number is preserved in the sign of 0, denormals are flushed to positive zero, respectively. +.. option:: -f[no-]fp-cast-overflow-workaround + + Enable a workaround for code that casts floating-point values to + integers and back to floating-point. If the floating-point value + is not representable in the intermediate integer type, the code is + incorrect according to the language standard. This flag will attempt + to generate code as if the result of an overflowing conversion matches + the overflowing behavior of a target's native float-to-int conversion + instructions. + .. option:: -fwhole-program-vtables Enable whole-program vtable optimizations, such as single-implementation Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Fri Apr 27 07:22:48 2018 @@ -1029,6 +1029,11 @@ def ffp_contract : Joined<["-"], "ffp-co Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)" " | on (according to FP_CONTRACT pragma, default) | off (never fuse)">, Values<"fast,on,off">; +def ffp_cast_overflow_workaround : Flag<["-"], + "ffp-cast-overflow-workaround">, Group<f_Group>, Flags<[CC1Option]>; +def fno_fp_cast_overflow_workaround : Flag<["-"], + "fno-fp-cast-overflow-workaround">, Group<f_Group>, Flags<[CC1Option]>; + def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>; Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original) +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Fri Apr 27 07:22:48 2018 @@ -136,6 +136,12 @@ CODEGENOPT(NoTrappingMath , 1, 0) /// CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. CODEGENOPT(FlushDenorm , 1, 0) ///< Allow FP denorm numbers to be flushed to zero CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt + +/// Disable a float-to-int-to-float cast optimization. This attempts to generate +/// code as if the result of an overflowing conversion matches the overflowing +/// behavior of a target's native float-to-int conversion instructions. +CODEGENOPT(FPCastOverflowWorkaround, 1, 0) + CODEGENOPT(UniformWGSize , 1, 0) ///< -cl-uniform-work-group-size CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. /// \brief Method of Objective-C dispatch to use. Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Apr 27 07:22:48 2018 @@ -1727,6 +1727,9 @@ void CodeGenModule::ConstructDefaultFnAt FuncAttrs.addAttribute("no-trapping-math", llvm::toStringRef(CodeGenOpts.NoTrappingMath)); + if (CodeGenOpts.FPCastOverflowWorkaround) + FuncAttrs.addAttribute("fp-cast-overflow-workaround", "true"); + // TODO: Are these all needed? // unsafe/inf/nan/nsz are handled by instruction-level FastMathFlags. FuncAttrs.addAttribute("no-infs-fp-math", Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Fri Apr 27 07:22:48 2018 @@ -2241,6 +2241,11 @@ static void RenderFloatingPointOptions(c CmdArgs.push_back("-mfpmath"); CmdArgs.push_back(A->getValue()); } + + // Disable a codegen optimization for floating-point casts. + if (Args.hasFlag(options::OPT_ffp_cast_overflow_workaround, + options::OPT_fno_fp_cast_overflow_workaround, false)) + CmdArgs.push_back("-ffp-cast-overflow-workaround"); } static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs, Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Apr 27 07:22:48 2018 @@ -699,6 +699,8 @@ static bool ParseCodeGenArgs(CodeGenOpti Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ); Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math); Opts.NoTrappingMath = Args.hasArg(OPT_fno_trapping_math); + Opts.FPCastOverflowWorkaround = Args.hasArg(OPT_ffp_cast_overflow_workaround); + Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); Added: cfe/trunk/test/CodeGen/no-junk-ftrunc.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/no-junk-ftrunc.c?rev=331041&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/no-junk-ftrunc.c (added) +++ cfe/trunk/test/CodeGen/no-junk-ftrunc.c Fri Apr 27 07:22:48 2018 @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -S -ffp-cast-overflow-workaround %s -emit-llvm -o - | FileCheck %s +// CHECK-LABEL: main +// CHECK: attributes #0 = {{.*}}"fp-cast-overflow-workaround"="true"{{.*}} + +// The workaround attribute is not applied by default. + +// RUN: %clang_cc1 -S %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT +// DEFAULT-LABEL: main +// DEFAULT-NOT: fp-cast-overflow-workaround + +int main() { + return 0; +} + Modified: cfe/trunk/test/Driver/fast-math.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fast-math.c?rev=331041&r1=331040&r2=331041&view=diff ============================================================================== --- cfe/trunk/test/Driver/fast-math.c (original) +++ cfe/trunk/test/Driver/fast-math.c Fri Apr 27 07:22:48 2018 @@ -287,3 +287,27 @@ // RUN: %clang -### -ftrapping-math -fno-trapping-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-TRAPPING-MATH %s // CHECK-NO-TRAPPING-MATH: "-fno-trapping-math" + +// This isn't fast-math, but the option is handled in the same place as other FP params. +// Last option wins, and the flag is *not* passed by default. + +// RUN: %clang -### -ffp-cast-overflow-workaround -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FPOV-WORKAROUND %s +// CHECK-FPOV-WORKAROUND: "-cc1" +// CHECK-FPOV-WORKAROUND: "-ffp-cast-overflow-workaround" + +// RUN: %clang -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-FPOV-WORKAROUND-DEFAULT %s +// CHECK-FPOV-WORKAROUND-DEFAULT: "-cc1" +// CHECK-FPOV-WORKAROUND-DEFAULT-NOT: "-ffp-cast-overflow-workaround" + +// RUN: %clang -### -fno-fp-cast-overflow-workaround -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FPOV-WORKAROUND %s +// CHECK-NO-FPOV-WORKAROUND: "-cc1" +// CHECK-NO-FPOV-WORKAROUND-NOT: "-ffp-cast-overflow-workaround" + +// RUN: %clang -### -ffp-cast-overflow-workaround -fno-fp-cast-overflow-workaround -c %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FPOV-WORKAROUND-OVERRIDE %s +// CHECK-NO-FPOV-WORKAROUND-OVERRIDE: "-cc1" +// CHECK-NO-FPOV-WORKAROUND-OVERRIDE-NOT: "-ffp-cast-overflow-workaround" + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits