89 lines · plain
1; This is a collection of really basic tests for gc.statepoint rewriting.2; RUN: opt < %s -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S | FileCheck %s3 4; Trivial relocation over a single call5 6declare void @foo()7 8define ptr addrspace(1) @test1(ptr addrspace(1) %obj) gc "statepoint-example" {9; CHECK-LABEL: @test110entry:11; CHECK-LABEL: entry:12; CHECK-NEXT: gc.statepoint13; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)14; Two safepoints in a row (i.e. consistent liveness)15 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]16 ret ptr addrspace(1) %obj17}18 19define ptr addrspace(1) @test2(ptr addrspace(1) %obj) gc "statepoint-example" {20; CHECK-LABEL: @test221entry:22; CHECK-LABEL: entry:23; CHECK-NEXT: gc.statepoint24; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)25; CHECK-NEXT: gc.statepoint26; CHECK-NEXT: %obj.relocated2 = call coldcc ptr addrspace(1)27; A simple derived pointer28 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]29 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]30 ret ptr addrspace(1) %obj31}32 33define i8 @test3(ptr addrspace(1) %obj) gc "statepoint-example" {34entry:35; CHECK-LABEL: entry:36; CHECK-NEXT: getelementptr37; CHECK-NEXT: gc.statepoint38; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)39; CHECK-NEXT: %derived.relocated = call coldcc ptr addrspace(1)40; CHECK-NEXT: load i8, ptr addrspace(1) %derived.relocated41; CHECK-NEXT: load i8, ptr addrspace(1) %obj.relocated42; Tests to make sure we visit both the taken and untaken predeccessor43; of merge. This was a bug in the dataflow liveness at one point.44 %derived = getelementptr i8, ptr addrspace(1) %obj, i64 1045 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]46 %a = load i8, ptr addrspace(1) %derived47 %b = load i8, ptr addrspace(1) %obj48 %c = sub i8 %a, %b49 ret i8 %c50}51 52define ptr addrspace(1) @test4(i1 %cmp, ptr addrspace(1) %obj) gc "statepoint-example" {53entry:54 br i1 %cmp, label %taken, label %untaken55 56taken: ; preds = %entry57; CHECK-LABEL: taken:58; CHECK-NEXT: gc.statepoint59; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)60 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]61 br label %merge62 63untaken: ; preds = %entry64; CHECK-LABEL: untaken:65; CHECK-NEXT: gc.statepoint66; CHECK-NEXT: %obj.relocated2 = call coldcc ptr addrspace(1)67 call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]68 br label %merge69 70merge: ; preds = %untaken, %taken71; CHECK-LABEL: merge:72; CHECK-NEXT: %.0 = phi ptr addrspace(1) [ %obj.relocated, %taken ], [ %obj.relocated2, %untaken ]73; CHECK-NEXT: ret ptr addrspace(1) %.074; When run over a function which doesn't opt in, should do nothing!75 ret ptr addrspace(1) %obj76}77 78define ptr addrspace(1) @test5(ptr addrspace(1) %obj) gc "ocaml" {79; CHECK-LABEL: @test580entry:81; CHECK-LABEL: entry:82; CHECK-NEXT: gc.statepoint83; CHECK-NOT: %obj.relocated = call coldcc ptr addrspace(1)84 %0 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 0, i32 -1, i32 0, i32 0, i32 0)]85 ret ptr addrspace(1) %obj86}87 88declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)89