forked from OSchip/llvm-project
				
			pull a bunch of logic out of instcombine into instsimplify for compare
simplification, this handles the foldable fcmp x,x cases among many others. llvm-svn: 86627
This commit is contained in:
		
							parent
							
								
									2ac504729b
								
							
						
					
					
						commit
						ccfdceb22c
					
				| 
						 | 
				
			
			@ -31,6 +31,10 @@ Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const Type *GetCompareTy(Value *Op) {
 | 
			
		||||
  return CmpInst::makeCmpResultType(Op->getType());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
 | 
			
		||||
/// fold the result.  If not, this returns null.
 | 
			
		||||
| 
						 | 
				
			
			@ -43,12 +47,58 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 | 
			
		|||
    if (Constant *CRHS = dyn_cast<Constant>(RHS))
 | 
			
		||||
      return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD);
 | 
			
		||||
  
 | 
			
		||||
  // If this is an integer compare and the LHS and RHS are the same, fold it.
 | 
			
		||||
  // ITy - This is the return type of the compare we're considering.
 | 
			
		||||
  const Type *ITy = GetCompareTy(LHS);
 | 
			
		||||
  
 | 
			
		||||
  // icmp X, X -> true/false
 | 
			
		||||
  if (LHS == RHS)
 | 
			
		||||
    if (ICmpInst::isTrueWhenEqual(Pred))
 | 
			
		||||
      return ConstantInt::getTrue(LHS->getContext());
 | 
			
		||||
    else
 | 
			
		||||
      return ConstantInt::getFalse(LHS->getContext());
 | 
			
		||||
    return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
 | 
			
		||||
 | 
			
		||||
  // If we have a constant, make sure it is on the RHS.
 | 
			
		||||
  if (isa<Constant>(LHS)) {
 | 
			
		||||
    std::swap(LHS, RHS);
 | 
			
		||||
    Pred = CmpInst::getSwappedPredicate(Pred);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (isa<UndefValue>(RHS))                  // X icmp undef -> undef
 | 
			
		||||
    return UndefValue::get(ITy);
 | 
			
		||||
  
 | 
			
		||||
  // icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
 | 
			
		||||
  // addresses never equal each other!  We already know that Op0 != Op1.
 | 
			
		||||
  if ((isa<GlobalValue>(LHS) || isa<AllocaInst>(LHS) || 
 | 
			
		||||
       isa<ConstantPointerNull>(LHS)) &&
 | 
			
		||||
      (isa<GlobalValue>(RHS) || isa<AllocaInst>(RHS) || 
 | 
			
		||||
       isa<ConstantPointerNull>(RHS)))
 | 
			
		||||
    return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
 | 
			
		||||
  
 | 
			
		||||
  // See if we are doing a comparison with a constant.
 | 
			
		||||
  if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
 | 
			
		||||
    // If we have an icmp le or icmp ge instruction, turn it into the
 | 
			
		||||
    // appropriate icmp lt or icmp gt instruction.  This allows us to rely on
 | 
			
		||||
    // them being folded in the code below.
 | 
			
		||||
    switch (Pred) {
 | 
			
		||||
    default: break;
 | 
			
		||||
    case ICmpInst::ICMP_ULE:
 | 
			
		||||
      if (CI->isMaxValue(false))                 // A <=u MAX -> TRUE
 | 
			
		||||
        return ConstantInt::getTrue(CI->getContext());
 | 
			
		||||
      break;
 | 
			
		||||
    case ICmpInst::ICMP_SLE:
 | 
			
		||||
      if (CI->isMaxValue(true))                  // A <=s MAX -> TRUE
 | 
			
		||||
        return ConstantInt::getTrue(CI->getContext());
 | 
			
		||||
      break;
 | 
			
		||||
    case ICmpInst::ICMP_UGE:
 | 
			
		||||
      if (CI->isMinValue(false))                 // A >=u MIN -> TRUE
 | 
			
		||||
        return ConstantInt::getTrue(CI->getContext());
 | 
			
		||||
      break;
 | 
			
		||||
    case ICmpInst::ICMP_SGE:
 | 
			
		||||
      if (CI->isMinValue(true))                  // A >=s MIN -> TRUE
 | 
			
		||||
        return ConstantInt::getTrue(CI->getContext());
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +114,44 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 | 
			
		|||
    if (Constant *CRHS = dyn_cast<Constant>(RHS))
 | 
			
		||||
      return ConstantFoldCompareInstOperands(Pred, CLHS, CRHS, TD);
 | 
			
		||||
  
 | 
			
		||||
  // Fold trivial predicates.
 | 
			
		||||
  if (Pred == FCmpInst::FCMP_FALSE)
 | 
			
		||||
    return ConstantInt::get(GetCompareTy(LHS), 0);
 | 
			
		||||
  if (Pred == FCmpInst::FCMP_TRUE)
 | 
			
		||||
    return ConstantInt::get(GetCompareTy(LHS), 1);
 | 
			
		||||
 | 
			
		||||
  // If we have a constant, make sure it is on the RHS.
 | 
			
		||||
  if (isa<Constant>(LHS)) {
 | 
			
		||||
    std::swap(LHS, RHS);
 | 
			
		||||
    Pred = CmpInst::getSwappedPredicate(Pred);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (isa<UndefValue>(RHS))                  // fcmp pred X, undef -> undef
 | 
			
		||||
    return UndefValue::get(GetCompareTy(LHS));
 | 
			
		||||
 | 
			
		||||
  // fcmp x,x -> true/false.  Not all compares are foldable.
 | 
			
		||||
  if (LHS == RHS) {
 | 
			
		||||
    if (CmpInst::isTrueWhenEqual(Pred))
 | 
			
		||||
      return ConstantInt::get(GetCompareTy(LHS), 1);
 | 
			
		||||
    if (CmpInst::isFalseWhenEqual(Pred))
 | 
			
		||||
      return ConstantInt::get(GetCompareTy(LHS), 0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Handle fcmp with constant RHS
 | 
			
		||||
  if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
 | 
			
		||||
    // If the constant is a nan, see if we can fold the comparison based on it.
 | 
			
		||||
    if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHSC)) {
 | 
			
		||||
      if (CFP->getValueAPF().isNaN()) {
 | 
			
		||||
        if (FCmpInst::isOrdered(Pred))   // True "if ordered and foo"
 | 
			
		||||
          return ConstantInt::getFalse(CFP->getContext());
 | 
			
		||||
        assert(FCmpInst::isUnordered(Pred) &&
 | 
			
		||||
               "Comparison must be either ordered or unordered!");
 | 
			
		||||
        // True if unordered.
 | 
			
		||||
        return ConstantInt::getTrue(CFP->getContext());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5942,25 +5942,13 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
 | 
			
		|||
 | 
			
		||||
  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 | 
			
		||||
  
 | 
			
		||||
  // Fold trivial predicates.
 | 
			
		||||
  if (I.getPredicate() == FCmpInst::FCMP_FALSE)
 | 
			
		||||
    return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 0));
 | 
			
		||||
  if (I.getPredicate() == FCmpInst::FCMP_TRUE)
 | 
			
		||||
    return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 1));
 | 
			
		||||
  if (Value *V = SimplifyFCmpInst(I.getPredicate(), Op0, Op1, TD))
 | 
			
		||||
    return ReplaceInstUsesWith(I, V);
 | 
			
		||||
 | 
			
		||||
  // Simplify 'fcmp pred X, X'
 | 
			
		||||
  if (Op0 == Op1) {
 | 
			
		||||
    switch (I.getPredicate()) {
 | 
			
		||||
    default: llvm_unreachable("Unknown predicate!");
 | 
			
		||||
    case FCmpInst::FCMP_UEQ:    // True if unordered or equal
 | 
			
		||||
    case FCmpInst::FCMP_UGE:    // True if unordered, greater than, or equal
 | 
			
		||||
    case FCmpInst::FCMP_ULE:    // True if unordered, less than, or equal
 | 
			
		||||
      return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 1));
 | 
			
		||||
    case FCmpInst::FCMP_OGT:    // True if ordered and greater than
 | 
			
		||||
    case FCmpInst::FCMP_OLT:    // True if ordered and less than
 | 
			
		||||
    case FCmpInst::FCMP_ONE:    // True if ordered and operands are unequal
 | 
			
		||||
      return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), 0));
 | 
			
		||||
      
 | 
			
		||||
    case FCmpInst::FCMP_UNO:    // True if unordered: isnan(X) | isnan(Y)
 | 
			
		||||
    case FCmpInst::FCMP_ULT:    // True if unordered or less than
 | 
			
		||||
    case FCmpInst::FCMP_UGT:    // True if unordered or greater than
 | 
			
		||||
