Logo Search packages:      
Sourcecode: llvm version File versions  Download package

Constant * llvm::ConstantFoldCastInstruction ( unsigned  opc,
const Constant V,
const Type DestTy 
)

Parameters:
opcode  The opcode of the cast
V  The source constant
DestTy  The destination type

Definition at line 171 of file ConstantFold.cpp.

References llvm::ConstantPointerNull::get(), llvm::ConstantVector::get(), llvm::ConstantInt::get(), llvm::ConstantFP::get(), llvm::UndefValue::get(), llvm::ConstantExpr::getCast(), llvm::SequentialType::getElementType(), llvm::Constant::getNullValue(), llvm::VectorType::getNumElements(), llvm::Constant::getOperand(), llvm::ConstantExpr::getPointerCast(), llvm::Type::getPrimitiveSizeInBits(), llvm::APInt::getRawData(), llvm::ConstantVector::getType(), llvm::Value::getType(), llvm::ConstantInt::getValue(), and llvm::Constant::isNullValue().

                                                                {
  const Type *SrcTy = V->getType();

  if (isa<UndefValue>(V)) {
    // zext(undef) = 0, because the top bits will be zero.
    // sext(undef) = 0, because the top bits will all be the same.
    if (opc == Instruction::ZExt || opc == Instruction::SExt)
      return Constant::getNullValue(DestTy);
    return UndefValue::get(DestTy);
  }
  // No compile-time operations on this type yet.
  if (V->getType() == Type::PPC_FP128Ty || DestTy == Type::PPC_FP128Ty)
    return 0;

  // If the cast operand is a constant expression, there's a few things we can
  // do to try to simplify it.
  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->isCast()) {
      // Try hard to fold cast of cast because they are often eliminable.
      if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy))
        return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy);
    } else if (CE->getOpcode() == Instruction::GetElementPtr) {
      // If all of the indexes in the GEP are null values, there is no pointer
      // adjustment going on.  We might as well cast the source pointer.
      bool isAllNull = true;
      for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
        if (!CE->getOperand(i)->isNullValue()) {
          isAllNull = false;
          break;
        }
      if (isAllNull)
        // This is casting one pointer type to another, always BitCast
        return ConstantExpr::getPointerCast(CE->getOperand(0), DestTy);
    }
  }

  // We actually have to do a cast now. Perform the cast according to the
  // opcode specified.
  switch (opc) {
  case Instruction::FPTrunc:
  case Instruction::FPExt:
    if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
      APFloat Val = FPC->getValueAPF();
      Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle :
                  DestTy == Type::DoubleTy ? APFloat::IEEEdouble :
                  DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended :
                  DestTy == Type::FP128Ty ? APFloat::IEEEquad :
                  APFloat::Bogus,
                  APFloat::rmNearestTiesToEven);
      return ConstantFP::get(DestTy, Val);
    }
    return 0; // Can't fold.
  case Instruction::FPToUI: 
  case Instruction::FPToSI:
    if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
      const APFloat &V = FPC->getValueAPF();
      uint64_t x[2]; 
      uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
      (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
                                APFloat::rmTowardZero);
      APInt Val(DestBitWidth, 2, x);
      return ConstantInt::get(Val);
    }
    if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
      std::vector<Constant*> res;
      const VectorType *DestVecTy = cast<VectorType>(DestTy);
      const Type *DstEltTy = DestVecTy->getElementType();
      for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
        res.push_back(ConstantFoldCastInstruction(opc, V->getOperand(i),
                                                  DstEltTy));
      return ConstantVector::get(DestVecTy, res);
    }
    return 0; // Can't fold.
  case Instruction::IntToPtr:   //always treated as unsigned
    if (V->isNullValue())       // Is it an integral null value?
      return ConstantPointerNull::get(cast<PointerType>(DestTy));
    return 0;                   // Other pointer types cannot be casted
  case Instruction::PtrToInt:   // always treated as unsigned
    if (V->isNullValue())       // is it a null pointer value?
      return ConstantInt::get(DestTy, 0);
    return 0;                   // Other pointer types cannot be casted
  case Instruction::UIToFP:
  case Instruction::SIToFP:
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      APInt api = CI->getValue();
      const uint64_t zero[] = {0, 0};
      uint32_t BitWidth = cast<IntegerType>(SrcTy)->getBitWidth();
      APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(),
                                  2, zero));
      (void)apf.convertFromZeroExtendedInteger(api.getRawData(), BitWidth, 
                                   opc==Instruction::SIToFP,
                                   APFloat::rmNearestTiesToEven);
      return ConstantFP::get(DestTy, apf);
    }
    if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
      std::vector<Constant*> res;
      const VectorType *DestVecTy = cast<VectorType>(DestTy);
      const Type *DstEltTy = DestVecTy->getElementType();
      for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
        res.push_back(ConstantFoldCastInstruction(opc, V->getOperand(i),
                                                  DstEltTy));
      return ConstantVector::get(DestVecTy, res);
    }
    return 0;
  case Instruction::ZExt:
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
      APInt Result(CI->getValue());
      Result.zext(BitWidth);
      return ConstantInt::get(Result);
    }
    return 0;
  case Instruction::SExt:
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
      APInt Result(CI->getValue());
      Result.sext(BitWidth);
      return ConstantInt::get(Result);
    }
    return 0;
  case Instruction::Trunc:
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
      APInt Result(CI->getValue());
      Result.trunc(BitWidth);
      return ConstantInt::get(Result);
    }
    return 0;
  case Instruction::BitCast:
    return FoldBitCast(const_cast<Constant*>(V), DestTy);
  default:
    assert(!"Invalid CE CastInst opcode");
    break;
  }

  assert(0 && "Failed to cast constant expression");
  return 0;
}


Generated by  Doxygen 1.6.0   Back to index