Skip to content

Commit fd48c14

Browse files
committed
[InstCombine] Special handle va_copy(dst, src) + va_end(src)
1 parent f55daa8 commit fd48c14

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -816,9 +816,12 @@ removeTriviallyEmptyRange(IntrinsicInst &EndI, InstCombinerImpl &IC,
816816
}
817817

818818
Instruction *InstCombinerImpl::visitVAEndInst(VAEndInst &I) {
819-
removeTriviallyEmptyRange(I, *this, [](const IntrinsicInst &I) {
820-
return I.getIntrinsicID() == Intrinsic::vastart ||
821-
I.getIntrinsicID() == Intrinsic::vacopy;
819+
removeTriviallyEmptyRange(I, *this, [&I](const IntrinsicInst &II) {
820+
// Bail out on the case where the source va_list of a va_copy is destroyed
821+
// immediately by a follow-up va_end.
822+
return II.getIntrinsicID() == Intrinsic::vastart ||
823+
(II.getIntrinsicID() == Intrinsic::vacopy &&
824+
I.getArgOperand(0) != II.getArgOperand(1));
822825
});
823826
return nullptr;
824827
}

llvm/test/Transforms/InstCombine/vararg.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ define void @func_destroy_copy_src(ptr nocapture readnone %fmt, ...) {
3333
; CHECK-NEXT: [[VA1:%.*]] = alloca [[STRUCT___VA_LIST]], align 8
3434
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VA0]])
3535
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VA1]])
36+
; CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VA0]])
3637
; CHECK-NEXT: call void @llvm.va_copy.p0(ptr nonnull [[VA1]], ptr nonnull [[VA0]])
38+
; CHECK-NEXT: call void @llvm.va_end.p0(ptr [[VA0]])
3739
; CHECK-NEXT: call void @callee(ptr nonnull [[VA1]])
3840
; CHECK-NEXT: call void @llvm.va_end.p0(ptr [[VA1]])
3941
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VA1]])

0 commit comments

Comments
 (0)