cast<Constant>(RHS)->isNullValue()) {
LoadInst* LI = cast<LoadInst>(LHS);
if (isValidAssumeForContext(II, LI, DL, DT)) {
- // assume( load (call|invoke) != null ) -> add 'nonnull' return
- // attribute
- Value *LIOperand = LI->getOperand(0);
- if (CallInst *I = dyn_cast<CallInst>(LIOperand))
- I->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);
- else if (InvokeInst *I = dyn_cast<InvokeInst>(LIOperand))
- I->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);
-
MDNode *MD = MDNode::get(II->getContext(), None);
LI->setMetadata(LLVMContext::MD_nonnull, MD);
return EraseInstFromFunction(*II);
}
}
+ // TODO: apply nonnull return attributes to calls and invokes
// TODO: apply range metadata for range check patterns?
}
// If there is a dominating assume with the same condition as this one,
; CHECK: call void @llvm.assume
}
-declare i32** @id(i32** %a)
-; Check that nonnull return attribute is applied to call
-define i1 @nonnull5(i32** %a) {
-entry:
- %idr = call i32** @id(i32** %a)
- %load = load i32** %idr
- %cmp = icmp ne i32* %load, null
- tail call void @llvm.assume(i1 %cmp)
- %rval = icmp eq i32* %load, null
- ret i1 %rval
-
-; CHECK-LABEL: @nonnull5
-; CHECK: call nonnull
-; CHECK-NOT: call void @llvm.assume
-; CHECK: ret i1 false
-}
-
-declare i32 @__personality0(...)
-; Check that nonnull return attribute is applied to invoke
-define i1 @nonnull6(i32** %a) {
-entry:
- %idr = invoke i32** @id(i32** %a) to label %norm unwind label %lpad
-norm:
- %load = load i32** %idr
- %cmp = icmp ne i32* %load, null
- tail call void @llvm.assume(i1 %cmp)
- %rval = icmp eq i32* %load, null
- ret i1 %rval
-lpad:
- %res = landingpad { i8*, i32 } personality i32 (...)* @__personality0 cleanup
- resume { i8*, i32 } undef
-
-; CHECK-LABEL: @nonnull6
-; CHECK: invoke nonnull
-; CHECK-NOT: call void @llvm.assume
-; CHECK: ret i1 false
-}
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind }