diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-03-21 19:31:53 +0000 | 
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-03-21 19:31:53 +0000 | 
| commit | e235942a1e8f4cbeed6ff9ab744aa01616653c51 (patch) | |
| tree | 400a473b0dd3a6474fe61bb077b02e9654de5a06 /llvm/lib/Analysis | |
| parent | f2ab05c43259f59ff5a2ed1704748747d53c5f05 (diff) | |
| download | bcm5719-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.cpp | 42 | 
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 | 

