1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=strip-gc-relocates,instcombine < %s | FileCheck %s
; test utility/debugging pass which removes gc.relocates, inserted by -rewrite-statepoints-for-gc
declare void @use_obj32(ptr addrspace(1)) "gc-leaf-function"
declare void @g()
declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) #0
declare void @do_safepoint()
declare ptr addrspace(1) @new_instance() #1
; Simple case: remove gc.relocate
define ptr addrspace(1) @test1(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 100), "gc-live"() ]
; CHECK-NEXT: ret ptr addrspace(1) [[ARG:%.*]]
;
entry:
%statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg), "deopt" (i32 100)]
%arg.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%arg, %arg)
ret ptr addrspace(1) %arg.relocated
}
; Remove gc.relocates in presence of nested relocates.
define void @test2(ptr addrspace(1) %base) gc "statepoint-example" {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[PTR_GEP1:%.*]] = getelementptr i8, ptr addrspace(1) [[BASE:%.*]], i64 120
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ]
; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP1]])
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ]
; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP1]])
; CHECK-NEXT: ret void
;
entry:
%ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
%ptr.gep1 = getelementptr i32, ptr addrspace(1) %ptr.gep, i32 15
%statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %ptr.gep1, ptr addrspace(1) %base)]
%ptr.gep1.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 1, i32 0) ; (%base, %ptr.gep1)
%base.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 1, i32 1) ; (%base, %base)
call void @use_obj32(ptr addrspace(1) %ptr.gep1.relocated)
%statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %ptr.gep1.relocated, ptr addrspace(1) %base.relocated)]
%ptr.gep1.relocated2 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token1, i32 1, i32 0) ; (%base.relocated, %ptr.gep1.relocated)
%base.relocated3 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token1, i32 1, i32 1) ; (%base.relocated, %base.relocated)
call void @use_obj32(ptr addrspace(1) %ptr.gep1.relocated2)
ret void
}
; landing pad gc.relocates removed by instcombine since it has no uses.
define ptr addrspace(1) @test3(ptr addrspace(1) %arg) gc "statepoint-example" personality i32 8 {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 100), "gc-live"() ]
; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]]
; CHECK: normal_dest:
; CHECK-NEXT: ret ptr addrspace(1) [[ARG:%.*]]
; CHECK: unwind_dest:
; CHECK-NEXT: [[LPAD:%.*]] = landingpad token
; CHECK-NEXT: cleanup
; CHECK-NEXT: resume token undef
;
entry:
%statepoint_token = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg), "deopt" (i32 100)]
to label %normal_dest unwind label %unwind_dest
normal_dest: ; preds = %entry
%arg.relocated1 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%arg, %arg)
ret ptr addrspace(1) %arg.relocated1
unwind_dest: ; preds = %entry
%lpad = landingpad token
cleanup
%arg.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lpad, i32 0, i32 0) ; (%arg, %arg)
resume token undef
}
; in presence of phi
define void @test4(i1 %cond) gc "statepoint-example" {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BASE1:%.*]] = call ptr addrspace(1) @new_instance()
; CHECK-NEXT: [[BASE2:%.*]] = call ptr addrspace(1) @new_instance()
; CHECK-NEXT: br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
; CHECK: here:
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: there:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[BASEPHI_BASE:%.*]] = phi ptr addrspace(1) [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ], !is_base_value !0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ]
; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i8, ptr addrspace(1) [[BASEPHI_BASE]], i64 60
; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP_REMAT]])
; CHECK-NEXT: ret void
;
entry:
%base1 = call ptr addrspace(1) @new_instance()
%base2 = call ptr addrspace(1) @new_instance()
br i1 %cond, label %here, label %there
here: ; preds = %entry
br label %merge
there: ; preds = %entry
br label %merge
merge: ; preds = %there, %here
%basephi.base = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ], !is_base_value !0
%basephi = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ]
%ptr.gep = getelementptr i32, ptr addrspace(1) %basephi, i32 15
%statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %basephi.base)]
%basephi.base.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%basephi.base, %basephi.base)
%ptr.gep.remat = getelementptr i32, ptr addrspace(1) %basephi.base.relocated, i32 15
call void @use_obj32(ptr addrspace(1) %ptr.gep.remat)
ret void
}
; The gc.relocate type is different from %arg, but removing the gc.relocate,
; needs a bitcast to be added from ptr addrspace(1) to ptr addrspace(1)
define ptr addrspace(1) @test5(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr nonnull elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 100), "gc-live"() ]
; CHECK-NEXT: ret ptr addrspace(1) [[ARG:%.*]]
;
entry:
%statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @g, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %arg), "deopt" (i32 100)]
%arg.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%arg, %arg)
ret ptr addrspace(1) %arg.relocated
}
attributes #0 = { nounwind readonly }
attributes #1 = { nounwind "gc-leaf-function" }
!0 = !{}
|