| ; RUN: llc < %s |
| |
| |
| declare i8* @llvm_gc_allocate(i32) |
| declare void @llvm_gc_initialize(i32) |
| |
| declare void @llvm.gcroot(i8**, i8*) |
| declare void @llvm.gcwrite(i8*, i8*, i8**) |
| |
| define i32 @main() gc "shadow-stack" { |
| entry: |
| %A = alloca i8* |
| %B = alloca i8** |
| |
| call void @llvm_gc_initialize(i32 1048576) ; Start with 1MB heap |
| |
| ;; void *A; |
| call void @llvm.gcroot(i8** %A, i8* null) |
| |
| ;; A = gcalloc(10); |
| %Aptr = call i8* @llvm_gc_allocate(i32 10) |
| store i8* %Aptr, i8** %A |
| |
| ;; void **B; |
| %tmp.1 = bitcast i8*** %B to i8** |
| call void @llvm.gcroot(i8** %tmp.1, i8* null) |
| |
| ;; B = gcalloc(4); |
| %B.upgrd.1 = call i8* @llvm_gc_allocate(i32 8) |
| %tmp.2 = bitcast i8* %B.upgrd.1 to i8** |
| store i8** %tmp.2, i8*** %B |
| |
| ;; *B = A; |
| %B.1 = load i8*** %B |
| %A.1 = load i8** %A |
| call void @llvm.gcwrite(i8* %A.1, i8* %B.upgrd.1, i8** %B.1) |
| |
| br label %AllocLoop |
| |
| AllocLoop: |
| %i = phi i32 [ 0, %entry ], [ %indvar.next, %AllocLoop ] |
| ;; Allocated mem: allocated memory is immediately dead. |
| call i8* @llvm_gc_allocate(i32 100) |
| |
| %indvar.next = add i32 %i, 1 |
| %exitcond = icmp eq i32 %indvar.next, 10000000 |
| br i1 %exitcond, label %Exit, label %AllocLoop |
| |
| Exit: |
| ret i32 0 |
| } |
| |
| declare void @__main() |