本文整理汇总了C++中APInt::trunc方法的典型用法代码示例。如果您正苦于以下问题:C++ APInt::trunc方法的具体用法?C++ APInt::trunc怎么用?C++ APInt::trunc使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类APInt
的用法示例。
在下文中一共展示了APInt::trunc方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: truncate
/// truncate - Return a new range in the specified integer type, which must be
/// strictly smaller than the current type. The returned range will
/// correspond to the possible range of values as if the source range had been
/// truncated to the specified type.
ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
unsigned SrcTySize = getBitWidth();
assert(SrcTySize > DstTySize && "Not a value truncation");
APInt Size(APInt::getLowBitsSet(SrcTySize, DstTySize));
if (isFullSet() || getSetSize().ugt(Size))
return ConstantRange(DstTySize);
APInt L = Lower; L.trunc(DstTySize);
APInt U = Upper; U.trunc(DstTySize);
return ConstantRange(L, U);
}
示例2: constantFoldCast
APInt swift::constantFoldCast(APInt val, const BuiltinInfo &BI) {
// Get the cast result.
Type SrcTy = BI.Types[0];
Type DestTy = BI.Types.size() == 2 ? BI.Types[1] : Type();
uint32_t SrcBitWidth =
SrcTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
uint32_t DestBitWidth =
DestTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
APInt CastResV;
if (SrcBitWidth == DestBitWidth) {
return val;
} else switch (BI.ID) {
default : llvm_unreachable("Invalid case.");
case BuiltinValueKind::Trunc:
case BuiltinValueKind::TruncOrBitCast:
return val.trunc(DestBitWidth);
case BuiltinValueKind::ZExt:
case BuiltinValueKind::ZExtOrBitCast:
return val.zext(DestBitWidth);
break;
case BuiltinValueKind::SExt:
case BuiltinValueKind::SExtOrBitCast:
return val.sext(DestBitWidth);
}
}
示例3: truncate
/// truncate - Return a new range in the specified integer type, which must be
/// strictly smaller than the current type. The returned range will
/// correspond to the possible range of values as if the source range had been
/// truncated to the specified type.
ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
assert(getBitWidth() > DstTySize && "Not a value truncation");
if (isEmptySet())
return ConstantRange(DstTySize, /*isFullSet=*/false);
if (isFullSet())
return ConstantRange(DstTySize, /*isFullSet=*/true);
APInt MaxValue = APInt::getMaxValue(DstTySize).zext(getBitWidth());
APInt MaxBitValue(getBitWidth(), 0);
MaxBitValue.setBit(DstTySize);
APInt LowerDiv(Lower), UpperDiv(Upper);
ConstantRange Union(DstTySize, /*isFullSet=*/false);
// Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue]
// We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and
// then we do the union with [MaxValue, Upper)
if (isWrappedSet()) {
// if Upper is greater than Max Value, it covers the whole truncated range.
if (Upper.uge(MaxValue))
return ConstantRange(DstTySize, /*isFullSet=*/true);
Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize));
UpperDiv = APInt::getMaxValue(getBitWidth());
// Union covers the MaxValue case, so return if the remaining range is just
// MaxValue.
if (LowerDiv == UpperDiv)
return Union;
}
// Chop off the most significant bits that are past the destination bitwidth.
if (LowerDiv.uge(MaxValue)) {
APInt Div(getBitWidth(), 0);
APInt::udivrem(LowerDiv, MaxBitValue, Div, LowerDiv);
UpperDiv = UpperDiv - MaxBitValue * Div;
}
if (UpperDiv.ule(MaxValue))
return ConstantRange(LowerDiv.trunc(DstTySize),
UpperDiv.trunc(DstTySize)).unionWith(Union);
// The truncated value wrapps around. Check if we can do better than fullset.
APInt UpperModulo = UpperDiv - MaxBitValue;
if (UpperModulo.ult(LowerDiv))
return ConstantRange(LowerDiv.trunc(DstTySize),
UpperModulo.trunc(DstTySize)).unionWith(Union);
return ConstantRange(DstTySize, /*isFullSet=*/true);
}
示例4: get
/// isBytewiseValue - If the specified value can be set by repeating the same
/// byte in memory, return the i8 value that it is represented with. This is
/// true for all i8 values obviously, but is also true for i32 0, i32 -1,
/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated
/// byte store (e.g. i16 0x1234), return null.
static Value *isBytewiseValue(Value *V) {
LLVMContext &Context = V->getContext();
// All byte-wide stores are splatable, even of arbitrary variables.
if (V->getType()->isIntegerTy(8)) return V;
// Constant float and double values can be handled as integer values if the
// corresponding integer value is "byteable". An important case is 0.0.
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
if (CFP->getType()->isFloatTy())
V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(Context));
if (CFP->getType()->isDoubleTy())
V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(Context));
// Don't handle long double formats, which have strange constraints.
}
// We can handle constant integers that are power of two in size and a
// multiple of 8 bits.
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
unsigned Width = CI->getBitWidth();
if (isPowerOf2_32(Width) && Width > 8) {
// We can handle this value if the recursive binary decomposition is the
// same at all levels.
APInt Val = CI->getValue();
APInt Val2;
while (Val.getBitWidth() != 8) {
unsigned NextWidth = Val.getBitWidth()/2;
Val2 = Val.lshr(NextWidth);
Val2.trunc(Val.getBitWidth()/2);
Val.trunc(Val.getBitWidth()/2);
// If the top/bottom halves aren't the same, reject it.
if (Val != Val2)
return 0;
}
return ConstantInt::get(Context, Val);
}
}
// Conceptually, we could handle things like:
// %a = zext i8 %X to i16
// %b = shl i16 %a, 8
// %c = or i16 %a, %b
// but until there is an example that actually needs this, it doesn't seem
// worth worrying about.
return 0;
}
示例5: assert
llvm::Constant *irgen::emitConstantInt(IRGenModule &IGM,
IntegerLiteralInst *ILI) {
APInt value = ILI->getValue();
BuiltinIntegerWidth width
= ILI->getType().castTo<BuiltinIntegerType>()->getWidth();
// The value may need truncation if its type had an abstract size.
if (!width.isFixedWidth()) {
assert(width.isPointerWidth() && "impossible width value");
unsigned pointerWidth = IGM.getPointerSize().getValueInBits();
assert(pointerWidth <= value.getBitWidth()
&& "lost precision at AST/SIL level?!");
if (pointerWidth < value.getBitWidth())
value = value.trunc(pointerWidth);
}
return llvm::ConstantInt::get(IGM.LLVMContext, value);
}
示例6: determineLiveOperandBits
//.........这里部分代码省略.........
// If the shift is nuw/nsw, then the high bits are not dead
// (because we've promised that they *must* be zero).
const ShlOperator *S = cast<ShlOperator>(UserI);
if (S->hasNoSignedWrap())
AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt+1);
else if (S->hasNoUnsignedWrap())
AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt);
}
break;
case Instruction::LShr:
if (OperandNo == 0)
if (ConstantInt *CI =
dyn_cast<ConstantInt>(UserI->getOperand(1))) {
uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1);
AB = AOut.shl(ShiftAmt);
// If the shift is exact, then the low bits are not dead
// (they must be zero).
if (cast<LShrOperator>(UserI)->isExact())
AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
}
break;
case Instruction::AShr:
if (OperandNo == 0)
if (ConstantInt *CI =
dyn_cast<ConstantInt>(UserI->getOperand(1))) {
uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1);
AB = AOut.shl(ShiftAmt);
// Because the high input bit is replicated into the
// high-order bits of the result, if we need any of those
// bits, then we must keep the highest input bit.
if ((AOut & APInt::getHighBitsSet(BitWidth, ShiftAmt))
.getBoolValue())
AB.setBit(BitWidth-1);
// If the shift is exact, then the low bits are not dead
// (they must be zero).
if (cast<AShrOperator>(UserI)->isExact())
AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
}
break;
case Instruction::And:
AB = AOut;
// For bits that are known zero, the corresponding bits in the
// other operand are dead (unless they're both zero, in which
// case they can't both be dead, so just mark the LHS bits as
// dead).
if (OperandNo == 0) {
ComputeKnownBits(BitWidth, I, UserI->getOperand(1));
AB &= ~KnownZero2;
} else {
if (!isa<Instruction>(UserI->getOperand(0)))
ComputeKnownBits(BitWidth, UserI->getOperand(0), I);
AB &= ~(KnownZero & ~KnownZero2);
}
break;
case Instruction::Or:
AB = AOut;
// For bits that are known one, the corresponding bits in the
// other operand are dead (unless they're both one, in which
// case they can't both be dead, so just mark the LHS bits as
// dead).
if (OperandNo == 0) {
ComputeKnownBits(BitWidth, I, UserI->getOperand(1));
AB &= ~KnownOne2;
} else {
if (!isa<Instruction>(UserI->getOperand(0)))
ComputeKnownBits(BitWidth, UserI->getOperand(0), I);
AB &= ~(KnownOne & ~KnownOne2);
}
break;
case Instruction::Xor:
case Instruction::PHI:
AB = AOut;
break;
case Instruction::Trunc:
AB = AOut.zext(BitWidth);
break;
case Instruction::ZExt:
AB = AOut.trunc(BitWidth);
break;
case Instruction::SExt:
AB = AOut.trunc(BitWidth);
// Because the high input bit is replicated into the
// high-order bits of the result, if we need any of those
// bits, then we must keep the highest input bit.
if ((AOut & APInt::getHighBitsSet(AOut.getBitWidth(),
AOut.getBitWidth() - BitWidth))
.getBoolValue())
AB.setBit(BitWidth-1);
break;
case Instruction::Select:
if (OperandNo != 0)
AB = AOut;
break;
}
}
示例7: ComputeMaskedBits
//.........这里部分代码省略.........
// which fall through here.
const Type *SrcTy = I->getOperand(0)->getType();
unsigned SrcBitWidth = TD ?
TD->getTypeSizeInBits(SrcTy) :
SrcTy->getPrimitiveSizeInBits();
APInt MaskIn(Mask);
MaskIn.zextOrTrunc(SrcBitWidth);
KnownZero.zextOrTrunc(SrcBitWidth);
KnownOne.zextOrTrunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
KnownZero.zextOrTrunc(BitWidth);
KnownOne.zextOrTrunc(BitWidth);
// Any top bits are known to be zero.
if (BitWidth > SrcBitWidth)
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
return;
}
case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy->isInteger() || isa<PointerType>(SrcTy)) {
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, TD,
Depth+1);
return;
}
break;
}
case Instruction::SExt: {
// Compute the bits in the result that are not present in the input.
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
unsigned SrcBitWidth = SrcTy->getBitWidth();
APInt MaskIn(Mask);
MaskIn.trunc(SrcBitWidth);
KnownZero.trunc(SrcBitWidth);
KnownOne.trunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero.zext(BitWidth);
KnownOne.zext(BitWidth);
// If the sign bit of the input is known set or clear, then we know the
// top bits of the result.
if (KnownZero[SrcBitWidth-1]) // Input sign bit known zero
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
else if (KnownOne[SrcBitWidth-1]) // Input sign bit known set
KnownOne |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
return;
}
case Instruction::Shl:
// (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth);
APInt Mask2(Mask.lshr(ShiftAmt));
ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
KnownZero <<= ShiftAmt;
KnownOne <<= ShiftAmt;
KnownZero |= APInt::getLowBitsSet(BitWidth, ShiftAmt); // low bits known 0
return;
}
break;
case Instruction::LShr:
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
示例8: unknownResult
SymbolicValue
ConstExprFunctionState::computeConstantValueBuiltin(BuiltinInst *inst) {
const BuiltinInfo &builtin = inst->getBuiltinInfo();
// Handle various cases in groups.
auto unknownResult = [&]() -> SymbolicValue {
return evaluator.getUnknown(SILValue(inst), UnknownReason::Default);
};
// Unary operations.
if (inst->getNumOperands() == 1) {
auto operand = getConstantValue(inst->getOperand(0));
// TODO: Could add a "value used here" sort of diagnostic.
if (!operand.isConstant())
return operand;
// TODO: SUCheckedConversion/USCheckedConversion
// Implement support for s_to_s_checked_trunc_Int2048_Int64 and other
// checking integer truncates. These produce a tuple of the result value
// and an overflow bit.
//
// TODO: We can/should diagnose statically detectable integer overflow
// errors and subsume the ConstantFolding.cpp mandatory SIL pass.
auto IntCheckedTruncFn = [&](bool srcSigned,
bool dstSigned) -> SymbolicValue {
if (operand.getKind() != SymbolicValue::Integer)
return unknownResult();
auto operandVal = operand.getIntegerValue();
uint32_t srcBitWidth = operandVal.getBitWidth();
auto dstBitWidth =
builtin.Types[1]->castTo<BuiltinIntegerType>()->getGreatestWidth();
APInt result = operandVal.trunc(dstBitWidth);
// Compute the overflow by re-extending the value back to its source and
// checking for loss of value.
APInt reextended =
dstSigned ? result.sext(srcBitWidth) : result.zext(srcBitWidth);
bool overflowed = (operandVal != reextended);
if (!srcSigned && dstSigned)
overflowed |= result.isSignBitSet();
if (overflowed)
return evaluator.getUnknown(SILValue(inst), UnknownReason::Overflow);
auto &astContext = evaluator.getASTContext();
// Build the Symbolic value result for our truncated value.
return SymbolicValue::getAggregate(
{SymbolicValue::getInteger(result, astContext),
SymbolicValue::getInteger(APInt(1, overflowed), astContext)},
astContext);
};
switch (builtin.ID) {
default:
break;
case BuiltinValueKind::SToSCheckedTrunc:
return IntCheckedTruncFn(true, true);
case BuiltinValueKind::UToSCheckedTrunc:
return IntCheckedTruncFn(false, true);
case BuiltinValueKind::SToUCheckedTrunc:
return IntCheckedTruncFn(true, false);
case BuiltinValueKind::UToUCheckedTrunc:
return IntCheckedTruncFn(false, false);
case BuiltinValueKind::Trunc:
case BuiltinValueKind::TruncOrBitCast:
case BuiltinValueKind::ZExt:
case BuiltinValueKind::ZExtOrBitCast:
case BuiltinValueKind::SExt:
case BuiltinValueKind::SExtOrBitCast: {
if (operand.getKind() != SymbolicValue::Integer)
return unknownResult();
unsigned destBitWidth =
inst->getType().castTo<BuiltinIntegerType>()->getGreatestWidth();
APInt result = operand.getIntegerValue();
if (result.getBitWidth() != destBitWidth) {
switch (builtin.ID) {
default:
assert(0 && "Unknown case");
case BuiltinValueKind::Trunc:
case BuiltinValueKind::TruncOrBitCast:
result = result.trunc(destBitWidth);
break;
case BuiltinValueKind::ZExt:
case BuiltinValueKind::ZExtOrBitCast:
result = result.zext(destBitWidth);
break;
case BuiltinValueKind::SExt:
case BuiltinValueKind::SExtOrBitCast:
result = result.sext(destBitWidth);
break;
}
}
return SymbolicValue::getInteger(result, evaluator.getASTContext());
//.........这里部分代码省略.........
示例9: constructResultWithOverflowTuple
static SILInstruction *
constantFoldAndCheckIntegerConversions(BuiltinInst *BI,
const BuiltinInfo &Builtin,
Optional<bool> &ResultsInError) {
assert(Builtin.ID == BuiltinValueKind::SToSCheckedTrunc ||
Builtin.ID == BuiltinValueKind::UToUCheckedTrunc ||
Builtin.ID == BuiltinValueKind::SToUCheckedTrunc ||
Builtin.ID == BuiltinValueKind::UToSCheckedTrunc ||
Builtin.ID == BuiltinValueKind::SUCheckedConversion ||
Builtin.ID == BuiltinValueKind::USCheckedConversion);
// Check if we are converting a constant integer.
OperandValueArrayRef Args = BI->getArguments();
auto *V = dyn_cast<IntegerLiteralInst>(Args[0]);
if (!V)
return nullptr;
APInt SrcVal = V->getValue();
// Get source type and bit width.
Type SrcTy = Builtin.Types[0];
uint32_t SrcBitWidth =
Builtin.Types[0]->castTo<BuiltinIntegerType>()->getGreatestWidth();
// Compute the destination (for SrcBitWidth < DestBitWidth) and enough info
// to check for overflow.
APInt Result;
bool OverflowError;
Type DstTy;
// Process conversions signed <-> unsigned for same size integers.
if (Builtin.ID == BuiltinValueKind::SUCheckedConversion ||
Builtin.ID == BuiltinValueKind::USCheckedConversion) {
DstTy = SrcTy;
Result = SrcVal;
// Report an error if the sign bit is set.
OverflowError = SrcVal.isNegative();
// Process truncation from unsigned to signed.
} else if (Builtin.ID != BuiltinValueKind::UToSCheckedTrunc) {
assert(Builtin.Types.size() == 2);
DstTy = Builtin.Types[1];
uint32_t DstBitWidth =
DstTy->castTo<BuiltinIntegerType>()->getGreatestWidth();
// Result = trunc_IntFrom_IntTo(Val)
// For signed destination:
// sext_IntFrom(Result) == Val ? Result : overflow_error
// For signed destination:
// zext_IntFrom(Result) == Val ? Result : overflow_error
Result = SrcVal.trunc(DstBitWidth);
// Get the signedness of the destination.
bool Signed = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc);
APInt Ext = Signed ? Result.sext(SrcBitWidth) : Result.zext(SrcBitWidth);
OverflowError = (SrcVal != Ext);
// Process the rest of truncations.
} else {
assert(Builtin.Types.size() == 2);
DstTy = Builtin.Types[1];
uint32_t DstBitWidth =
Builtin.Types[1]->castTo<BuiltinIntegerType>()->getGreatestWidth();
// Compute the destination (for SrcBitWidth < DestBitWidth):
// Result = trunc_IntTo(Val)
// Trunc = trunc_'IntTo-1bit'(Val)
// zext_IntFrom(Trunc) == Val ? Result : overflow_error
Result = SrcVal.trunc(DstBitWidth);
APInt TruncVal = SrcVal.trunc(DstBitWidth - 1);
OverflowError = (SrcVal != TruncVal.zext(SrcBitWidth));
}
// Check for overflow.
if (OverflowError) {
// If we are not asked to emit overflow diagnostics, just return nullptr on
// overflow.
if (!ResultsInError.hasValue())
return nullptr;
SILLocation Loc = BI->getLoc();
SILModule &M = BI->getModule();
const ApplyExpr *CE = Loc.getAsASTNode<ApplyExpr>();
Type UserSrcTy;
Type UserDstTy;
// Primitive heuristics to get the user-written type.
// Eventually we might be able to use SILLocation (when it contains info
// about inlined call chains).
if (CE) {
if (const TupleType *RTy = CE->getArg()->getType()->getAs<TupleType>()) {
if (RTy->getNumElements() == 1) {
UserSrcTy = RTy->getElementType(0);
UserDstTy = CE->getType();
}
} else {
UserSrcTy = CE->getArg()->getType();
UserDstTy = CE->getType();
}
}
// Assume that we are converting from a literal if the Source size is
// 2048. Is there a better way to identify conversions from literals?
bool Literal = (SrcBitWidth == 2048);
//.........这里部分代码省略.........