Skip to content

LLVM fails to merge blocks with calls that only differ in attributes. #9618

Closed
@d0k

Description

@d0k
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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzilla

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions