/// Check if a checked trunc instruction can overflow. /// Returns false if it can be proven that no overflow can happen. /// Otherwise returns true. static bool checkTruncOverflow(BuiltinInst *BI) { SILValue Left, Right; if (match(BI, m_CheckedTrunc(m_And(m_SILValue(Left), m_SILValue(Right))))) { // [US]ToSCheckedTrunc(And(x, mask)) cannot overflow // if mask has the following properties: // Only the first (N-1) bits are allowed to be set, where N is the width // of the trunc result type. // // [US]ToUCheckedTrunc(And(x, mask)) cannot overflow // if mask has the following properties: // Only the first N bits are allowed to be set, where N is the width // of the trunc result type. if (auto BITy = BI->getType(). getTupleElementType(0). getAs<BuiltinIntegerType>()) { unsigned Width = BITy->getFixedWidth(); switch (BI->getBuiltinInfo().ID) { case BuiltinValueKind::SToSCheckedTrunc: case BuiltinValueKind::UToSCheckedTrunc: // If it is a trunc to a signed value // then sign bit should not be set to avoid overflows. --Width; break; default: break; } if (auto *ILLeft = dyn_cast<IntegerLiteralInst>(Left)) { APInt Value = ILLeft->getValue(); if (Value.isIntN(Width)) { return false; } } if (auto *ILRight = dyn_cast<IntegerLiteralInst>(Right)) { APInt Value = ILRight->getValue(); if (Value.isIntN(Width)) { return false; } } } } return true; }
/// We do not support symbolic projections yet, only 32-bit unsigned integers. bool swift::getIntegerIndex(SILValue IndexVal, unsigned &IndexConst) { if (auto *IndexLiteral = dyn_cast<IntegerLiteralInst>(IndexVal)) { APInt ConstInt = IndexLiteral->getValue(); // IntegerLiterals are signed. if (ConstInt.isIntN(32) && ConstInt.isNonNegative()) { IndexConst = (unsigned)ConstInt.getSExtValue(); return true; } } return false; }
// Select constant vector splats. // // In addition to the requirements of selectVSplat(), this function returns // true and sets Imm if: // * The splat value is the same width as the elements of the vector // * The splat value fits in an integer with the specified signed-ness and // width. // // This function looks through ISD::BITCAST nodes. // TODO: This might not be appropriate for big-endian MSA since BITCAST is // sometimes a shuffle in big-endian mode. // // It's worth noting that this function is not used as part of the selection // of ldi.[bhwd] since it does not permit using the wrong-typed ldi.[bhwd] // instruction to achieve the desired bit pattern. ldi.[bhwd] is selected in // MipsSEDAGToDAGISel::selectNode. bool MipsSEDAGToDAGISel:: selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed, unsigned ImmBitSize) const { APInt ImmValue; EVT EltTy = N->getValueType(0).getVectorElementType(); if (N->getOpcode() == ISD::BITCAST) N = N->getOperand(0); if (selectVSplat (N.getNode(), ImmValue) && ImmValue.getBitWidth() == EltTy.getSizeInBits()) { if (( Signed && ImmValue.isSignedIntN(ImmBitSize)) || (!Signed && ImmValue.isIntN(ImmBitSize))) { Imm = CurDAG->getTargetConstant(ImmValue, EltTy); return true; } } return false; }
static AsmToken intToken(StringRef Ref, APInt &Value) { if (Value.isIntN(64)) return AsmToken(AsmToken::Integer, Ref, Value); return AsmToken(AsmToken::BigNum, Ref, Value); }