[DeadArgElim] Guard against function type mismatch

If the call function type and function type don't match, we should
consider the function live (there is effectively a bitcast
sitting in between).
This commit is contained in:
Nikita Popov 2022-03-14 13:03:04 +01:00
parent cf18ec445d
commit 3ec44c22b1
2 changed files with 20 additions and 1 deletions

View File

@ -560,7 +560,8 @@ void DeadArgumentEliminationPass::SurveyFunction(const Function &F) {
// If the function is PASSED IN as an argument, its address has been // If the function is PASSED IN as an argument, its address has been
// taken. // taken.
const auto *CB = dyn_cast<CallBase>(U.getUser()); const auto *CB = dyn_cast<CallBase>(U.getUser());
if (!CB || !CB->isCallee(&U)) { if (!CB || !CB->isCallee(&U) ||
CB->getFunctionType() != F.getFunctionType()) {
MarkLive(F); MarkLive(F);
return; return;
} }

View File

@ -21,3 +21,21 @@ define void @caller() {
call void @callee(i32 42, i32 24) call void @callee(i32 42, i32 24)
ret void ret void
} }
define internal i16 @callee2(i16 %p1, i16 %p2) {
; CHECK-LABEL: define {{[^@]+}}@callee2
; CHECK-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) {
; CHECK-NEXT: ret i16 [[P2]]
;
ret i16 %p2
}
define i16 @caller2(i16 %a) {
; CHECK-LABEL: define {{[^@]+}}@caller2
; CHECK-SAME: (i16 [[A:%.*]]) {
; CHECK-NEXT: [[CALL:%.*]] = call i16 @callee2(i16 [[A]], i32 42)
; CHECK-NEXT: ret i16 [[CALL]]
;
%call = call i16 @callee2(i16 %a, i32 42)
ret i16 %call
}