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