1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -hotcoldsplit -hotcoldsplit-threshold=0 < %s 2>&1 | FileCheck %s
4 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
6 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
8 declare void @cold_use(i8*) cold
10 declare void @use(i8*)
12 ; In this CFG, splitting will extract the blocks extract{1,2}. I.e., it will
13 ; extract a lifetime.start marker, but not the corresponding lifetime.end
14 ; marker. Make sure that a lifetime.start marker is emitted before the call to
15 ; the split function, and *only* that marker.
19 ; extract1 no-extract1
28 ; After splitting, we should see:
32 ; codeRepl no-extract1
37 define void @only_lifetime_start_is_cold() {
38 ; CHECK-LABEL: @only_lifetime_start_is_cold(
40 ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
41 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
42 ; CHECK-NEXT: br i1 undef, label [[CODEREPL:%.*]], label [[NO_EXTRACT1:%.*]]
44 ; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
45 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]])
46 ; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3
47 ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[NO_EXTRACT1]], label [[EXIT:%.*]]
49 ; CHECK-NEXT: br label [[EXIT]]
51 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[LOCAL1_CAST]])
52 ; CHECK-NEXT: ret void
56 %local1_cast = bitcast i256* %local1 to i8*
57 br i1 undef, label %extract1, label %no-extract1
61 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local1_cast)
62 call void @cold_use(i8* %local1_cast)
63 br i1 undef, label %extract2, label %no-extract1
73 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast)
77 ; In this CFG, splitting will extract the block extract1. I.e., it will extract
78 ; a lifetime.end marker, but not the corresponding lifetime.start marker. Do
79 ; not emit a lifetime.end marker after the call to the split function.
84 ; no-extract1 extract1
89 ; After splitting, we should see:
94 ; no-extract1 codeRepl
98 define void @only_lifetime_end_is_cold() {
99 ; CHECK-LABEL: @only_lifetime_end_is_cold(
101 ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
102 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
103 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]])
104 ; CHECK-NEXT: br i1 undef, label [[NO_EXTRACT1:%.*]], label [[CODEREPL:%.*]]
105 ; CHECK: no-extract1:
106 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[LOCAL1_CAST]])
107 ; CHECK-NEXT: br label [[EXIT:%.*]]
109 ; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3
110 ; CHECK-NEXT: br label [[EXIT]]
112 ; CHECK-NEXT: ret void
116 %local1 = alloca i256
117 %local1_cast = bitcast i256* %local1 to i8*
118 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local1_cast)
119 br i1 undef, label %no-extract1, label %extract1
123 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast)
128 call void @cold_use(i8* %local1_cast)
129 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast)
136 ; In this CFG, splitting will extract the blocks extract{1,2,3}. Lifting the
137 ; lifetime.end marker would be a miscompile.
138 define void @do_not_lift_lifetime_end() {
139 ; CHECK-LABEL: @do_not_lift_lifetime_end(
141 ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256
142 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8*
143 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]])
144 ; CHECK-NEXT: br label [[HEADER:%.*]]
146 ; CHECK-NEXT: call void @use(i8* [[LOCAL1_CAST]])
147 ; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[CODEREPL:%.*]]
149 ; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) #3
150 ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[HEADER]], label [[EXIT]]
152 ; CHECK-NEXT: ret void
156 %local1 = alloca i256
157 %local1_cast = bitcast i256* %local1 to i8*
158 call void @llvm.lifetime.start.p0i8(i64 1, i8* %local1_cast)
162 ; If the lifetime.end marker is lifted, this use becomes dead the second time
163 ; the header block is executed.
164 call void @use(i8* %local1_cast)
165 br i1 undef, label %exit, label %extract1
168 call void @cold_use(i8* %local1_cast)
169 br i1 undef, label %extract2, label %extract3
177 call void @llvm.lifetime.end.p0i8(i64 1, i8* %local1_cast)