@@ -155,6 +155,44 @@ define void @partial_promotion_of_alloca() {
155155 ret void
156156}
157157
158+ define void @launder_in_loop () {
159+ ; CHECK-LABEL: @launder_in_loop(
160+ ; CHECK-NEXT: br label %[[HEADER:.*]]
161+ ;
162+ %struct_ptr = alloca %t , i64 1 , align 4
163+ br label %header
164+
165+ ; CHECK: [[HEADER]]:
166+ ; CHECK-NEXT: br i1 true, label %[[BODY:.*]], label %[[EXIT:.*]]
167+ ;
168+ header:
169+ br i1 true , label %body , label %exit
170+
171+ ; CHECK: [[BODY]]:
172+ ; CHECK-NEXT: [[STRUCT:%.*]] = call %t @make_t()
173+ ; CHECK-NEXT: [[FIRST:%.*]] = extractvalue %t [[STRUCT]], 0
174+ ; CHECK-NEXT: [[SECOND:%.*]] = extractvalue %t [[STRUCT]], 1
175+ ; CHECK-NEXT: br label %[[HEADER]]
176+ ;
177+ body: ; preds = %6
178+ %struct_ptr_fresh = call ptr @llvm.launder.invariant.group.p0 (ptr %struct_ptr )
179+ %struct = call %t @make_t ()
180+ store %t %struct , ptr %struct_ptr_fresh , align 4 , !invariant.group !0
181+ %first_ptr = getelementptr %t , ptr %struct_ptr_fresh , i32 0 , i32 0
182+ %first = load i32 , ptr %first_ptr , align 4
183+ %second_ptr = getelementptr %t , ptr %struct_ptr_fresh , i32 0 , i32 1
184+ %second = load i32 , ptr %second_ptr , align 4
185+ br label %header
186+
187+ ; CHECK: [[EXIT]]:
188+ ; CHECK-NEXT: ret void
189+ ;
190+ exit:
191+ ret void
192+ }
193+
194+ declare %t @make_t ()
195+
158196declare void @use (ptr )
159197
160198!0 = !{}
0 commit comments