Files
clang-p2996/llvm/test/Transforms/CodeExtractor/PartialInlineAlloca4.ll
Vedant Kumar 5f5cac3ae2 [CodeExtractor] Do not lift lifetime.end markers for region inputs
If a lifetime.end marker occurs along one path through the extraction
region, but not another, then it's still incorrect to lift the marker,
because there is some path through the extracted function which would
ordinarily not reach the marker. If the call to the extracted function
is in a loop, unrolling can cause inputs to the function to become
optimized out as undef after the first iteration.

To prevent incorrect stack slot merging in the calling function, it
should be sufficient to lift lifetime.start markers for region inputs.
I've tested this theory out by doing a stage2 check-all with randomized
splitting enabled.

This is a follow-up to r353973, and there's additional context for this
change in https://reviews.llvm.org/D57834.

rdar://47896986

Differential Revision: https://reviews.llvm.org/D58253

llvm-svn: 354159
2019-02-15 18:46:58 +00:00

71 lines
2.1 KiB
LLVM

; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
; RUN: opt < %s -passes=partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s
%"class.base" = type { %"struct.base"* }
%"struct.base" = type opaque
@g = external local_unnamed_addr global i32, align 4
; CHECK-LABEL: define{{.*}}@caller(
; CHECK: call void @llvm.lifetime.start.p0i8(i64 -1, i8* %tmp.i)
; CHECK-NEXT: call void @callee_unknown_use1.{{.*}}(i8* %tmp.i
define i32 @callee_unknown_use1(i32 %arg) local_unnamed_addr #0 {
; CHECK-LABEL:define{{.*}}@callee_unknown_use1.{{[0-9]}}
; CHECK-NOT: alloca
bb:
%tmp = alloca i8, align 4
%tmp2 = load i32, i32* @g, align 4, !tbaa !2
%tmp3 = add nsw i32 %tmp2, 1
%tmp4 = icmp slt i32 %arg, 0
br i1 %tmp4, label %bb6, label %bb5
bb5: ; preds = %bb
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) #2
store i32 %tmp3, i32* @g, align 4, !tbaa !2
%tmp11 = bitcast i8* %tmp to i32*
call void @bar(i32* nonnull %tmp11) #2
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp) #2
br label %bb6
bb6: ; preds = %bb5, %bb
%tmp7 = phi i32 [ 1, %bb5 ], [ 0, %bb ]
%tmp1 = bitcast i8* %tmp to i32*
ret i32 %tmp7
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
declare void @bar(i32*) local_unnamed_addr #2
declare void @bar2(i32*, i32*) local_unnamed_addr #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
; Function Attrs: nounwind uwtable
define i32 @caller(i32 %arg) local_unnamed_addr #0 {
bb:
%tmp = tail call i32 @callee_unknown_use1(i32 %arg)
ret i32 %tmp
}
attributes #0 = { nounwind uwtable}
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (trunk 303574)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}