Description
Bugzilla Link | 9246 |
Resolution | FIXED |
Resolved on | Mar 24, 2011 11:11 |
Version | trunk |
OS | All |
Attachments | preprocessed C testcase |
Extended Description
For the attached test case clang -O3 generates
===
define i8* @foo(i8* %x, i8* %y) nounwind ssp {
entry:
%0 = tail call i64 @llvm.objectsize.i64(i8* %x, i1 false)
%cmp = icmp eq i64 %0, -1
br i1 %cmp, label %cond.false, label %cond.true
cond.true: ; preds = %entry
%call = tail call i8* @__memcpy_chk(i8* %x, i8* %y, i64 42, i64 %0)
br label %cond.end
cond.false: ; preds = %entry
%call.i = tail call i8* @__memcpy_chk(i8* %x, i8* %y, i64 42, i64 %0) nounwind
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
%cond = phi i8* [ %call, %cond.true ], [ %call.i, %cond.false ]
ret i8* %cond
}
declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone
declare i8* @__memcpy_chk(i8*, i8*, i64, i64) nounwind
cond.true and cond.false should be merged, eliminating the icmp+branch.
This happens because darwin10's headers expand memcpy into a normal __memcpy_chk call and a call to an inlined function. At this point neither __memcpy_chk have a nounwind attribute. When the inliner inlines the function it detects that it was "nounwind" and applies the attribute to the inlined call.