FastDivInsertionTask::FastDivInsertionTask(Instruction *I,
                                           const BypassWidthsTy &BypassWidths) {
  switch (I->getOpcode()) {
  case Instruction::UDiv:
  case Instruction::SDiv:
  case Instruction::URem:
  case Instruction::SRem:
    SlowDivOrRem = I;
    break;
  default:
    // I is not a div/rem operation.
    return;
  }

  // Skip division on vector types. Only optimize integer instructions.
  IntegerType *SlowType = dyn_cast<IntegerType>(SlowDivOrRem->getType());
  if (!SlowType)
    return;

  // Skip if this bitwidth is not bypassed.
  auto BI = BypassWidths.find(SlowType->getBitWidth());
  if (BI == BypassWidths.end())
    return;

  // Get type for div/rem instruction with bypass bitwidth.
  IntegerType *BT = IntegerType::get(I->getContext(), BI->second);
  BypassType = BT;

  // The original basic block.
  MainBB = I->getParent();

  // The instruction is indeed a slow div or rem operation.
  IsValidTask = true;
}
void ConstantOffsetExtractor::ComputeKnownBits(Value *V, APInt &KnownOne,
                                               APInt &KnownZero) const {
  IntegerType *IT = cast<IntegerType>(V->getType());
  KnownOne = APInt(IT->getBitWidth(), 0);
  KnownZero = APInt(IT->getBitWidth(), 0);
  llvm::computeKnownBits(V, KnownZero, KnownOne, DL, 0);
}
Esempio n. 3
0
ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const TargetData *TD,
                                                 LLVMContext &Context,
                                                 bool RoundToAlign)
: TD(TD), RoundToAlign(RoundToAlign) {
  IntegerType *IntTy = TD->getIntPtrType(Context);
  IntTyBits = IntTy->getBitWidth();
  Zero = APInt::getNullValue(IntTyBits);
}
Esempio n. 4
0
ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout *DL,
                                                 const TargetLibraryInfo *TLI,
                                                 LLVMContext &Context,
                                                 bool RoundToAlign)
: DL(DL), TLI(TLI), RoundToAlign(RoundToAlign) {
  IntegerType *IntTy = DL->getIntPtrType(Context);
  IntTyBits = IntTy->getBitWidth();
  Zero = APInt::getNullValue(IntTyBits);
}
Esempio n. 5
0
void RuntimeDebugBuilder::createIntPrinter(Value *V) {
  IntegerType *Ty = dyn_cast<IntegerType>(V->getType());
  assert(Ty && Ty->getBitWidth() == 64 &&
         "Cannot insert printer for this type.");

  Function *F = getPrintF();
  Value *String = Builder.CreateGlobalStringPtr("%ld");
  Builder.CreateCall2(F, String, V);
  createFlush();
}
Esempio n. 6
0
static Value *splitStore(StoreInst *Inst, ConversionState &State) {
  if (Inst->isVolatile() || Inst->isAtomic())
    report_fatal_error("Can't split volatile/atomic stores");
  if (cast<IntegerType>(Inst->getValueOperand()->getType())->getBitWidth() % 8
      != 0)
    report_fatal_error("Stores must be a multiple of 8 bits");

  Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
  // OrigPtr is now a placeholder in recursive calls, and so has no name.
  if (OrigPtr->getName().empty())
    OrigPtr->setName(Inst->getPointerOperand()->getName());
  Value *OrigVal = State.getConverted(Inst->getValueOperand());
  unsigned Width = cast<IntegerType>(
      Inst->getValueOperand()->getType())->getBitWidth();
  unsigned LoWidth = Width;

  while (!isLegalSize(LoWidth)) LoWidth -= 8;
  IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth);
  IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth);
  IRBuilder<> IRB(Inst->getParent(), Inst);

  Value *BCLo = IRB.CreateBitCast(
      OrigPtr,
      LoType->getPointerTo(),
      OrigPtr->getName() + ".loty");
  Value *LoTrunc = IRB.CreateTrunc(
      OrigVal, LoType, OrigVal->getName() + ".lo");
  IRB.CreateAlignedStore(LoTrunc, BCLo, Inst->getAlignment());

  Value *HiLShr = IRB.CreateLShr(
      OrigVal, LoWidth, OrigVal->getName() + ".hi.sh");
  Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi");
  Value *HiTrunc = IRB.CreateTrunc(
      HiLShr, HiType, OrigVal->getName() + ".hi");
  Value *BCHi = IRB.CreateBitCast(
        GEPHi,
        HiType->getPointerTo(),
        OrigPtr->getName() + ".hity");

  Value *StoreHi = IRB.CreateStore(HiTrunc, BCHi);

  if (!isLegalSize(Width - LoWidth)) {
    // HiTrunc is still illegal, and is redundant with the truncate in the
    // recursive call, so just get rid of it.
    State.recordConverted(cast<Instruction>(HiTrunc), HiLShr,
                          /*TakeName=*/false);
    StoreHi = splitStore(cast<StoreInst>(StoreHi), State);
    // BCHi was still illegal, and has been replaced with a placeholder in the
    // recursive call. Since it is redundant with BCLo in the recursive call,
    // just splice it out entirely.
    State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false);
  }
  State.recordConverted(Inst, StoreHi, /*TakeName=*/false);
  return StoreHi;
}
Esempio n. 7
0
// Split an illegal load into multiple legal loads and return the resulting
// promoted value. The size of the load is assumed to be a multiple of 8.
static Value *splitLoad(LoadInst *Inst, ConversionState &State) {
  if (Inst->isVolatile() || Inst->isAtomic())
    report_fatal_error("Can't split volatile/atomic loads");
  if (cast<IntegerType>(Inst->getType())->getBitWidth() % 8 != 0)
    report_fatal_error("Loads must be a multiple of 8 bits");

  Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
  // OrigPtr is a placeholder in recursive calls, and so has no name
  if (OrigPtr->getName().empty())
    OrigPtr->setName(Inst->getPointerOperand()->getName());
  unsigned Width = cast<IntegerType>(Inst->getType())->getBitWidth();
  Type *NewType = getPromotedType(Inst->getType());
  unsigned LoWidth = Width;

  while (!isLegalSize(LoWidth)) LoWidth -= 8;
  IntegerType *LoType = IntegerType::get(Inst->getContext(), LoWidth);
  IntegerType *HiType = IntegerType::get(Inst->getContext(), Width - LoWidth);
  IRBuilder<> IRB(Inst->getParent(), Inst);

  Value *BCLo = IRB.CreateBitCast(
      OrigPtr,
      LoType->getPointerTo(),
      OrigPtr->getName() + ".loty");
  Value *LoadLo = IRB.CreateAlignedLoad(
      BCLo, Inst->getAlignment(), Inst->getName() + ".lo");
  Value *LoExt = IRB.CreateZExt(LoadLo, NewType, LoadLo->getName() + ".ext");
  Value *GEPHi = IRB.CreateConstGEP1_32(BCLo, 1, OrigPtr->getName() + ".hi");
  Value *BCHi = IRB.CreateBitCast(
        GEPHi,
        HiType->getPointerTo(),
        OrigPtr->getName() + ".hity");

  Value *LoadHi = IRB.CreateLoad(BCHi, Inst->getName() + ".hi");
  if (!isLegalSize(Width - LoWidth)) {
    LoadHi = splitLoad(cast<LoadInst>(LoadHi), State);
    // BCHi was still illegal, and has been replaced with a placeholder in the
    // recursive call. Since it is redundant with BCLo in the recursive call,
    // just splice it out entirely.
    State.recordConverted(cast<Instruction>(BCHi), GEPHi, /*TakeName=*/false);
  }

  Value *HiExt = IRB.CreateZExt(LoadHi, NewType, LoadHi->getName() + ".ext");
  Value *HiShift = IRB.CreateShl(HiExt, LoWidth, HiExt->getName() + ".sh");
  Value *Result = IRB.CreateOr(LoExt, HiShift);

  State.recordConverted(Inst, Result);

  return Result;
}
static bool isByteSwap64(ShuffleVectorInst &SI, SmallVector<int, 16>&RefMasks)
{

    RefMasks.clear();
    unsigned VWidth = cast<VectorType>(SI.getType())->getNumElements();
    VectorType *LHS = cast<VectorType>(SI.getOperand(0)->getType());
    VectorType *RHS = cast<VectorType>(SI.getOperand(1)->getType());

    IntegerType *IT = dyn_cast<IntegerType>(LHS->getElementType());
    //When Element Type is not IntegerType or the Result's element number
    //can't be divided by 8, return false
    //TODO:Need to check all masks are all constants.
    if (IT == nullptr
        || ! IT->isIntegerTy(8)
        || VWidth % 8 != 0) {
        return false;
    }

    SmallVector<int, 16> Masks(SI.getShuffleMask());
    bool isByteSwap = true;

    for (unsigned i = 0; i < VWidth / 8; ++i) {
        unsigned base = Masks[i * 8];
        if (base % 8 != 7) {
            isByteSwap = false;
            break;
        }

        for (unsigned j = 1; j < 8; ++j) {
            if (base - Masks[i * 8 + j] != j) {
                isByteSwap = false;
                break;
            }
        }

        if (isByteSwap) {
            RefMasks.push_back(base / 8);
        } else {
            break;
        }
    }

    if (!isByteSwap) {
        RefMasks.clear();
    }

    return isByteSwap;
}
Esempio n. 9
0
Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
         "Expression not of type isl_ast_expr_int");
  isl_int Int;
  Value *V;
  APInt APValue;
  IntegerType *T;

  isl_int_init(Int);
  isl_ast_expr_get_int(Expr, &Int);
  APValue = APInt_from_MPZ(Int);
  T = getType(Expr);
  APValue = APValue.sextOrSelf(T->getBitWidth());
  V = ConstantInt::get(T, APValue);

  isl_ast_expr_free(Expr);
  isl_int_clear(Int);
  return V;
}
Esempio n. 10
0
// bypassSlowDivision - This optimization identifies DIV instructions that can
// be profitably bypassed and carried out with a shorter, faster divide.
bool llvm::bypassSlowDivision(Function &F,
                              Function::iterator &I,
                              const DenseMap<unsigned int, unsigned int> &BypassWidths) {
  DivCacheTy DivCache;

  bool MadeChange = false;
  for (BasicBlock::iterator J = I->begin(); J != I->end(); J++) {

    // Get instruction details
    unsigned Opcode = J->getOpcode();
    bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
    bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem;
    bool UseSignedOp = Opcode == Instruction::SDiv ||
                       Opcode == Instruction::SRem;

    // Only optimize div or rem ops
    if (!UseDivOp && !UseRemOp)
      continue;

    // Skip division on vector types, only optimize integer instructions
    if (!J->getType()->isIntegerTy())
      continue;

    // Get bitwidth of div/rem instruction
    IntegerType *T = cast<IntegerType>(J->getType());
    unsigned int bitwidth = T->getBitWidth();

    // Continue if bitwidth is not bypassed
    DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth);
    if (BI == BypassWidths.end())
      continue;

    // Get type for div/rem instruction with bypass bitwidth
    IntegerType *BT = IntegerType::get(J->getContext(), BI->second);

    MadeChange |= reuseOrInsertFastDiv(F, I, J, BT, UseDivOp,
                                       UseSignedOp, DivCache);
  }

  return MadeChange;
}
Esempio n. 11
0
void X86InstrSema::translateDivRem(bool isThreeOperand, bool isSigned) {
  EVT Re2EVT = NextVT();
  assert(Re2EVT == ResEVT && "X86 division result type mismatch!");
  (void)Re2EVT;
  Type *ResType = ResEVT.getTypeForEVT(*Ctx);

  Instruction::CastOps ExtOp;
  Instruction::BinaryOps DivOp, RemOp;
  if (isSigned) {
    ExtOp = Instruction::SExt;
    DivOp = Instruction::SDiv;
    RemOp = Instruction::SRem;
  } else {
    ExtOp = Instruction::ZExt;
    DivOp = Instruction::UDiv;
    RemOp = Instruction::URem;
  }

  Value *Dividend;
  if (isThreeOperand) {
    Value *Op1 = getNextOperand(), *Op2 = getNextOperand();
    IntegerType *HalfType = cast<IntegerType>(ResType);
    unsigned HalfBits = HalfType->getPrimitiveSizeInBits();
    IntegerType *FullType = IntegerType::get(*Ctx, HalfBits * 2);
    Value *DivHi = Builder->CreateCast(Instruction::ZExt, Op1, FullType);
    Value *DivLo = Builder->CreateCast(Instruction::ZExt, Op2, FullType);
    Dividend = Builder->CreateOr(
        Builder->CreateShl(DivHi, ConstantInt::get(FullType, HalfBits)), DivLo);
  } else {
    Dividend = getNextOperand();
  }

  Value *Divisor = getNextOperand();
  Divisor = Builder->CreateCast(ExtOp, Divisor, Dividend->getType());

  registerResult(Builder->CreateTrunc(
                     Builder->CreateBinOp(DivOp, Dividend, Divisor), ResType));
  registerResult(Builder->CreateTrunc(
                     Builder->CreateBinOp(RemOp, Dividend, Divisor), ResType));
}
Esempio n. 12
0
unsigned TypeUtils::getPrimitiveTypeWidth(const Type* type) {
	if (type->isVoidTy()) {
		return 0;
	} else if (type->isFloatTy()) {
		return 32 / 8;
	} else if (type->isDoubleTy()) {
		return 64 / 8;
	} else if (type->isX86_FP80Ty()) {
		return 80 / 8;
	} else if (type->isFP128Ty()) {
		return 128 / 8;
	} else if (type->isPPC_FP128Ty()) {
		return 128 / 8;
	} else if (type->isX86_MMXTy()) {
		return 64 / 8;
	} else if (type->isIntegerTy()) {
		IntegerType* integerTy = (IntegerType*) type;
		return integerTy->getBitWidth() / 8;
	} else {
		assert(0 && "must be a primitive type");
		return -1;
	}
}
Esempio n. 13
0
void TypeDeduction::Visit(BinaryExpression* node)
{
    Type *leftType, *rightType;

    node->GetLeftOperand()->Accept(this);
    node->GetRightOperand()->Accept(this);

    leftType = node->GetLeftOperand()->GetTag<Type>("Type");
    rightType = node->GetRightOperand()->GetTag<Type>("Type");

    Type *targetType = NULL;

    switch (node->GetAction())
    {
        case Expression::Add:
        case Expression::Subtract:
        case Expression::Multiply:
        case Expression::Divide:
        case Expression::Modulo:
            if (typeid(*leftType) == typeid(IntegerType))
            {
                if (typeid(*rightType) == typeid(IntegerType))
                {
                    IntegerType *leftIntType = dynamic_cast<IntegerType *>(leftType);
                    IntegerType *rightIntType = dynamic_cast<IntegerType *>(rightType);
                    targetType = new IntegerType(MAX(leftIntType->GetSize(), rightIntType->GetSize()), leftIntType->IsSigned() || rightIntType->IsSigned());
                    leftType = targetType;
                    rightType = targetType;
                }
                else if (typeid(*rightType) == typeid(FloatingPointType))
                {
                    targetType = rightType;
                    leftType = targetType;
                }
                else
                {
                    targetType = NULL;
                }
            }
            else if (typeid(*leftType) == typeid(FloatingPointType))
            {
                if (typeid(*rightType) == typeid(IntegerType))
                {
                    targetType = leftType;
                    rightType = targetType;
                }
                else if (typeid(*rightType) == typeid(FloatingPointType))
                {
                    FloatingPointType *lt = dynamic_cast<FloatingPointType *>(leftType);
                    FloatingPointType *rt = dynamic_cast<FloatingPointType *>(rightType);
                    targetType = new FloatingPointType(MAX(lt->GetSize(), rt->GetSize()));
                    leftType = targetType;
                    rightType = targetType;
                }
                else
                {
                    targetType = NULL;
                }
            }
            else if (typeid(*leftType) == typeid(PointerType))
            {
                if (typeid(*rightType) == typeid(IntegerType))
                {
                    targetType = leftType;
                }
                else
                {
                    targetType = NULL;
                }
            }
            else
            {
                targetType = NULL;
            }
            break;
        case Expression::LeftShift:
        case Expression::RightShift:
            if (typeid(*leftType) == typeid(IntegerType) && typeid(*rightType) == typeid(IntegerType))
            {
                targetType = leftType;
            }
            else
            {
                targetType = NULL;
            }
            break;
        case Expression::Equal:
        case Expression::NotEqual:
        case Expression::GreaterThan:
        case Expression::GreaterThanOrEqual:
        case Expression::LessThan:
        case Expression::LessThanOrEqual:
            if (typeid(*leftType) == typeid(IntegerType))
            {
                if (typeid(*rightType) == typeid(IntegerType))
                {
                    IntegerType *leftIntType = dynamic_cast<IntegerType *>(leftType);
                    IntegerType *rightIntType = dynamic_cast<IntegerType *>(rightType);
                    leftType = new IntegerType(MAX(leftIntType->GetSize(), rightIntType->GetSize()), leftIntType->IsSigned() || rightIntType->IsSigned());;
                    targetType = new BooleanType();
                }
                else if (typeid(*rightType) == typeid(FloatingPointType))
                {
                    leftType = rightType;
                    targetType = new BooleanType();
                }
                else
                {
                    targetType = NULL;
                }
            }
            else if (typeid(*leftType) == typeid(FloatingPointType))
            {
                if (typeid(*rightType) == typeid(IntegerType))
                {
                    rightType = leftType;
                    targetType = new BooleanType();
                }
                else if (typeid(*rightType) == typeid(FloatingPointType))
                {
                    FloatingPointType *lt = dynamic_cast<FloatingPointType *>(leftType);
                    FloatingPointType *rt = dynamic_cast<FloatingPointType *>(rightType);
                    leftType = rightType = new FloatingPointType(MAX(lt->GetSize(), rt->GetSize()));
                    targetType = new BooleanType();
                }
                else
                {
                    targetType = NULL;
                }
            }
            else if (typeid(*leftType) == typeid(PointerType))
            {
                if (typeid(*rightType) == typeid(PointerType))
                {
                    targetType = new BooleanType();
                }
                else
                {
                    targetType = NULL;
                }
            }
            else
            {
                std::cout << "ERROR: TypeDeduction.cpp @558\n";
                exit(-1);
                targetType = NULL;
            }
            break;
        case Expression::And:
        case Expression::Or:
        case Expression::ExclusiveOr:
            if (typeid(*leftType) == typeid(IntegerType) && typeid(*rightType) == typeid(IntegerType))
            {
                IntegerType *leftIntType = dynamic_cast<IntegerType *>(leftType);
                IntegerType *rightIntType = dynamic_cast<IntegerType *>(rightType);
                targetType = new IntegerType(MAX(leftIntType->GetSize(), rightIntType->GetSize()), leftIntType->IsSigned() || rightIntType->IsSigned());
                leftType = targetType;
                rightType = targetType;
            }
            else if (typeid(*leftType) == typeid(BooleanType) && typeid(*rightType) == typeid(BooleanType))
            {
                targetType = new BooleanType();
            }
            else
            {
                targetType = NULL;
            }
            break;
        case Expression::AndAlso:
        case Expression::OrElse:
            if (typeid(*leftType) == typeid(BooleanType) && typeid(*rightType) == typeid(BooleanType))
            {
                targetType = new BooleanType();
            }
            else
            {
                targetType = NULL;
            }
            break;
        default:
            abort();
    }

    if (targetType == NULL)
    {
        
        CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Type mismatch.");
        return;
    }

    if (!leftType->Equals(node->GetLeftOperand()->GetTag<Type>("Type")))
    {
        node->SetLeftOperand(new ConvertExpression(leftType, node->GetLeftOperand()));
        node->GetLeftOperand()->SetTag<Type>("Type", leftType);
    }

    if (!rightType->Equals(node->GetRightOperand()->GetTag<Type>("Type")))
    {
        node->SetRightOperand(new ConvertExpression(rightType, node->GetRightOperand()));
        node->GetRightOperand()->SetTag<Type>("Type", rightType);
    }

    node->SetTag<Type>("Type", targetType);
}
Esempio n. 14
0
/// Generates code to divide two unsigned scalar 32-bit or 64-bit integers.
/// Returns the quotient, rounded towards 0. Builder's insert point should
/// point where the caller wants code generated, e.g. at the udiv instruction.
static Value *generateUnsignedDivisionCode(Value *Dividend, Value *Divisor,
                                           IRBuilder<> &Builder) {
  // The basic algorithm can be found in the compiler-rt project's
  // implementation of __udivsi3.c. Here, we do a lower-level IR based approach
  // that's been hand-tuned to lessen the amount of control flow involved.

  // Some helper values
  IntegerType *DivTy = cast<IntegerType>(Dividend->getType());
  unsigned BitWidth = DivTy->getBitWidth();

  ConstantInt *Zero;
  ConstantInt *One;
  ConstantInt *NegOne;
  ConstantInt *MSB;

  if (BitWidth == 64) {
    Zero      = Builder.getInt64(0);
    One       = Builder.getInt64(1);
    NegOne    = ConstantInt::getSigned(DivTy, -1);
    MSB       = Builder.getInt64(63);
  } else {
    assert(BitWidth == 32 && "Unexpected bit width");
    Zero      = Builder.getInt32(0);
    One       = Builder.getInt32(1);
    NegOne    = ConstantInt::getSigned(DivTy, -1);
    MSB       = Builder.getInt32(31);
  }

  ConstantInt *True = Builder.getTrue();

  BasicBlock *IBB = Builder.GetInsertBlock();
  Function *F = IBB->getParent();
  Function *CTLZ = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
                                             DivTy);

  // Our CFG is going to look like:
  // +---------------------+
  // | special-cases       |
  // |   ...               |
  // +---------------------+
  //  |       |
  //  |   +----------+
  //  |   |  bb1     |
  //  |   |  ...     |
  //  |   +----------+
  //  |    |      |
  //  |    |  +------------+
  //  |    |  |  preheader |
  //  |    |  |  ...       |
  //  |    |  +------------+
  //  |    |      |
  //  |    |      |      +---+
  //  |    |      |      |   |
  //  |    |  +------------+ |
  //  |    |  |  do-while  | |
  //  |    |  |  ...       | |
  //  |    |  +------------+ |
  //  |    |      |      |   |
  //  |   +-----------+  +---+
  //  |   | loop-exit |
  //  |   |  ...      |
  //  |   +-----------+
  //  |     |
  // +-------+
  // | ...   |
  // | end   |
  // +-------+
  BasicBlock *SpecialCases = Builder.GetInsertBlock();
  SpecialCases->setName(Twine(SpecialCases->getName(), "_udiv-special-cases"));
  BasicBlock *End = SpecialCases->splitBasicBlock(Builder.GetInsertPoint(),
                                                  "udiv-end");
  BasicBlock *LoopExit  = BasicBlock::Create(Builder.getContext(),
                                             "udiv-loop-exit", F, End);
  BasicBlock *DoWhile   = BasicBlock::Create(Builder.getContext(),
                                             "udiv-do-while", F, End);
  BasicBlock *Preheader = BasicBlock::Create(Builder.getContext(),
                                             "udiv-preheader", F, End);
  BasicBlock *BB1       = BasicBlock::Create(Builder.getContext(),
                                             "udiv-bb1", F, End);

  // We'll be overwriting the terminator to insert our extra blocks
  SpecialCases->getTerminator()->eraseFromParent();

  // Same instructions are generated for both i32 (msb 31) and i64 (msb 63).

  // First off, check for special cases: dividend or divisor is zero, divisor
  // is greater than dividend, and divisor is 1.
  // ; special-cases:
  // ;   %ret0_1      = icmp eq i32 %divisor, 0
  // ;   %ret0_2      = icmp eq i32 %dividend, 0
  // ;   %ret0_3      = or i1 %ret0_1, %ret0_2
  // ;   %tmp0        = tail call i32 @llvm.ctlz.i32(i32 %divisor, i1 true)
  // ;   %tmp1        = tail call i32 @llvm.ctlz.i32(i32 %dividend, i1 true)
  // ;   %sr          = sub nsw i32 %tmp0, %tmp1
  // ;   %ret0_4      = icmp ugt i32 %sr, 31
  // ;   %ret0        = or i1 %ret0_3, %ret0_4
  // ;   %retDividend = icmp eq i32 %sr, 31
  // ;   %retVal      = select i1 %ret0, i32 0, i32 %dividend
  // ;   %earlyRet    = or i1 %ret0, %retDividend
  // ;   br i1 %earlyRet, label %end, label %bb1
  Builder.SetInsertPoint(SpecialCases);
  Value *Ret0_1      = Builder.CreateICmpEQ(Divisor, Zero);
  Value *Ret0_2      = Builder.CreateICmpEQ(Dividend, Zero);
  Value *Ret0_3      = Builder.CreateOr(Ret0_1, Ret0_2);
  Value *Tmp0 = Builder.CreateCall(CTLZ, {Divisor, True});
  Value *Tmp1 = Builder.CreateCall(CTLZ, {Dividend, True});
  Value *SR          = Builder.CreateSub(Tmp0, Tmp1);
  Value *Ret0_4      = Builder.CreateICmpUGT(SR, MSB);
  Value *Ret0        = Builder.CreateOr(Ret0_3, Ret0_4);
  Value *RetDividend = Builder.CreateICmpEQ(SR, MSB);
  Value *RetVal      = Builder.CreateSelect(Ret0, Zero, Dividend);
  Value *EarlyRet    = Builder.CreateOr(Ret0, RetDividend);
  Builder.CreateCondBr(EarlyRet, End, BB1);

  // ; bb1:                                             ; preds = %special-cases
  // ;   %sr_1     = add i32 %sr, 1
  // ;   %tmp2     = sub i32 31, %sr
  // ;   %q        = shl i32 %dividend, %tmp2
  // ;   %skipLoop = icmp eq i32 %sr_1, 0
  // ;   br i1 %skipLoop, label %loop-exit, label %preheader
  Builder.SetInsertPoint(BB1);
  Value *SR_1     = Builder.CreateAdd(SR, One);
  Value *Tmp2     = Builder.CreateSub(MSB, SR);
  Value *Q        = Builder.CreateShl(Dividend, Tmp2);
  Value *SkipLoop = Builder.CreateICmpEQ(SR_1, Zero);
  Builder.CreateCondBr(SkipLoop, LoopExit, Preheader);

  // ; preheader:                                           ; preds = %bb1
  // ;   %tmp3 = lshr i32 %dividend, %sr_1
  // ;   %tmp4 = add i32 %divisor, -1
  // ;   br label %do-while
  Builder.SetInsertPoint(Preheader);
  Value *Tmp3 = Builder.CreateLShr(Dividend, SR_1);
  Value *Tmp4 = Builder.CreateAdd(Divisor, NegOne);
  Builder.CreateBr(DoWhile);

  // ; do-while:                                 ; preds = %do-while, %preheader
  // ;   %carry_1 = phi i32 [ 0, %preheader ], [ %carry, %do-while ]
  // ;   %sr_3    = phi i32 [ %sr_1, %preheader ], [ %sr_2, %do-while ]
  // ;   %r_1     = phi i32 [ %tmp3, %preheader ], [ %r, %do-while ]
  // ;   %q_2     = phi i32 [ %q, %preheader ], [ %q_1, %do-while ]
  // ;   %tmp5  = shl i32 %r_1, 1
  // ;   %tmp6  = lshr i32 %q_2, 31
  // ;   %tmp7  = or i32 %tmp5, %tmp6
  // ;   %tmp8  = shl i32 %q_2, 1
  // ;   %q_1   = or i32 %carry_1, %tmp8
  // ;   %tmp9  = sub i32 %tmp4, %tmp7
  // ;   %tmp10 = ashr i32 %tmp9, 31
  // ;   %carry = and i32 %tmp10, 1
  // ;   %tmp11 = and i32 %tmp10, %divisor
  // ;   %r     = sub i32 %tmp7, %tmp11
  // ;   %sr_2  = add i32 %sr_3, -1
  // ;   %tmp12 = icmp eq i32 %sr_2, 0
  // ;   br i1 %tmp12, label %loop-exit, label %do-while
  Builder.SetInsertPoint(DoWhile);
  PHINode *Carry_1 = Builder.CreatePHI(DivTy, 2);
  PHINode *SR_3    = Builder.CreatePHI(DivTy, 2);
  PHINode *R_1     = Builder.CreatePHI(DivTy, 2);
  PHINode *Q_2     = Builder.CreatePHI(DivTy, 2);
  Value *Tmp5  = Builder.CreateShl(R_1, One);
  Value *Tmp6  = Builder.CreateLShr(Q_2, MSB);
  Value *Tmp7  = Builder.CreateOr(Tmp5, Tmp6);
  Value *Tmp8  = Builder.CreateShl(Q_2, One);
  Value *Q_1   = Builder.CreateOr(Carry_1, Tmp8);
  Value *Tmp9  = Builder.CreateSub(Tmp4, Tmp7);
  Value *Tmp10 = Builder.CreateAShr(Tmp9, MSB);
  Value *Carry = Builder.CreateAnd(Tmp10, One);
  Value *Tmp11 = Builder.CreateAnd(Tmp10, Divisor);
  Value *R     = Builder.CreateSub(Tmp7, Tmp11);
  Value *SR_2  = Builder.CreateAdd(SR_3, NegOne);
  Value *Tmp12 = Builder.CreateICmpEQ(SR_2, Zero);
  Builder.CreateCondBr(Tmp12, LoopExit, DoWhile);

  // ; loop-exit:                                      ; preds = %do-while, %bb1
  // ;   %carry_2 = phi i32 [ 0, %bb1 ], [ %carry, %do-while ]
  // ;   %q_3     = phi i32 [ %q, %bb1 ], [ %q_1, %do-while ]
  // ;   %tmp13 = shl i32 %q_3, 1
  // ;   %q_4   = or i32 %carry_2, %tmp13
  // ;   br label %end
  Builder.SetInsertPoint(LoopExit);
  PHINode *Carry_2 = Builder.CreatePHI(DivTy, 2);
  PHINode *Q_3     = Builder.CreatePHI(DivTy, 2);
  Value *Tmp13 = Builder.CreateShl(Q_3, One);
  Value *Q_4   = Builder.CreateOr(Carry_2, Tmp13);
  Builder.CreateBr(End);

  // ; end:                                 ; preds = %loop-exit, %special-cases
  // ;   %q_5 = phi i32 [ %q_4, %loop-exit ], [ %retVal, %special-cases ]
  // ;   ret i32 %q_5
  Builder.SetInsertPoint(End, End->begin());
  PHINode *Q_5 = Builder.CreatePHI(DivTy, 2);

  // Populate the Phis, since all values have now been created. Our Phis were:
  // ;   %carry_1 = phi i32 [ 0, %preheader ], [ %carry, %do-while ]
  Carry_1->addIncoming(Zero, Preheader);
  Carry_1->addIncoming(Carry, DoWhile);
  // ;   %sr_3 = phi i32 [ %sr_1, %preheader ], [ %sr_2, %do-while ]
  SR_3->addIncoming(SR_1, Preheader);
  SR_3->addIncoming(SR_2, DoWhile);
  // ;   %r_1 = phi i32 [ %tmp3, %preheader ], [ %r, %do-while ]
  R_1->addIncoming(Tmp3, Preheader);
  R_1->addIncoming(R, DoWhile);
  // ;   %q_2 = phi i32 [ %q, %preheader ], [ %q_1, %do-while ]
  Q_2->addIncoming(Q, Preheader);
  Q_2->addIncoming(Q_1, DoWhile);
  // ;   %carry_2 = phi i32 [ 0, %bb1 ], [ %carry, %do-while ]
  Carry_2->addIncoming(Zero, BB1);
  Carry_2->addIncoming(Carry, DoWhile);
  // ;   %q_3 = phi i32 [ %q, %bb1 ], [ %q_1, %do-while ]
  Q_3->addIncoming(Q, BB1);
  Q_3->addIncoming(Q_1, DoWhile);
  // ;   %q_5 = phi i32 [ %q_4, %loop-exit ], [ %retVal, %special-cases ]
  Q_5->addIncoming(Q_4, LoopExit);
  Q_5->addIncoming(RetVal, SpecialCases);

  return Q_5;
}
Esempio n. 15
0
bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV,
                                                      Instruction *BBI,
                                                      BasicBlock *BB) {
  // Figure out the range of the LHS.  If that fails, bail.
  if (!hasBlockValue(BBI->getOperand(0), BB)) {
    BlockValueStack.push(std::make_pair(BB, BBI->getOperand(0)));
    return false;
  }

  LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB);
  if (!LHSVal.isConstantRange()) {
    BBLV.markOverdefined();
    return true;
  }
  
  ConstantRange LHSRange = LHSVal.getConstantRange();
  ConstantRange RHSRange(1);
  IntegerType *ResultTy = cast<IntegerType>(BBI->getType());
  if (isa<BinaryOperator>(BBI)) {
    if (ConstantInt *RHS = dyn_cast<ConstantInt>(BBI->getOperand(1))) {
      RHSRange = ConstantRange(RHS->getValue());
    } else {
      BBLV.markOverdefined();
      return true;
    }
  }

  // NOTE: We're currently limited by the set of operations that ConstantRange
  // can evaluate symbolically.  Enhancing that set will allows us to analyze
  // more definitions.
  LVILatticeVal Result;
  switch (BBI->getOpcode()) {
  case Instruction::Add:
    Result.markConstantRange(LHSRange.add(RHSRange));
    break;
  case Instruction::Sub:
    Result.markConstantRange(LHSRange.sub(RHSRange));
    break;
  case Instruction::Mul:
    Result.markConstantRange(LHSRange.multiply(RHSRange));
    break;
  case Instruction::UDiv:
    Result.markConstantRange(LHSRange.udiv(RHSRange));
    break;
  case Instruction::Shl:
    Result.markConstantRange(LHSRange.shl(RHSRange));
    break;
  case Instruction::LShr:
    Result.markConstantRange(LHSRange.lshr(RHSRange));
    break;
  case Instruction::Trunc:
    Result.markConstantRange(LHSRange.truncate(ResultTy->getBitWidth()));
    break;
  case Instruction::SExt:
    Result.markConstantRange(LHSRange.signExtend(ResultTy->getBitWidth()));
    break;
  case Instruction::ZExt:
    Result.markConstantRange(LHSRange.zeroExtend(ResultTy->getBitWidth()));
    break;
  case Instruction::BitCast:
    Result.markConstantRange(LHSRange);
    break;
  case Instruction::And:
    Result.markConstantRange(LHSRange.binaryAnd(RHSRange));
    break;
  case Instruction::Or:
    Result.markConstantRange(LHSRange.binaryOr(RHSRange));
    break;
  
  // Unhandled instructions are overdefined.
  default:
    DEBUG(dbgs() << " compute BB '" << BB->getName()
                 << "' - overdefined because inst def found.\n");
    Result.markOverdefined();
    break;
  }
  
  BBLV = Result;
  return true;
}
Esempio n. 16
0
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
  bool Changed = SimplifyAssociativeOrCommutative(I);
  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

  if (Value *V = SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(),
                                 I.hasNoUnsignedWrap(), TD))
    return ReplaceInstUsesWith(I, V);

  // (A*B)+(A*C) -> A*(B+C) etc
  if (Value *V = SimplifyUsingDistributiveLaws(I))
    return ReplaceInstUsesWith(I, V);

  if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
    // X + (signbit) --> X ^ signbit
    const APInt &Val = CI->getValue();
    if (Val.isSignBit())
      return BinaryOperator::CreateXor(LHS, RHS);
    
    // See if SimplifyDemandedBits can simplify this.  This handles stuff like
    // (X & 254)+1 -> (X&254)|1
    if (SimplifyDemandedInstructionBits(I))
      return &I;

    // zext(bool) + C -> bool ? C + 1 : C
    if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS))
      if (ZI->getSrcTy()->isIntegerTy(1))
        return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI);
    
    Value *XorLHS = 0; ConstantInt *XorRHS = 0;
    if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {
      uint32_t TySizeBits = I.getType()->getScalarSizeInBits();
      const APInt &RHSVal = CI->getValue();
      unsigned ExtendAmt = 0;
      // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
      // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
      if (XorRHS->getValue() == -RHSVal) {
        if (RHSVal.isPowerOf2())
          ExtendAmt = TySizeBits - RHSVal.logBase2() - 1;
        else if (XorRHS->getValue().isPowerOf2())
          ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1;
      }
      
      if (ExtendAmt) {
        APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt);
        if (!MaskedValueIsZero(XorLHS, Mask))
          ExtendAmt = 0;
      }
      
      if (ExtendAmt) {
        Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt);
        Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext");
        return BinaryOperator::CreateAShr(NewShl, ShAmt);
      }

      // If this is a xor that was canonicalized from a sub, turn it back into
      // a sub and fuse this add with it.
      if (LHS->hasOneUse() && (XorRHS->getValue()+1).isPowerOf2()) {
        IntegerType *IT = cast<IntegerType>(I.getType());
        APInt Mask = APInt::getAllOnesValue(IT->getBitWidth());
        APInt LHSKnownOne(IT->getBitWidth(), 0);
        APInt LHSKnownZero(IT->getBitWidth(), 0);
        ComputeMaskedBits(XorLHS, Mask, LHSKnownZero, LHSKnownOne);
        if ((XorRHS->getValue() | LHSKnownZero).isAllOnesValue())
          return BinaryOperator::CreateSub(ConstantExpr::getAdd(XorRHS, CI),
                                           XorLHS);
      }
    }
  }

  if (isa<Constant>(RHS) && isa<PHINode>(LHS))
    if (Instruction *NV = FoldOpIntoPhi(I))
      return NV;

  if (I.getType()->isIntegerTy(1))
    return BinaryOperator::CreateXor(LHS, RHS);

  // X + X --> X << 1
  if (LHS == RHS) {
    BinaryOperator *New =
      BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1));
    New->setHasNoSignedWrap(I.hasNoSignedWrap());
    New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
    return New;
  }

  // -A + B  -->  B - A
  // -A + -B  -->  -(A + B)
  if (Value *LHSV = dyn_castNegVal(LHS)) {
    if (Value *RHSV = dyn_castNegVal(RHS)) {
      Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum");
      return BinaryOperator::CreateNeg(NewAdd);
    }
    
    return BinaryOperator::CreateSub(RHS, LHSV);
  }

  // A + -B  -->  A - B
  if (!isa<Constant>(RHS))
    if (Value *V = dyn_castNegVal(RHS))
      return BinaryOperator::CreateSub(LHS, V);


  ConstantInt *C2;
  if (Value *X = dyn_castFoldableMul(LHS, C2)) {
    if (X == RHS)   // X*C + X --> X * (C+1)
      return BinaryOperator::CreateMul(RHS, AddOne(C2));

    // X*C1 + X*C2 --> X * (C1+C2)
    ConstantInt *C1;
    if (X == dyn_castFoldableMul(RHS, C1))
      return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2));
  }

  // X + X*C --> X * (C+1)
  if (dyn_castFoldableMul(RHS, C2) == LHS)
    return BinaryOperator::CreateMul(LHS, AddOne(C2));

  // A+B --> A|B iff A and B have no bits set in common.
  if (IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
    APInt Mask = APInt::getAllOnesValue(IT->getBitWidth());
    APInt LHSKnownOne(IT->getBitWidth(), 0);
    APInt LHSKnownZero(IT->getBitWidth(), 0);
    ComputeMaskedBits(LHS, Mask, LHSKnownZero, LHSKnownOne);
    if (LHSKnownZero != 0) {
      APInt RHSKnownOne(IT->getBitWidth(), 0);
      APInt RHSKnownZero(IT->getBitWidth(), 0);
      ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne);
      
      // No bits in common -> bitwise or.
      if ((LHSKnownZero|RHSKnownZero).isAllOnesValue())
        return BinaryOperator::CreateOr(LHS, RHS);
    }
  }

  // W*X + Y*Z --> W * (X+Z)  iff W == Y
  {
    Value *W, *X, *Y, *Z;
    if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&
        match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) {
      if (W != Y) {
        if (W == Z) {
          std::swap(Y, Z);
        } else if (Y == X) {
          std::swap(W, X);
        } else if (X == Z) {
          std::swap(Y, Z);
          std::swap(W, X);
        }
      }

      if (W == Y) {
        Value *NewAdd = Builder->CreateAdd(X, Z, LHS->getName());
        return BinaryOperator::CreateMul(W, NewAdd);
      }
    }
  }

  if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
    Value *X = 0;
    if (match(LHS, m_Not(m_Value(X))))    // ~X + C --> (C-1) - X
      return BinaryOperator::CreateSub(SubOne(CRHS), X);

    // (X & FF00) + xx00  -> (X+xx00) & FF00
    if (LHS->hasOneUse() &&
        match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) &&
        CRHS->getValue() == (CRHS->getValue() & C2->getValue())) {
      // See if all bits from the first bit set in the Add RHS up are included
      // in the mask.  First, get the rightmost bit.
      const APInt &AddRHSV = CRHS->getValue();
      
      // Form a mask of all bits from the lowest bit added through the top.
      APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));

      // See if the and mask includes all of these bits.
      APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue());

      if (AddRHSHighBits == AddRHSHighBitsAnd) {
        // Okay, the xform is safe.  Insert the new add pronto.
        Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->getName());
        return BinaryOperator::CreateAnd(NewAdd, C2);
      }
    }

    // Try to fold constant add into select arguments.
    if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
      if (Instruction *R = FoldOpIntoSelect(I, SI))
        return R;
  }

  // add (select X 0 (sub n A)) A  -->  select X A n
  {
    SelectInst *SI = dyn_cast<SelectInst>(LHS);
    Value *A = RHS;
    if (!SI) {
      SI = dyn_cast<SelectInst>(RHS);
      A = LHS;
    }
    if (SI && SI->hasOneUse()) {
      Value *TV = SI->getTrueValue();
      Value *FV = SI->getFalseValue();
      Value *N;

      // Can we fold the add into the argument of the select?
      // We check both true and false select arguments for a matching subtract.
      if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A))))
        // Fold the add into the true select value.
        return SelectInst::Create(SI->getCondition(), N, A);
      
      if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A))))
        // Fold the add into the false select value.
        return SelectInst::Create(SI->getCondition(), A, N);
    }
  }

  // Check for (add (sext x), y), see if we can merge this into an
  // integer add followed by a sext.
  if (SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
    // (add (sext x), cst) --> (sext (add x, cst'))
    if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
      Constant *CI = 
        ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType());
      if (LHSConv->hasOneUse() &&
          ConstantExpr::getSExt(CI, I.getType()) == RHSC &&
          WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) {
        // Insert the new, smaller add.
        Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), 
                                              CI, "addconv");
        return new SExtInst(NewAdd, I.getType());
      }
    }
    
    // (add (sext x), (sext y)) --> (sext (add int x, y))
    if (SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) {
      // Only do this if x/y have the same type, if at last one of them has a
      // single use (so we don't increase the number of sexts), and if the
      // integer add will not overflow.
      if (LHSConv->getOperand(0)->getType()==RHSConv->getOperand(0)->getType()&&
          (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
          WillNotOverflowSignedAdd(LHSConv->getOperand(0),
                                   RHSConv->getOperand(0))) {
        // Insert the new integer add.
        Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), 
                                             RHSConv->getOperand(0), "addconv");
        return new SExtInst(NewAdd, I.getType());
      }
    }
  }

  return Changed ? &I : 0;
}
Esempio n. 17
0
/// visitSelectInstWithICmp - Visit a SelectInst that has an
/// ICmpInst as its first operand.
///
Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
                                                   ICmpInst *ICI) {
  bool Changed = false;
  ICmpInst::Predicate Pred = ICI->getPredicate();
  Value *CmpLHS = ICI->getOperand(0);
  Value *CmpRHS = ICI->getOperand(1);
  Value *TrueVal = SI.getTrueValue();
  Value *FalseVal = SI.getFalseValue();

  // Check cases where the comparison is with a constant that
  // can be adjusted to fit the min/max idiom. We may move or edit ICI
  // here, so make sure the select is the only user.
  if (ICI->hasOneUse())
    if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) {
      // X < MIN ? T : F  -->  F
      if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT)
          && CI->isMinValue(Pred == ICmpInst::ICMP_SLT))
        return ReplaceInstUsesWith(SI, FalseVal);
      // X > MAX ? T : F  -->  F
      else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT)
               && CI->isMaxValue(Pred == ICmpInst::ICMP_SGT))
        return ReplaceInstUsesWith(SI, FalseVal);
      switch (Pred) {
      default: break;
      case ICmpInst::ICMP_ULT:
      case ICmpInst::ICMP_SLT:
      case ICmpInst::ICMP_UGT:
      case ICmpInst::ICMP_SGT: {
        // These transformations only work for selects over integers.
        IntegerType *SelectTy = dyn_cast<IntegerType>(SI.getType());
        if (!SelectTy)
          break;

        Constant *AdjustedRHS;
        if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT)
          AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1);
        else // (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT)
          AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() - 1);

        // X > C ? X : C+1  -->  X < C+1 ? C+1 : X
        // X < C ? X : C-1  -->  X > C-1 ? C-1 : X
        if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) ||
            (CmpLHS == FalseVal && AdjustedRHS == TrueVal))
          ; // Nothing to do here. Values match without any sign/zero extension.

        // Types do not match. Instead of calculating this with mixed types
        // promote all to the larger type. This enables scalar evolution to
        // analyze this expression.
        else if (CmpRHS->getType()->getScalarSizeInBits()
                 < SelectTy->getBitWidth()) {
          Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, SelectTy);

          // X = sext x; x >s c ? X : C+1 --> X = sext x; X <s C+1 ? C+1 : X
          // X = sext x; x <s c ? X : C-1 --> X = sext x; X >s C-1 ? C-1 : X
          // X = sext x; x >u c ? X : C+1 --> X = sext x; X <u C+1 ? C+1 : X
          // X = sext x; x <u c ? X : C-1 --> X = sext x; X >u C-1 ? C-1 : X
          if (match(TrueVal, m_SExt(m_Specific(CmpLHS))) &&
                sextRHS == FalseVal) {
            CmpLHS = TrueVal;
            AdjustedRHS = sextRHS;
          } else if (match(FalseVal, m_SExt(m_Specific(CmpLHS))) &&
                     sextRHS == TrueVal) {
            CmpLHS = FalseVal;
            AdjustedRHS = sextRHS;
          } else if (ICI->isUnsigned()) {
            Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, SelectTy);
            // X = zext x; x >u c ? X : C+1 --> X = zext x; X <u C+1 ? C+1 : X
            // X = zext x; x <u c ? X : C-1 --> X = zext x; X >u C-1 ? C-1 : X
            // zext + signed compare cannot be changed:
            //    0xff <s 0x00, but 0x00ff >s 0x0000
            if (match(TrueVal, m_ZExt(m_Specific(CmpLHS))) &&
                zextRHS == FalseVal) {
              CmpLHS = TrueVal;
              AdjustedRHS = zextRHS;
            } else if (match(FalseVal, m_ZExt(m_Specific(CmpLHS))) &&
                       zextRHS == TrueVal) {
              CmpLHS = FalseVal;
              AdjustedRHS = zextRHS;
            } else
              break;
          } else
            break;
        } else
          break;

        Pred = ICmpInst::getSwappedPredicate(Pred);
        CmpRHS = AdjustedRHS;
        std::swap(FalseVal, TrueVal);
        ICI->setPredicate(Pred);
        ICI->setOperand(0, CmpLHS);
        ICI->setOperand(1, CmpRHS);
        SI.setOperand(1, TrueVal);
        SI.setOperand(2, FalseVal);

        // Move ICI instruction right before the select instruction. Otherwise
        // the sext/zext value may be defined after the ICI instruction uses it.
        ICI->moveBefore(&SI);

        Changed = true;
        break;
      }
      }
    }

  // Transform (X >s -1) ? C1 : C2 --> ((X >>s 31) & (C2 - C1)) + C1
  // and       (X <s  0) ? C2 : C1 --> ((X >>s 31) & (C2 - C1)) + C1
  // FIXME: Type and constness constraints could be lifted, but we have to
  //        watch code size carefully. We should consider xor instead of
  //        sub/add when we decide to do that.
  if (IntegerType *Ty = dyn_cast<IntegerType>(CmpLHS->getType())) {
    if (TrueVal->getType() == Ty) {
      if (ConstantInt *Cmp = dyn_cast<ConstantInt>(CmpRHS)) {
        ConstantInt *C1 = nullptr, *C2 = nullptr;
        if (Pred == ICmpInst::ICMP_SGT && Cmp->isAllOnesValue()) {
          C1 = dyn_cast<ConstantInt>(TrueVal);
          C2 = dyn_cast<ConstantInt>(FalseVal);
        } else if (Pred == ICmpInst::ICMP_SLT && Cmp->isNullValue()) {
          C1 = dyn_cast<ConstantInt>(FalseVal);
          C2 = dyn_cast<ConstantInt>(TrueVal);
        }
        if (C1 && C2) {
          // This shift results in either -1 or 0.
          Value *AShr = Builder->CreateAShr(CmpLHS, Ty->getBitWidth()-1);

          // Check if we can express the operation with a single or.
          if (C2->isAllOnesValue())
            return ReplaceInstUsesWith(SI, Builder->CreateOr(AShr, C1));

          Value *And = Builder->CreateAnd(AShr, C2->getValue()-C1->getValue());
          return ReplaceInstUsesWith(SI, Builder->CreateAdd(And, C1));
        }
      }
    }
  }

  // If we have an equality comparison then we know the value in one of the
  // arms of the select. See if substituting this value into the arm and
  // simplifying the result yields the same value as the other arm.
  if (Pred == ICmpInst::ICMP_EQ) {
    if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
            TrueVal ||
        SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
            TrueVal)
      return ReplaceInstUsesWith(SI, FalseVal);
    if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
            FalseVal ||
        SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
            FalseVal)
      return ReplaceInstUsesWith(SI, FalseVal);
  } else if (Pred == ICmpInst::ICMP_NE) {
    if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
            FalseVal ||
        SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
            FalseVal)
      return ReplaceInstUsesWith(SI, TrueVal);
    if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
            TrueVal ||
        SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
            TrueVal)
      return ReplaceInstUsesWith(SI, TrueVal);
  }

  // NOTE: if we wanted to, this is where to detect integer MIN/MAX

  if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
    if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
      // Transform (X == C) ? X : Y -> (X == C) ? C : Y
      SI.setOperand(1, CmpRHS);
      Changed = true;
    } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
      // Transform (X != C) ? Y : X -> (X != C) ? Y : C
      SI.setOperand(2, CmpRHS);
      Changed = true;
    }
  }

  if (unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits()) {
    APInt MinSignedValue = APInt::getSignBit(BitWidth);
    Value *X;
    const APInt *Y, *C;
    bool TrueWhenUnset;
    bool IsBitTest = false;
    if (ICmpInst::isEquality(Pred) &&
        match(CmpLHS, m_And(m_Value(X), m_Power2(Y))) &&
        match(CmpRHS, m_Zero())) {
      IsBitTest = true;
      TrueWhenUnset = Pred == ICmpInst::ICMP_EQ;
    } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
      X = CmpLHS;
      Y = &MinSignedValue;
      IsBitTest = true;
      TrueWhenUnset = false;
    } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
      X = CmpLHS;
      Y = &MinSignedValue;
      IsBitTest = true;
      TrueWhenUnset = true;
    }
    if (IsBitTest) {
      Value *V = nullptr;
      // (X & Y) == 0 ? X : X ^ Y  --> X & ~Y
      if (TrueWhenUnset && TrueVal == X &&
          match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
        V = Builder->CreateAnd(X, ~(*Y));
      // (X & Y) != 0 ? X ^ Y : X  --> X & ~Y
      else if (!TrueWhenUnset && FalseVal == X &&
               match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
        V = Builder->CreateAnd(X, ~(*Y));
      // (X & Y) == 0 ? X ^ Y : X  --> X | Y
      else if (TrueWhenUnset && FalseVal == X &&
               match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
        V = Builder->CreateOr(X, *Y);
      // (X & Y) != 0 ? X : X ^ Y  --> X | Y
      else if (!TrueWhenUnset && TrueVal == X &&
               match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
        V = Builder->CreateOr(X, *Y);

      if (V)
        return ReplaceInstUsesWith(SI, V);
    }
  }

  if (Value *V = foldSelectICmpAndOr(SI, TrueVal, FalseVal, Builder))
    return ReplaceInstUsesWith(SI, V);

  return Changed ? &SI : nullptr;
}