/// Subtract a constant from a builtin integer value. static SILValue getSub(SILLocation Loc, SILValue Val, unsigned SubVal, SILBuilder &B) { SmallVector<SILValue, 4> Args(1, Val); Args.push_back(B.createIntegerLiteral(Loc, Val->getType(), SubVal)); Args.push_back(B.createIntegerLiteral( Loc, SILType::getBuiltinIntegerType(1, B.getASTContext()), -1)); auto *AI = B.createBuiltinBinaryFunctionWithOverflow( Loc, "ssub_with_overflow", Args); return B.createTupleExtract(Loc, AI, 0); }
/// If necessary insert an overflow for this induction variable. /// If we compare for equality we need to make sure that the range does wrap. /// We would have trapped either when overflowing or when accessing an array /// out of bounds in the original loop. void checkOverflow(SILBuilder &Builder) { if (IsOverflowCheckInserted || Cmp != BuiltinValueKind::ICMP_EQ) return; auto Loc = Inc->getLoc(); auto ResultTy = SILType::getBuiltinIntegerType(1, Builder.getASTContext()); auto *CmpSGE = Builder.createBuiltinBinaryFunction( Loc, "cmp_sge", Start->getType(), ResultTy, {Start, End}); Builder.createCondFail(Loc, CmpSGE); IsOverflowCheckInserted = true; // We can now remove the cond fail on the increment the above comparison // guarantees that the addition won't overflow. auto *CondFail = isOverflowChecked(cast<BuiltinInst>(Inc)); if (CondFail) CondFail->eraseFromParent(); }
NullablePtr<SILInstruction> Projection:: createAddrProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const { // Grab Base's type. SILType BaseTy = Base.getType(); // If BaseTy is not an address type, bail. if (!BaseTy.isAddress()) return nullptr; // If this projection is associated with an object type, convert its type to // an address type. // // *NOTE* We purposely do not handle local storage types here since we want to // always fail in such a case. That is handled by checking that Ty is an // address. SILType Ty = Type.isObject()? Type.getAddressType() : Type; if (!Ty.isAddress()) return nullptr; // Ok, we now know that the type of Base and the type represented by the base // of this projection match and that this projection can be represented as // value. Create the instruction if we can. Otherwise, return nullptr. switch (getKind()) { case ProjectionKind::Struct: return B.createStructElementAddr(Loc, Base, cast<VarDecl>(getDecl())); case ProjectionKind::Tuple: return B.createTupleElementAddr(Loc, Base, getIndex()); case ProjectionKind::Index: { auto Ty = SILType::getBuiltinIntegerType(32, B.getASTContext()); auto *IntLiteral = B.createIntegerLiteral(Loc, Ty, getIndex()); return B.createIndexAddr(Loc, Base, IntLiteral); } case ProjectionKind::Enum: return B.createUncheckedTakeEnumDataAddr(Loc, Base, cast<EnumElementDecl>(getDecl())); case ProjectionKind::Class: return B.createRefElementAddr(Loc, Base, cast<VarDecl>(getDecl())); } }