diff options
Diffstat (limited to 'lib/Analysis/ValueTracking.cpp')
| -rw-r--r-- | lib/Analysis/ValueTracking.cpp | 26 | 
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 2730daefa625..cd4cee631568 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -4238,14 +4238,14 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,    LHS = CmpLHS;    RHS = CmpRHS; -  // If the predicate is an "or-equal"  (FP) predicate, then signed zeroes may -  // return inconsistent results between implementations. -  //   (0.0 <= -0.0) ? 0.0 : -0.0 // Returns 0.0 -  //   minNum(0.0, -0.0)          // May return -0.0 or 0.0 (IEEE 754-2008 5.3.1) -  // Therefore we behave conservatively and only proceed if at least one of the -  // operands is known to not be zero, or if we don't care about signed zeroes. +  // Signed zero may return inconsistent results between implementations. +  //  (0.0 <= -0.0) ? 0.0 : -0.0 // Returns 0.0 +  //  minNum(0.0, -0.0)          // May return -0.0 or 0.0 (IEEE 754-2008 5.3.1) +  // Therefore, we behave conservatively and only proceed if at least one of the +  // operands is known to not be zero or if we don't care about signed zero.    switch (Pred) {    default: break; +  // FIXME: Include OGT/OLT/UGT/ULT.    case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLE:    case CmpInst::FCMP_UGE: case CmpInst::FCMP_ULE:      if (!FMF.noSignedZeros() && !isKnownNonZero(CmpLHS) && @@ -4493,14 +4493,24 @@ SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,    // Deal with type mismatches.    if (CastOp && CmpLHS->getType() != TrueVal->getType()) { -    if (Value *C = lookThroughCast(CmpI, TrueVal, FalseVal, CastOp)) +    if (Value *C = lookThroughCast(CmpI, TrueVal, FalseVal, CastOp)) { +      // If this is a potential fmin/fmax with a cast to integer, then ignore +      // -0.0 because there is no corresponding integer value. +      if (*CastOp == Instruction::FPToSI || *CastOp == Instruction::FPToUI) +        FMF.setNoSignedZeros();        return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,                                    cast<CastInst>(TrueVal)->getOperand(0), C,                                    LHS, RHS); -    if (Value *C = lookThroughCast(CmpI, FalseVal, TrueVal, CastOp)) +    } +    if (Value *C = lookThroughCast(CmpI, FalseVal, TrueVal, CastOp)) { +      // If this is a potential fmin/fmax with a cast to integer, then ignore +      // -0.0 because there is no corresponding integer value. +      if (*CastOp == Instruction::FPToSI || *CastOp == Instruction::FPToUI) +        FMF.setNoSignedZeros();        return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,                                    C, cast<CastInst>(FalseVal)->getOperand(0),                                    LHS, RHS); +    }    }    return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS, TrueVal, FalseVal,                                LHS, RHS);  | 