| 
						 | 
				
			
			@ -5981,23 +5969,8 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
    
 | 
			
		||||
  if (isa<UndefValue>(Op1))                  // fcmp pred X, undef -> undef
 | 
			
		||||
    return ReplaceInstUsesWith(I, UndefValue::get(I.getType()));
 | 
			
		||||
 | 
			
		||||
  // Handle fcmp with constant RHS
 | 
			
		||||
  if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
 | 
			
		||||
    // If the constant is a nan, see if we can fold the comparison based on it.
 | 
			
		||||
    if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHSC)) {
 | 
			
		||||
      if (CFP->getValueAPF().isNaN()) {
 | 
			
		||||
        if (FCmpInst::isOrdered(I.getPredicate()))   // True if ordered and...
 | 
			
		||||
          return ReplaceInstUsesWith(I, ConstantInt::getFalse(*Context));
 | 
			
		||||
        assert(FCmpInst::isUnordered(I.getPredicate()) &&
 | 
			
		||||
               "Comparison must be either ordered or unordered!");
 | 
			
		||||
        // True if unordered.
 | 
			
		||||
        return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
 | 
			
		||||
      switch (LHSI->getOpcode()) {
 | 
			
		||||
      case Instruction::PHI:
 | 
			
		||||
| 
						 | 
				
			
			@ -6055,25 +6028,12 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
 | 
			
		|||
  }
 | 
			
		||||
  
 | 
			
		||||
  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 | 
			
		||||
  
 | 
			
		||||
  if (Value *V = SimplifyICmpInst(I.getPredicate(), Op0, Op1, TD))
 | 
			
		||||
    return ReplaceInstUsesWith(I, V);
 | 
			
		||||
  
 | 
			
		||||
  const Type *Ty = Op0->getType();
 | 
			
		||||
 | 
			
		||||
  // icmp X, X
 | 
			
		||||
  if (Op0 == Op1)
 | 
			
		||||
    return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(),
 | 
			
		||||
                                                   I.isTrueWhenEqual()));
 | 
			
		||||
 | 
			
		||||
  if (isa<UndefValue>(Op1))                  // X icmp undef -> undef
 | 
			
		||||
    return ReplaceInstUsesWith(I, UndefValue::get(I.getType()));
 | 
			
		||||
  
 | 
			
		||||
  // icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
 | 
			
		||||
  // addresses never equal each other!  We already know that Op0 != Op1.
 | 
			
		||||
  if ((isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0) || 
 | 
			
		||||
       isa<ConstantPointerNull>(Op0)) &&
 | 
			
		||||
      (isa<GlobalValue>(Op1) || isa<AllocaInst>(Op1) || 
 | 
			
		||||
       isa<ConstantPointerNull>(Op1)))
 | 
			
		||||
    return ReplaceInstUsesWith(I, ConstantInt::get(Type::getInt1Ty(*Context), 
 | 
			
		||||
                                                   !I.isTrueWhenEqual()));
 | 
			
		||||
 | 
			
		||||
  // icmp's with boolean values can always be turned into bitwise operations
 | 
			
		||||
  if (Ty == Type::getInt1Ty(*Context)) {
 | 
			
		||||
    switch (I.getPredicate()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -6137,27 +6097,24 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
 | 
			
		|||
    
 | 
			
		||||
    // If we have an icmp le or icmp ge instruction, turn it into the
 | 
			
		||||
    // appropriate icmp lt or icmp gt instruction.  This allows us to rely on
 | 
			
		||||
    // them being folded in the code below.
 | 
			
		||||
    // them being folded in the code below.  The SimplifyICmpInst code has
 | 
			
		||||
    // already handled the edge cases for us, so we just assert on them.
 | 
			
		||||
    switch (I.getPredicate()) {
 | 
			
		||||
    default: break;
 | 
			
		||||
    case ICmpInst::ICMP_ULE:
 | 
			
		||||
      if (CI->isMaxValue(false))                 // A <=u MAX -> TRUE
 | 
			
		||||
        return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context));
 | 
			
		||||
      assert(!CI->isMaxValue(false));                 // A <=u MAX -> TRUE
 | 
			
		||||
      return new ICmpInst(ICmpInst::ICMP_ULT, Op0,
 | 
			
		||||
                          AddOne(CI));
 | 
			
		||||
    case ICmpInst::ICMP_SLE:
 | 
			
		||||
      if (CI->isMaxValue(true))                  // A <=s MAX -> TRUE
 | 
			
		||||
        return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context));
 | 
			
		||||
      assert(!CI->isMaxValue(true));                  // A <=s MAX -> TRUE
 | 
			
		||||
      return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
 | 
			
		||||
                          AddOne(CI));
 | 
			
		||||
    case ICmpInst::ICMP_UGE:
 | 
			
		||||
      if (CI->isMinValue(false))                 // A >=u MIN -> TRUE
 | 
			
		||||
        return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context));
 | 
			
		||||
      assert(!CI->isMinValue(false));                  // A >=u MIN -> TRUE
 | 
			
		||||
      return new ICmpInst(ICmpInst::ICMP_UGT, Op0,
 | 
			
		||||
                          SubOne(CI));
 | 
			
		||||
    case ICmpInst::ICMP_SGE:
 | 
			
		||||
      if (CI->isMinValue(true))                  // A >=s MIN -> TRUE
 | 
			
		||||
        return ReplaceInstUsesWith(I, ConstantInt::getTrue(*Context));
 | 
			
		||||
      assert(!CI->isMinValue(true));                   // A >=s MIN -> TRUE
 | 
			
		||||
      return new ICmpInst(ICmpInst::ICMP_SGT, Op0,
 | 
			
		||||
                          SubOne(CI));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue