1; RUN: llc < %s 2; REQUIRES: default_triple 3 4 5declare i8* @llvm_gc_allocate(i32) 6declare void @llvm_gc_initialize(i32) 7 8declare void @llvm.gcroot(i8**, i8*) 9declare void @llvm.gcwrite(i8*, i8*, i8**) 10 11define i32 @main() gc "shadow-stack" { 12entry: 13 %A = alloca i8* 14 %B = alloca i8** 15 16 call void @llvm_gc_initialize(i32 1048576) ; Start with 1MB heap 17 18 ;; void *A; 19 call void @llvm.gcroot(i8** %A, i8* null) 20 21 ;; A = gcalloc(10); 22 %Aptr = call i8* @llvm_gc_allocate(i32 10) 23 store i8* %Aptr, i8** %A 24 25 ;; void **B; 26 %tmp.1 = bitcast i8*** %B to i8** 27 call void @llvm.gcroot(i8** %tmp.1, i8* null) 28 29 ;; B = gcalloc(4); 30 %B.upgrd.1 = call i8* @llvm_gc_allocate(i32 8) 31 %tmp.2 = bitcast i8* %B.upgrd.1 to i8** 32 store i8** %tmp.2, i8*** %B 33 34 ;; *B = A; 35 %B.1 = load i8**, i8*** %B 36 %A.1 = load i8*, i8** %A 37 call void @llvm.gcwrite(i8* %A.1, i8* %B.upgrd.1, i8** %B.1) 38 39 br label %AllocLoop 40 41AllocLoop: 42 %i = phi i32 [ 0, %entry ], [ %indvar.next, %AllocLoop ] 43 ;; Allocated mem: allocated memory is immediately dead. 44 call i8* @llvm_gc_allocate(i32 100) 45 46 %indvar.next = add i32 %i, 1 47 %exitcond = icmp eq i32 %indvar.next, 10000000 48 br i1 %exitcond, label %Exit, label %AllocLoop 49 50Exit: 51 ret i32 0 52} 53 54declare void @__main() 55