mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Split -enable-finite-only-fp-math to two options:
-enable-no-nans-fp-math and -enable-no-infs-fp-math. All of the current codegen fp math optimizations only care whether the fp arithmetics arguments and results can never be NaN. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
14ceb87c51
commit
60108e96bb
@ -71,13 +71,18 @@ namespace llvm {
|
||||
/// UnsafeFPMath implies LessPreciseFPMAD.
|
||||
extern bool UnsafeFPMath;
|
||||
|
||||
/// FiniteOnlyFPMath - This returns true when the -enable-finite-only-fp-math
|
||||
/// option is specified on the command line. If this returns false (default),
|
||||
/// the code generator is not allowed to assume that FP arithmetic arguments
|
||||
/// and results are never NaNs or +-Infs.
|
||||
extern bool FiniteOnlyFPMathOption;
|
||||
extern bool FiniteOnlyFPMath();
|
||||
|
||||
/// NoInfsFPMath - This flag is enabled when the
|
||||
/// -enable-no-infs-fp-math flag is specified on the command line. When
|
||||
/// this flag is off (the default), the code generator is not allowed to
|
||||
/// assume the FP arithmetic arguments and results are never +-Infs.
|
||||
extern bool NoInfsFPMath;
|
||||
|
||||
/// NoNaNsFPMath - This flag is enabled when the
|
||||
/// -enable-no-nans-fp-math flag is specified on the command line. When
|
||||
/// this flag is off (the default), the code generator is not allowed to
|
||||
/// assume the FP arithmetic arguments and results are never NaNs.
|
||||
extern bool NoNaNsFPMath;
|
||||
|
||||
/// 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
|
||||
|
@ -171,7 +171,7 @@ ISD::CondCode llvm::getFCmpCondCode(FCmpInst::Predicate Pred) {
|
||||
FOC = FPC = ISD::SETFALSE;
|
||||
break;
|
||||
}
|
||||
if (FiniteOnlyFPMath())
|
||||
if (NoNaNsFPMath)
|
||||
return FOC;
|
||||
else
|
||||
return FPC;
|
||||
|
@ -2236,7 +2236,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{
|
||||
|
||||
bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
|
||||
// If we're told that NaNs won't happen, assume they won't.
|
||||
if (FiniteOnlyFPMath())
|
||||
if (NoNaNsFPMath)
|
||||
return true;
|
||||
|
||||
// If the value is a constant, we can obviously see if it is a NaN or not.
|
||||
|
@ -2403,8 +2403,9 @@ ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
|
||||
bool SeenZero = false;
|
||||
if (canChangeToInt(LHS, SeenZero, Subtarget) &&
|
||||
canChangeToInt(RHS, SeenZero, Subtarget) &&
|
||||
// If one of the operand is zero, it's safe to ignore the NaN case.
|
||||
(FiniteOnlyFPMath() || SeenZero)) {
|
||||
// If one of the operand is zero, it's safe to ignore the NaN case since
|
||||
// we only care about equality comparisons.
|
||||
(SeenZero || (DAG.isKnownNeverNaN(LHS) && DAG.isKnownNeverNaN(RHS)))) {
|
||||
// If unsafe fp math optimization is enabled and there are no othter uses of
|
||||
// the CMP operands, and the condition code is EQ oe NE, we can optimize it
|
||||
// to an integer comparison.
|
||||
@ -4561,7 +4562,7 @@ static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG,
|
||||
static SDValue PerformSELECT_CCCombine(SDNode *N, SelectionDAG &DAG,
|
||||
const ARMSubtarget *ST) {
|
||||
// If the target supports NEON, try to use vmax/vmin instructions for f32
|
||||
// selects like "x < y ? x : y". Unless the FiniteOnlyFPMath option is set,
|
||||
// selects like "x < y ? x : y". Unless the NoNaNsFPMath option is set,
|
||||
// be careful about NaNs: NEON's vmax/vmin return NaN if either operand is
|
||||
// a NaN; only do the transformation when it matches that behavior.
|
||||
|
||||
|
@ -1174,7 +1174,7 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
|
||||
}
|
||||
|
||||
if (FiniteOnlyFPMath())
|
||||
if (NoInfsFPMath && NoNaNsFPMath)
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
|
||||
else
|
||||
|
@ -30,7 +30,8 @@ namespace llvm {
|
||||
bool NoFramePointerElimNonLeaf;
|
||||
bool NoExcessFPPrecision;
|
||||
bool UnsafeFPMath;
|
||||
bool FiniteOnlyFPMathOption;
|
||||
bool NoInfsFPMath;
|
||||
bool NoNaNsFPMath;
|
||||
bool HonorSignDependentRoundingFPMathOption;
|
||||
bool UseSoftFloat;
|
||||
FloatABI::ABIType FloatABIType;
|
||||
@ -80,9 +81,14 @@ EnableUnsafeFPMath("enable-unsafe-fp-math",
|
||||
cl::location(UnsafeFPMath),
|
||||
cl::init(false));
|
||||
static cl::opt<bool, true>
|
||||
EnableFiniteOnlyFPMath("enable-finite-only-fp-math",
|
||||
cl::desc("Enable optimizations that assumes non- NaNs / +-Infs"),
|
||||
cl::location(FiniteOnlyFPMathOption),
|
||||
EnableNoInfsFPMath("enable-no-infs-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no +-Infs"),
|
||||
cl::location(NoInfsFPMath),
|
||||
cl::init(false));
|
||||
static cl::opt<bool, true>
|
||||
EnableNoNaNsFPMath("enable-no-nans-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no NaNs"),
|
||||
cl::location(NoNaNsFPMath),
|
||||
cl::init(false));
|
||||
static cl::opt<bool, true>
|
||||
EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
|
||||
@ -290,12 +296,6 @@ namespace llvm {
|
||||
/// result is "less precise" than doing those operations individually.
|
||||
bool LessPreciseFPMAD() { return UnsafeFPMath || LessPreciseFPMADOption; }
|
||||
|
||||
/// FiniteOnlyFPMath - This returns true when the -enable-finite-only-fp-math
|
||||
/// option is specified on the command line. If this returns false (default),
|
||||
/// the code generator is not allowed to assume that FP arithmetic arguments
|
||||
/// and results are never NaNs or +-Infs.
|
||||
bool FiniteOnlyFPMath() { return FiniteOnlyFPMathOption; }
|
||||
|
||||
/// HonorSignDependentRoundingFPMath - Return true if the codegen must assume
|
||||
/// that the rounding mode of the FPU can change from its default.
|
||||
bool HonorSignDependentRoundingFPMath() {
|
||||
|
@ -9087,8 +9087,7 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// Converting this to a min would handle NaNs incorrectly, and swapping
|
||||
// the operands would cause it to handle comparisons between positive
|
||||
// and negative zero incorrectly.
|
||||
if (!FiniteOnlyFPMath() &&
|
||||
(!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))) {
|
||||
if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
|
||||
if (!UnsafeFPMath &&
|
||||
!(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
|
||||
break;
|
||||
@ -9126,8 +9125,7 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// Converting this to a max would handle NaNs incorrectly, and swapping
|
||||
// the operands would cause it to handle comparisons between positive
|
||||
// and negative zero incorrectly.
|
||||
if (!FiniteOnlyFPMath() &&
|
||||
(!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))) {
|
||||
if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)) {
|
||||
if (!UnsafeFPMath &&
|
||||
!(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
|
||||
break;
|
||||
@ -9156,8 +9154,7 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// cause it to handle NaNs incorrectly.
|
||||
if (!UnsafeFPMath &&
|
||||
!(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS))) {
|
||||
if (!FiniteOnlyFPMath() &&
|
||||
(!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
|
||||
if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
|
||||
break;
|
||||
std::swap(LHS, RHS);
|
||||
}
|
||||
@ -9182,8 +9179,7 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
|
||||
|
||||
case ISD::SETULT:
|
||||
// Converting this to a max would handle NaNs incorrectly.
|
||||
if (!FiniteOnlyFPMath() &&
|
||||
(!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
|
||||
if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
|
||||
break;
|
||||
Opcode = X86ISD::FMAX;
|
||||
break;
|
||||
@ -9193,8 +9189,7 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
|
||||
// cause it to handle NaNs incorrectly.
|
||||
if (!UnsafeFPMath &&
|
||||
!DAG.isKnownNeverZero(LHS) && !DAG.isKnownNeverZero(RHS)) {
|
||||
if (!FiniteOnlyFPMath() &&
|
||||
(!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS)))
|
||||
if (!DAG.isKnownNeverNaN(LHS) || !DAG.isKnownNeverNaN(RHS))
|
||||
break;
|
||||
std::swap(LHS, RHS);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s -march=arm -mcpu=cortex-a8 -mattr=+vfp2 -enable-unsafe-fp-math -enable-finite-only-fp-math | FileCheck -check-prefix=FINITE %s
|
||||
; RUN: llc < %s -march=arm -mcpu=cortex-a8 -mattr=+vfp2 -enable-unsafe-fp-math -enable-no-nans-fp-math | FileCheck -check-prefix=FINITE %s
|
||||
; RUN: llc < %s -march=arm -mcpu=cortex-a8 -mattr=+vfp2 -enable-unsafe-fp-math | FileCheck -check-prefix=NAN %s
|
||||
; rdar://7461510
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc < %s -march=x86 | grep setnp
|
||||
; RUN: llc < %s -march=x86 -enable-unsafe-fp-math -enable-finite-only-fp-math | \
|
||||
; RUN: llc < %s -march=x86 -enable-unsafe-fp-math -enable-no-nans-fp-math | \
|
||||
; RUN: not grep setnp
|
||||
|
||||
define i32 @test(float %f) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
; Make sure this testcase codegens to the fabs instruction, not a call to fabsf
|
||||
; RUN: llc < %s -march=x86 -mattr=-sse2,-sse3,-sse | grep fabs\$ | \
|
||||
; RUN: count 2
|
||||
; RUN: llc < %s -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math -enable-finite-only-fp-math | \
|
||||
; RUN: llc < %s -march=x86 -mattr=-sse,-sse2,-sse3 -enable-unsafe-fp-math -enable-no-nans-fp-math | \
|
||||
; RUN: grep fabs\$ | count 3
|
||||
|
||||
declare float @fabsf(float)
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s
|
||||
; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-unsafe-fp-math -enable-finite-only-fp-math | FileCheck -check-prefix=UNSAFE %s
|
||||
; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-finite-only-fp-math | FileCheck -check-prefix=FINITE %s
|
||||
; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-unsafe-fp-math -enable-no-nans-fp-math | FileCheck -check-prefix=UNSAFE %s
|
||||
; RUN: llc < %s -march=x86-64 -asm-verbose=false -enable-no-nans-fp-math | FileCheck -check-prefix=FINITE %s
|
||||
|
||||
; Some of these patterns can be matched as SSE min or max. Some of
|
||||
; then can be matched provided that the operands are swapped.
|
||||
|
Loading…
Reference in New Issue
Block a user