summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-03-21 19:31:53 +0000
committerSanjay Patel <spatel@rotateright.com>2018-03-21 19:31:53 +0000
commite235942a1e8f4cbeed6ff9ab744aa01616653c51 (patch)
tree400a473b0dd3a6474fe61bb077b02e9654de5a06 /llvm/lib/Analysis
parentf2ab05c43259f59ff5a2ed1704748747d53c5f05 (diff)
downloadbcm5719-llvm-e235942a1e8f4cbeed6ff9ab744aa01616653c51.tar.gz
bcm5719-llvm-e235942a1e8f4cbeed6ff9ab744aa01616653c51.zip
[InstSimplify] fp_binop X, NaN --> NaN
We propagate the existing NaN value when possible. Differential Revision: https://reviews.llvm.org/D44521 llvm-svn: 328140
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp42
1 files changed, 32 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 13e4fca781f..149a1967164 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4163,6 +4163,28 @@ Value *llvm::SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);
}
+static Constant *propagateNaN(Constant *In) {
+ // If the input is a vector with undef elements, just return a default NaN.
+ if (!In->isNaN())
+ return ConstantFP::getNaN(In->getType());
+
+ // Propagate the existing NaN constant when possible.
+ // TODO: Should we quiet a signaling NaN?
+ return In;
+}
+
+static Constant *simplifyFPBinop(Value *Op0, Value *Op1) {
+ if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
+ return ConstantFP::getNaN(Op0->getType());
+
+ if (match(Op0, m_NaN()))
+ return propagateNaN(cast<Constant>(Op0));
+ if (match(Op1, m_NaN()))
+ return propagateNaN(cast<Constant>(Op1));
+
+ return nullptr;
+}
+
/// Given operands for an FAdd, see if we can fold the result. If not, this
/// returns null.
static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
@@ -4170,8 +4192,8 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
return C;
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+ if (Constant *C = simplifyFPBinop(Op0, Op1))
+ return C;
// fadd X, -0 ==> X
if (match(Op1, m_NegZero()))
@@ -4203,8 +4225,8 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
return C;
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+ if (Constant *C = simplifyFPBinop(Op0, Op1))
+ return C;
// fsub X, 0 ==> X
if (match(Op1, m_Zero()))
@@ -4238,8 +4260,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FMul, Op0, Op1, Q))
return C;
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+ if (Constant *C = simplifyFPBinop(Op0, Op1))
+ return C;
// fmul X, 1.0 ==> X
if (match(Op1, m_FPOne()))
@@ -4282,8 +4304,8 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
return C;
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+ if (Constant *C = simplifyFPBinop(Op0, Op1))
+ return C;
// X / 1.0 -> X
if (match(Op1, m_FPOne()))
@@ -4329,8 +4351,8 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
return C;
- if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
- return ConstantFP::getNaN(Op0->getType());
+ if (Constant *C = simplifyFPBinop(Op0, Op1))
+ return C;
// Unlike fdiv, the result of frem always matches the sign of the dividend.
// The constant match may include undef elements in a vector, so return a full
OpenPOWER on IntegriCloud