Go to the documentation of this file.
69 #define DEBUG_TYPE "poison-checking"
74 cl::desc(
"Check that returns are non-poison (for testing)"));
79 if (
auto *CI = dyn_cast<ConstantInt>(V))
94 Accum =
B.CreateOr(Accum,
Op);
100 assert(isa<BinaryOperator>(
I));
105 switch (
I.getOpcode()) {
109 if (
I.hasNoSignedWrap()) {
111 B.CreateBinaryIntrinsic(Intrinsic::sadd_with_overflow,
LHS,
RHS);
112 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
114 if (
I.hasNoUnsignedWrap()) {
116 B.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow,
LHS,
RHS);
117 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
121 case Instruction::Sub: {
122 if (
I.hasNoSignedWrap()) {
124 B.CreateBinaryIntrinsic(Intrinsic::ssub_with_overflow,
LHS,
RHS);
125 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
127 if (
I.hasNoUnsignedWrap()) {
129 B.CreateBinaryIntrinsic(Intrinsic::usub_with_overflow,
LHS,
RHS);
130 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
135 if (
I.hasNoSignedWrap()) {
137 B.CreateBinaryIntrinsic(Intrinsic::smul_with_overflow,
LHS,
RHS);
138 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
140 if (
I.hasNoUnsignedWrap()) {
142 B.CreateBinaryIntrinsic(Intrinsic::umul_with_overflow,
LHS,
RHS);
143 Checks.push_back(
B.CreateExtractValue(OverflowOp, 1));
147 case Instruction::UDiv: {
152 Checks.push_back(
Check);
156 case Instruction::SDiv: {
161 Checks.push_back(
Check);
165 case Instruction::AShr:
166 case Instruction::LShr:
167 case Instruction::Shl: {
172 Checks.push_back(ShiftCheck);
184 if (isa<BinaryOperator>(
I) && !
I.getType()->isVectorTy())
188 switch (
I.getOpcode()) {
193 case Instruction::ExtractElement: {
194 Value *Vec =
I.getOperand(0);
195 auto *VecVTy = dyn_cast<FixedVectorType>(Vec->
getType());
198 Value *Idx =
I.getOperand(1);
199 unsigned NumElts = VecVTy->getNumElements();
203 Checks.push_back(
Check);
206 case Instruction::InsertElement: {
207 Value *Vec =
I.getOperand(0);
208 auto *VecVTy = dyn_cast<FixedVectorType>(Vec->
getType());
211 Value *Idx =
I.getOperand(2);
212 unsigned NumElts = VecVTy->getNumElements();
216 Checks.push_back(
Check);
223 auto Itr = ValToPoison.
find(V);
224 if (Itr != ValToPoison.
end())
226 if (isa<Constant>(V)) {
238 if (
auto *CI = dyn_cast<ConstantInt>(
Cond))
239 if (CI->isAllOnesValue())
242 Module *
M =
B.GetInsertBlock()->getModule();
243 M->getOrInsertFunction(
"__poison_checker_assert",
246 Function *TrapFunc =
M->getFunction(
"__poison_checker_assert");
247 B.CreateCall(TrapFunc,
Cond);
261 for (
auto I =
BB.begin(); isa<PHINode>(&*
I);
I++) {
262 auto *OldPHI = cast<PHINode>(&*
I);
263 auto *NewPHI =
PHINode::Create(Int1Ty, OldPHI->getNumIncomingValues());
264 for (
unsigned i = 0;
i < OldPHI->getNumIncomingValues();
i++)
266 OldPHI->getIncomingBlock(
i));
267 NewPHI->insertBefore(OldPHI);
268 ValToPoison[OldPHI] = NewPHI;
273 if (isa<PHINode>(
I))
continue;
282 for (
const Value *
Op : NonPoisonOps)
283 if (SeenNonPoisonOps.
insert(
Op).second)
288 if (
auto *RI = dyn_cast<ReturnInst>(&
I))
289 if (RI->getNumOperands() != 0) {
295 for (
const Use &U :
I.operands()) {
306 for (
auto I =
BB.begin(); isa<PHINode>(&*
I);
I++) {
307 auto *OldPHI = cast<PHINode>(&*
I);
308 if (!ValToPoison.
count(OldPHI))
310 auto *NewPHI = cast<PHINode>(ValToPoison[OldPHI]);
311 for (
unsigned i = 0;
i < OldPHI->getNumIncomingValues();
i++) {
312 auto *OldVal = OldPHI->getIncomingValue(
i);
313 NewPHI->setIncomingValue(
i,
getPoisonFor(ValToPoison, OldVal));
322 bool Changed =
false;
A set of analyses that are preserved following a run of a transformation pass.
This is an optimization pass for GlobalISel generic memory operations.
static IntegerType * getInt1Ty(LLVMContext &C)
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static Value * getPoisonFor(DenseMap< Value *, Value * > &ValToPoison, Value *V)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
static void generateCreationChecks(Instruction &I, SmallVectorImpl< Value * > &Checks)
Given an instruction which can produce poison on non-poison inputs (i.e.
LLVM Basic Block Representation.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
bool canCreatePoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static cl::opt< bool > LocalCheck("poison-checking-function-local", cl::init(false), cl::desc("Check that returns are non-poison (for testing)"))
static Value * buildOrChain(IRBuilder<> &B, ArrayRef< Value * > Ops)
initializer< Ty > init(const Ty &Val)
iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isConstantFalse(Value *V)
@ ICMP_UGE
unsigned greater or equal
A Module instance is used to store all the information related to an LLVM module.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
SmallVector< MachineOperand, 4 > Cond
Type * getType() const
All values are typed, get the type of this value.
LLVMContext & getContext() const
All values hold a context through their type.
static void CreateAssertNot(IRBuilder<> &B, Value *Cond)
static ConstantInt * getFalse(LLVMContext &Context)
static bool rewrite(Function &F)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
bool propagatesPoison(const Use &PoisonOp)
Return true if PoisonOp's user yields poison or raises UB if its operand PoisonOp is poison.
static void CreateAssert(IRBuilder<> &B, Value *Cond)
static Type * getVoidTy(LLVMContext &C)
size_t size() const
size - Get the array size.
static void generateCreationChecksForBinOp(Instruction &I, SmallVectorImpl< Value * > &Checks)
A container for analyses that lazily runs them and caches their results.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
void getGuaranteedNonPoisonOps(const Instruction *I, SmallVectorImpl< const Value * > &Ops)
Insert operands of I into Ops such that I will trigger undefined behavior if I is executed and that o...
LLVM Value Representation.
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.