ret void
}
+define i8* @test27_pointer_escape() {
+; CHECK-LABEL: @test27_pointer_escape(
+; CHECK-NEXT: bb1:
+; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[M:%.*]] = call noalias i8* @malloc(i64 10)
+; CHECK-NEXT: store i8 1, i8* [[M]], align 1
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[R:%.*]] = phi i8* [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
+; CHECK-NEXT: ret i8* [[R]]
+;
+bb1:
+ br i1 true, label %bb2, label %bb3
+bb2:
+ %m = call noalias i8* @malloc(i64 10)
+ store i8 1, i8* %m
+ br label %bb3
+bb3:
+ %r = phi i8* [ null, %bb1 ], [ %m, %bb2 ]
+ ret i8* %r
+}
define i8* @test28() {
; CHECK-LABEL: @test28(
%p3 = bitcast i32* %arrayidx0 to i8*
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
br i1 %c, label %bb1, label %bb2
+
bb1:
br label %bb3
+
bb2:
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
store i32 1, i32* %arrayidx1, align 4
br label %bb3
+
bb3:
ret void
}
}
+declare void @readonly_use(i32* nocapture) readonly
+
; Tests where the pointer/object is *NOT* accessible after the function returns.
; Overwriting store along one path to the exit.
; CHECK-NEXT: [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
+; CHECK-NEXT: call void @readonly_use(i32* [[P]])
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br label [[BB3:%.*]]
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
%p3 = bitcast i32* %arrayidx0 to i8*
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+ call void @readonly_use(i32* %P)
br i1 %c, label %bb1, label %bb2
+
bb1:
br label %bb3
+
bb2:
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
store i32 1, i32* %arrayidx1, align 4
br label %bb3
+
bb3:
ret void
}
; CHECK-NEXT: [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
-; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
+; CHECK-NEXT: call void @readonly_use(i32* [[P]])
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
%p3 = bitcast i32* %arrayidx0 to i8*
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
+ call void @readonly_use(i32* %P)
br i1 %c, label %bb1, label %bb2
bb1: