From 659bd73d13686948c2b4dbee02df2f82542849dd Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 4 Nov 2019 08:29:56 -0500 Subject: [InstSimplify] use FMF to improve fcmp+select fold This is part of a series of patches needed to solve PR39535: https://bugs.llvm.org/show_bug.cgi?id=39535 --- llvm/lib/Analysis/InstructionSimplify.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp') diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 11a12ab84e9..83b767a8fd1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3909,18 +3909,21 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, /// Try to simplify a select instruction when its condition operand is a /// floating-point comparison. -static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F) { +static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F, + const SimplifyQuery &Q) { FCmpInst::Predicate Pred; if (!match(Cond, m_FCmp(Pred, m_Specific(T), m_Specific(F))) && !match(Cond, m_FCmp(Pred, m_Specific(F), m_Specific(T)))) return nullptr; - // TODO: The transform may not be valid with -0.0. An incomplete way of - // testing for that possibility is to check if at least one operand is a - // non-zero constant. + // This transform is safe if we do not have (do not care about) -0.0 or if + // at least one operand is known to not be -0.0. Otherwise, the select can + // change the sign of a zero operand. + bool HasNoSignedZeros = Q.CxtI && isa(Q.CxtI) && + Q.CxtI->hasNoSignedZeros(); const APFloat *C; - if ((match(T, m_APFloat(C)) && C->isNonZero()) || - (match(F, m_APFloat(C)) && C->isNonZero())) { + if (HasNoSignedZeros || (match(T, m_APFloat(C)) && C->isNonZero()) || + (match(F, m_APFloat(C)) && C->isNonZero())) { // (T == F) ? T : F --> F // (F == T) ? T : F --> F if (Pred == FCmpInst::FCMP_OEQ) @@ -3971,7 +3974,7 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse)) return V; - if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal)) + if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal, Q)) return V; if (Value *V = foldSelectWithBinaryOp(Cond, TrueVal, FalseVal)) -- cgit v1.2.3