diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-05-22 23:10:53 +0000 | 
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-05-22 23:10:53 +0000 | 
| commit | a838a40bc4e94c544bc9e4ad907ac87f4849ee08 (patch) | |
| tree | 3e6bbaf02480fd9b4fe85f76ec759faedecc0658 | |
| parent | 36fe6901d40560b8f2b940aba9208a303037926f (diff) | |
| download | bcm5719-llvm-a838a40bc4e94c544bc9e4ad907ac87f4849ee08.tar.gz bcm5719-llvm-a838a40bc4e94c544bc9e4ad907ac87f4849ee08.zip  | |
Fix bug in FoldFCmp_IntToFP_Cst. If inttofp is a uintofp, use unsigned instead of signed integer constant.
llvm-svn: 72300
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 128 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/2009-05-23-FCmpToICmp.ll | 9 | 
2 files changed, 76 insertions, 61 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index df5145da2a0..e6f854f1a56 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5598,68 +5598,74 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I,    // [0, UMAX], but it may still be fractional.  See if it is fractional by    // casting the FP value to the integer value and back, checking for equality.    // Don't do this for zero, because -0.0 is not fractional. -  Constant *RHSInt = ConstantExpr::getFPToSI(RHSC, IntTy); -  if (!RHS.isZero() && -      ConstantExpr::getSIToFP(RHSInt, RHSC->getType()) != RHSC) { -    // If we had a comparison against a fractional value, we have to adjust the -    // compare predicate and sometimes the value.  RHSC is rounded towards zero -    // at this point. -    switch (Pred) { -    default: assert(0 && "Unexpected integer comparison!"); -    case ICmpInst::ICMP_NE:  // (float)int != 4.4   --> true -      return ReplaceInstUsesWith(I, ConstantInt::getTrue()); -    case ICmpInst::ICMP_EQ:  // (float)int == 4.4   --> false -      return ReplaceInstUsesWith(I, ConstantInt::getFalse()); -    case ICmpInst::ICMP_ULE: -      // (float)int <= 4.4   --> int <= 4 -      // (float)int <= -4.4  --> false -      if (RHS.isNegative()) -        return ReplaceInstUsesWith(I, ConstantInt::getFalse()); -      break; -    case ICmpInst::ICMP_SLE: -      // (float)int <= 4.4   --> int <= 4 -      // (float)int <= -4.4  --> int < -4 -      if (RHS.isNegative()) -        Pred = ICmpInst::ICMP_SLT; -      break; -    case ICmpInst::ICMP_ULT: -      // (float)int < -4.4   --> false -      // (float)int < 4.4    --> int <= 4 -      if (RHS.isNegative()) -        return ReplaceInstUsesWith(I, ConstantInt::getFalse()); -      Pred = ICmpInst::ICMP_ULE; -      break; -    case ICmpInst::ICMP_SLT: -      // (float)int < -4.4   --> int < -4 -      // (float)int < 4.4    --> int <= 4 -      if (!RHS.isNegative()) -        Pred = ICmpInst::ICMP_SLE; -      break; -    case ICmpInst::ICMP_UGT: -      // (float)int > 4.4    --> int > 4 -      // (float)int > -4.4   --> true -      if (RHS.isNegative()) -        return ReplaceInstUsesWith(I, ConstantInt::getTrue()); -      break; -    case ICmpInst::ICMP_SGT: -      // (float)int > 4.4    --> int > 4 -      // (float)int > -4.4   --> int >= -4 -      if (RHS.isNegative()) -        Pred = ICmpInst::ICMP_SGE; -      break; -    case ICmpInst::ICMP_UGE: -      // (float)int >= -4.4   --> true -      // (float)int >= 4.4    --> int > 4 -      if (!RHS.isNegative()) +  Constant *RHSInt = LHSUnsigned +    ? ConstantExpr::getFPToUI(RHSC, IntTy) +    : ConstantExpr::getFPToSI(RHSC, IntTy); +  if (!RHS.isZero()) { +    bool Equal = LHSUnsigned +      ? ConstantExpr::getUIToFP(RHSInt, RHSC->getType()) == RHSC +      : ConstantExpr::getSIToFP(RHSInt, RHSC->getType()) == RHSC; +    if (!Equal) { +      // If we had a comparison against a fractional value, we have to adjust +      // the compare predicate and sometimes the value.  RHSC is rounded towards +      // zero at this point. +      switch (Pred) { +      default: assert(0 && "Unexpected integer comparison!"); +      case ICmpInst::ICMP_NE:  // (float)int != 4.4   --> true          return ReplaceInstUsesWith(I, ConstantInt::getTrue()); -      Pred = ICmpInst::ICMP_UGT; -      break; -    case ICmpInst::ICMP_SGE: -      // (float)int >= -4.4   --> int >= -4 -      // (float)int >= 4.4    --> int > 4 -      if (!RHS.isNegative()) -        Pred = ICmpInst::ICMP_SGT; -      break; +      case ICmpInst::ICMP_EQ:  // (float)int == 4.4   --> false +        return ReplaceInstUsesWith(I, ConstantInt::getFalse()); +      case ICmpInst::ICMP_ULE: +        // (float)int <= 4.4   --> int <= 4 +        // (float)int <= -4.4  --> false +        if (RHS.isNegative()) +          return ReplaceInstUsesWith(I, ConstantInt::getFalse()); +        break; +      case ICmpInst::ICMP_SLE: +        // (float)int <= 4.4   --> int <= 4 +        // (float)int <= -4.4  --> int < -4 +        if (RHS.isNegative()) +          Pred = ICmpInst::ICMP_SLT; +        break; +      case ICmpInst::ICMP_ULT: +        // (float)int < -4.4   --> false +        // (float)int < 4.4    --> int <= 4 +        if (RHS.isNegative()) +          return ReplaceInstUsesWith(I, ConstantInt::getFalse()); +        Pred = ICmpInst::ICMP_ULE; +        break; +      case ICmpInst::ICMP_SLT: +        // (float)int < -4.4   --> int < -4 +        // (float)int < 4.4    --> int <= 4 +        if (!RHS.isNegative()) +          Pred = ICmpInst::ICMP_SLE; +        break; +      case ICmpInst::ICMP_UGT: +        // (float)int > 4.4    --> int > 4 +        // (float)int > -4.4   --> true +        if (RHS.isNegative()) +          return ReplaceInstUsesWith(I, ConstantInt::getTrue()); +        break; +      case ICmpInst::ICMP_SGT: +        // (float)int > 4.4    --> int > 4 +        // (float)int > -4.4   --> int >= -4 +        if (RHS.isNegative()) +          Pred = ICmpInst::ICMP_SGE; +        break; +      case ICmpInst::ICMP_UGE: +        // (float)int >= -4.4   --> true +        // (float)int >= 4.4    --> int > 4 +        if (!RHS.isNegative()) +          return ReplaceInstUsesWith(I, ConstantInt::getTrue()); +        Pred = ICmpInst::ICMP_UGT; +        break; +      case ICmpInst::ICMP_SGE: +        // (float)int >= -4.4   --> int >= -4 +        // (float)int >= 4.4    --> int > 4 +        if (!RHS.isNegative()) +          Pred = ICmpInst::ICMP_SGT; +        break; +      }      }    } diff --git a/llvm/test/Transforms/InstCombine/2009-05-23-FCmpToICmp.ll b/llvm/test/Transforms/InstCombine/2009-05-23-FCmpToICmp.ll new file mode 100644 index 00000000000..1eda7dfa9ec --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2009-05-23-FCmpToICmp.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep cmp +; rdar://6903175 + +define i1 @f0(i32 *%a) nounwind { +       %b = load i32* %a, align 4 +       %c = uitofp i32 %b to double +       %d = fcmp ogt double %c, 0x41EFFFFFFFE00000 +       ret i1 %d +}  | 

