158 changes: 76 additions & 82 deletions llvm/test/Transforms/RewriteStatepointsForGC/intrinsics.ll

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,134 +4,126 @@
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s

; A non-vector relocation for comparison
define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
define ptr addrspace(1) @test(ptr addrspace(1) %obj) gc "statepoint-example" {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(ptr addrspace(1) [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret ptr addrspace(1) [[OBJ_RELOCATED]]
;
; A base vector from a argument
entry:
call void @do_safepoint() [ "deopt"() ]
ret i64 addrspace(1)* %obj
ret ptr addrspace(1) %obj
}

; A vector argument
define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test2(<2 x ptr addrspace(1)> %obj) gc "statepoint-example" {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

; A load
define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test3(ptr %ptr) gc "statepoint-example" {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obj = load <2 x ptr addrspace(1)>, ptr %ptr
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

declare i32 @fake_personality_function()

; When a statepoint is an invoke rather than a call
define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function {
define <2 x ptr addrspace(1)> @test4(ptr %ptr) gc "statepoint-example" personality ptr @fake_personality_function {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke 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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: [[OBJ_RELOCATED1:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED1_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED1]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED1_CASTED]]
; CHECK-NEXT: [[OBJ_RELOCATED1:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED1]]
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad token
; CHECK-NEXT: cleanup
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obj = load <2 x ptr addrspace(1)>, ptr %ptr
invoke void @do_safepoint() [ "deopt"() ]
to label %normal_return unwind label %exceptional_return

normal_return: ; preds = %entry
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj

exceptional_return: ; preds = %entry
%landing_pad4 = landingpad token
cleanup
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

; A newly created vector
define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test5(ptr addrspace(1) %p) gc "statepoint-example" {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[P:%.*]], i32 0, !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> poison, i64 addrspace(1)* [[P]], i32 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[VEC]], <2 x i64 addrspace(1)*> [[VEC_BASE]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[VEC_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[VEC_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: [[VEC_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[VEC_BASE_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[VEC_BASE_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[VEC_RELOCATED_CASTED]]
; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x ptr addrspace(1)> zeroinitializer, ptr addrspace(1) [[P:%.*]], i32 0, !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x ptr addrspace(1)> poison, ptr addrspace(1) [[P]], i32 0
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[VEC]], <2 x ptr addrspace(1)> [[VEC_BASE]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[VEC_BASE_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[VEC_RELOCATED]]
;
entry:
%vec = insertelement <2 x i64 addrspace(1)*> poison, i64 addrspace(1)* %p, i32 0
%vec = insertelement <2 x ptr addrspace(1)> poison, ptr addrspace(1) %p, i32 0
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %vec
ret <2 x ptr addrspace(1)> %vec
}

; A merge point
define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test6(i1 %cnd, ptr %ptr) gc "statepoint-example" {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[CND:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
; CHECK: taken:
; CHECK-NEXT: [[OBJA:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[OBJA:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: untaken:
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x ptr addrspace(1)> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
br i1 %cnd, label %taken, label %untaken

taken: ; preds = %entry
%obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obja = load <2 x ptr addrspace(1)>, ptr %ptr
br label %merge

untaken: ; preds = %entry
%objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%objb = load <2 x ptr addrspace(1)>, ptr %ptr
br label %merge

merge: ; preds = %untaken, %taken
%obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
%obj = phi <2 x ptr addrspace(1)> [ %obja, %taken ], [ %objb, %untaken ]
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

declare void @do_safepoint()
102 changes: 47 additions & 55 deletions llvm/test/Transforms/RewriteStatepointsForGC/live-vector-nosplit.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,134 +4,126 @@
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s

; A non-vector relocation for comparison
define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
define ptr addrspace(1) @test(ptr addrspace(1) %obj) gc "statepoint-example" {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(ptr addrspace(1) [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret ptr addrspace(1) [[OBJ_RELOCATED]]
;
; A base vector from a argument
entry:
call void @do_safepoint() [ "deopt"() ]
ret i64 addrspace(1)* %obj
ret ptr addrspace(1) %obj
}

; A vector argument
define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test2(<2 x ptr addrspace(1)> %obj) gc "statepoint-example" {
; CHECK-LABEL: @test2(
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ:%.*]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

; A load
define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test3(ptr %ptr) gc "statepoint-example" {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obj = load <2 x ptr addrspace(1)>, ptr %ptr
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

declare i32 @fake_personality_function()

; When a statepoint is an invoke rather than a call
define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function {
define <2 x ptr addrspace(1)> @test4(ptr %ptr) gc "statepoint-example" personality ptr @fake_personality_function {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke 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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: [[OBJ_RELOCATED1:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED1_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED1]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED1_CASTED]]
; CHECK-NEXT: [[OBJ_RELOCATED1:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED1]]
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad token
; CHECK-NEXT: cleanup
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obj = load <2 x ptr addrspace(1)>, ptr %ptr
invoke void @do_safepoint() [ "deopt"() ]
to label %normal_return unwind label %exceptional_return

normal_return: ; preds = %entry
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj

exceptional_return: ; preds = %entry
%landing_pad4 = landingpad token
cleanup
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

; A newly created vector
define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test5(ptr addrspace(1) %p) gc "statepoint-example" {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[P:%.*]], i32 0, !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[P]], i32 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[VEC]], <2 x i64 addrspace(1)*> [[VEC_BASE]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[VEC_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[VEC_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: [[VEC_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[VEC_BASE_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[VEC_BASE_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[VEC_RELOCATED_CASTED]]
; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x ptr addrspace(1)> zeroinitializer, ptr addrspace(1) [[P:%.*]], i32 0, !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x ptr addrspace(1)> undef, ptr addrspace(1) [[P]], i32 0
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[VEC]], <2 x ptr addrspace(1)> [[VEC_BASE]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[VEC_BASE_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[VEC_RELOCATED]]
;
entry:
%vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
%vec = insertelement <2 x ptr addrspace(1)> undef, ptr addrspace(1) %p, i32 0
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %vec
ret <2 x ptr addrspace(1)> %vec
}

; A merge point
define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
define <2 x ptr addrspace(1)> @test6(i1 %cnd, ptr %ptr) gc "statepoint-example" {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[CND:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
; CHECK: taken:
; CHECK-NEXT: [[OBJA:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16
; CHECK-NEXT: [[OBJA:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR:%.*]], align 16
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: untaken:
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x ptr addrspace(1)>, ptr [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x ptr addrspace(1)> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[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) [ "deopt"(), "gc-live"(<2 x ptr addrspace(1)> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[OBJ_RELOCATED]]
;
entry:
br i1 %cnd, label %taken, label %untaken

taken: ; preds = %entry
%obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%obja = load <2 x ptr addrspace(1)>, ptr %ptr
br label %merge

untaken: ; preds = %entry
%objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
%objb = load <2 x ptr addrspace(1)>, ptr %ptr
br label %merge

merge: ; preds = %untaken, %taken
%obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
%obj = phi <2 x ptr addrspace(1)> [ %obja, %taken ], [ %objb, %untaken ]
call void @do_safepoint() [ "deopt"() ]
ret <2 x i64 addrspace(1)*> %obj
ret <2 x ptr addrspace(1)> %obj
}

declare void @do_safepoint()
36 changes: 18 additions & 18 deletions llvm/test/Transforms/RewriteStatepointsForGC/meetBDVState-hangs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,60 @@
; CHECK: test
target triple = "x86_64-unknown-linux-gnu"

declare void @bar(i8 addrspace(1)* nocapture readonly)
declare noalias i8 addrspace(1)* @foo()
declare void @bar(ptr addrspace(1) nocapture readonly)
declare noalias ptr addrspace(1) @foo()

define i8 addrspace(1)* @test(i1 %c, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5, i1 %c.exit) gc "statepoint-example" {
define ptr addrspace(1) @test(i1 %c, i1 %c1, i1 %c2, i1 %c3, i1 %c4, i1 %c5, i1 %c.exit) gc "statepoint-example" {
entry:
br i1 %c, label %ph.L, label %ph.R
ph.L:
%ph.L.p.b = call noalias nonnull i8 addrspace(1)* @foo()
%ph.L.p = getelementptr i8, i8 addrspace(1)* %ph.L.p.b, i64 8
%ph.L.p.b = call noalias nonnull ptr addrspace(1) @foo()
%ph.L.p = getelementptr i8, ptr addrspace(1) %ph.L.p.b, i64 8
br label %ph.M
ph.R:
%ph.R.p = call noalias nonnull i8 addrspace(1)* @foo()
%ph.R.p = call noalias nonnull ptr addrspace(1) @foo()
br label %ph.M
ph.M:
%ph.M.p = phi i8 addrspace(1)* [ %ph.L.p, %ph.L ], [ %ph.R.p, %ph.R ]
%ph.M.p = phi ptr addrspace(1) [ %ph.L.p, %ph.L ], [ %ph.R.p, %ph.R ]
br label %header

header:
%header.p = phi i8 addrspace(1)* [ %ph.M.p, %ph.M ], [ %backedge.p, %backedge]
%header.p = phi ptr addrspace(1) [ %ph.M.p, %ph.M ], [ %backedge.p, %backedge]
br i1 %c1, label %loop.M, label %loop.R

loop.R:
br i1 %c2, label %loop.R.M, label %loop.R.R

loop.R.R:
%loop.R.R.p = call noalias nonnull i8 addrspace(1)* @foo()
%loop.R.R.p = call noalias nonnull ptr addrspace(1) @foo()
br label %loop.R.M

loop.R.M:
%loop.R.M.p = phi i8 addrspace(1)* [ %header.p, %loop.R ], [ %loop.R.R.p, %loop.R.R ]
%loop.R.M.p = phi ptr addrspace(1) [ %header.p, %loop.R ], [ %loop.R.R.p, %loop.R.R ]
br label %loop.M

loop.M:
%loop.M.p = phi i8 addrspace(1)* [ %loop.R.M.p, %loop.R.M ], [ %header.p, %header ]
%loop.M.p = phi ptr addrspace(1) [ %loop.R.M.p, %loop.R.M ], [ %header.p, %header ]
br i1 %c4, label %backedge, label %pre.backedge.R

pre.backedge.R:
br i1 %c5, label %pre.backedge.R.L, label %pre.backedge.R.R
pre.backedge.R.L:
%pre.backedge.R.L.p.b = call noalias nonnull i8 addrspace(1)* @foo()
%pre.backedge.R.L.p = getelementptr i8, i8 addrspace(1)* %pre.backedge.R.L.p.b, i64 8
%pre.backedge.R.L.p.b = call noalias nonnull ptr addrspace(1) @foo()
%pre.backedge.R.L.p = getelementptr i8, ptr addrspace(1) %pre.backedge.R.L.p.b, i64 8
br label %pre.backedge.R.M
pre.backedge.R.R:
%pre.backedge.R.R.p = call noalias nonnull i8 addrspace(1)* @foo()
%pre.backedge.R.R.p = call noalias nonnull ptr addrspace(1) @foo()
br label %pre.backedge.R.M
pre.backedge.R.M:
%pre.backedge.R.M.p = phi i8 addrspace(1)* [ %pre.backedge.R.L.p, %pre.backedge.R.L ], [ %pre.backedge.R.R.p, %pre.backedge.R.R ]
%pre.backedge.R.M.p = phi ptr addrspace(1) [ %pre.backedge.R.L.p, %pre.backedge.R.L ], [ %pre.backedge.R.R.p, %pre.backedge.R.R ]
br label %backedge

backedge:
%backedge.p = phi i8 addrspace(1)* [ %pre.backedge.R.M.p, %pre.backedge.R.M ], [ %loop.M.p, %loop.M ]
%backedge.p = phi ptr addrspace(1) [ %pre.backedge.R.M.p, %pre.backedge.R.M ], [ %loop.M.p, %loop.M ]
br i1 %c.exit, label %header, label %exit

exit: ; preds = %3, %1
call void @bar(i8 addrspace(1)* align 8 %header.p) [ "deopt"() ]
ret i8 addrspace(1)* %header.p
call void @bar(ptr addrspace(1) align 8 %header.p) [ "deopt"() ]
ret ptr addrspace(1) %header.p
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
declare void @f()
declare i32 @personality_function()

define void @test_id() gc "statepoint-example" personality i32 ()* @personality_function {
define void @test_id() gc "statepoint-example" personality ptr @personality_function {
; CHECK-LABEL: @test_id(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 100, i32 0, void ()* elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 100, i32 0, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0)
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: ret void
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: ret void
;
Expand All @@ -23,19 +23,19 @@ normal_return:
ret void

exceptional_return:
%landing_pad4 = landingpad {i8*, i32} cleanup
%landing_pad4 = landingpad {ptr, i32} cleanup
ret void
}

define void @test_num_patch_bytes() gc "statepoint-example" personality i32 ()* @personality_function {
define void @test_num_patch_bytes() gc "statepoint-example" personality ptr @personality_function {
; CHECK-LABEL: @test_num_patch_bytes(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 99, void ()* elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 99, ptr elementtype(void ()) @f, i32 0, i32 0, i32 0, i32 0)
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: ret void
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: ret void
;
Expand All @@ -46,7 +46,7 @@ normal_return:
ret void

exceptional_return:
%landing_pad4 = landingpad {i8*, i32} cleanup
%landing_pad4 = landingpad {ptr, i32} cleanup
ret void
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

; We shouldn't crash when we encounter a vector phi with more than one input
; from the same predecessor.
define void @foo(<2 x i8 addrspace(1)*> %arg1, i32 %arg2, i1 %arg3, <2 x i64 addrspace(1)*> %arg4) gc "statepoint-example" personality i32* null {
define void @foo(<2 x ptr addrspace(1)> %arg1, i32 %arg2, i1 %arg3, <2 x ptr addrspace(1)> %arg4) gc "statepoint-example" personality ptr null {
bb:
%tmp = bitcast <2 x i8 addrspace(1)*> %arg1 to <2 x i64 addrspace(1)*>
%tmp = bitcast <2 x ptr addrspace(1)> %arg1 to <2 x ptr addrspace(1)>
switch i32 %arg2, label %bb2 [
i32 1, label %bb4
i32 2, label %bb4
Expand All @@ -15,9 +15,9 @@ bb2: ; preds = %bb
br i1 %arg3, label %bb8, label %bb4

bb4: ; preds = %bb2, %bb, %bb
%tmp5 = phi <2 x i64 addrspace(1)*> [ %tmp, %bb ], [ %tmp, %bb ], [ %arg4, %bb2 ]
%tmp5 = phi <2 x ptr addrspace(1)> [ %tmp, %bb ], [ %tmp, %bb ], [ %arg4, %bb2 ]
call void @bar()
%tmp6 = extractelement <2 x i64 addrspace(1)*> %tmp5, i32 1
%tmp6 = extractelement <2 x ptr addrspace(1)> %tmp5, i32 1
ret void

bb8: ; preds = %bb2
Expand Down
20 changes: 9 additions & 11 deletions llvm/test/Transforms/RewriteStatepointsForGC/pr55308.ll
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s

define void @test() gc "statepoint-example" personality i32* ()* @zot{
define void @test() gc "statepoint-example" personality ptr @zot{
; CHECK-LABEL: @test(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = freeze i8 addrspace(1)* undef
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[TMP]], i64 16
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8 addrspace(1)* [[TMP3]] to i32 addrspace(1)*
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @wibble, i32 0, i32 0, i32 0, i32 0) [ "deopt"() ]
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[TMP4]], i64 undef
; CHECK-NEXT: [[TMP:%.*]] = freeze ptr addrspace(1) undef
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[TMP]], i64 16
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @wibble, i32 0, i32 0, i32 0, i32 0) [ "deopt"() ]
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr addrspace(1) [[TMP3]], i64 undef
; CHECK-NEXT: ret void
;
bb:
%tmp = freeze i8 addrspace(1)* undef
%tmp3 = getelementptr inbounds i8, i8 addrspace(1)* %tmp, i64 16
%tmp4 = bitcast i8 addrspace(1)* %tmp3 to i32 addrspace(1)*
%tmp = freeze ptr addrspace(1) undef
%tmp3 = getelementptr inbounds i8, ptr addrspace(1) %tmp, i64 16
call void @wibble() #3 [ "deopt"() ]
%tmp5 = getelementptr inbounds i32, i32 addrspace(1)* %tmp4, i64 undef
%tmp5 = getelementptr inbounds i32, ptr addrspace(1) %tmp3, i64 undef
ret void
}

declare i32* @zot()
declare ptr @zot()

declare void @wibble()
10 changes: 5 additions & 5 deletions llvm/test/Transforms/RewriteStatepointsForGC/pr56493.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
; RUN: opt -passes=rewrite-statepoints-for-gc -S < %s | FileCheck %s

; Make sure this doesn't crash.
define void @test() gc "statepoint-example" personality i32* ()* @zot {
define void @test() gc "statepoint-example" personality ptr @zot {
; CHECK-LABEL: @test(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void (i32 addrspace(1)*, i64, i32 addrspace(1)*, i64, i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i32i64p1i32i64i64f(i64 2882400000, i32 0, void (i32 addrspace(1)*, i64, i32 addrspace(1)*, i64, i64)* elementtype(void (i32 addrspace(1)*, i64, i32 addrspace(1)*, i64, i64)) @__llvm_memcpy_element_unordered_atomic_safepoint_4, i32 5, i32 0, i32 addrspace(1)* null, i64 undef, i32 addrspace(1)* null, i64 ptrtoint (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 16) to i64), i64 undef, i32 0, i32 0) [ "deopt"() ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void (ptr addrspace(1), i64, ptr addrspace(1), i64, i64)) @__llvm_memcpy_element_unordered_atomic_safepoint_4, i32 5, i32 0, ptr addrspace(1) null, i64 undef, ptr addrspace(1) null, i64 ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) null, i64 16) to i64), i64 undef, i32 0, i32 0) [ "deopt"() ]
; CHECK-NEXT: ret void
;
bb:
call void @llvm.memcpy.element.unordered.atomic.p1i32.p1i32.i64(i32 addrspace(1)* elementtype(i32) align 8 undef, i32 addrspace(1)* elementtype(i32) align 16 bitcast (i8 addrspace(1)* getelementptr inbounds (i8, i8 addrspace(1)* null, i64 16) to i32 addrspace(1)*), i64 undef, i32 4) #3 [ "deopt"() ]
call void @llvm.memcpy.element.unordered.atomic.p1.p1.i64(ptr addrspace(1) elementtype(i32) align 8 undef, ptr addrspace(1) elementtype(i32) align 16 getelementptr inbounds (i8, ptr addrspace(1) null, i64 16), i64 undef, i32 4) #3 [ "deopt"() ]
ret void
}

declare i32* @zot()
declare ptr @zot()

declare void @llvm.memcpy.element.unordered.atomic.p1i32.p1i32.i64(i32 addrspace(1)* nocapture writeonly, i32 addrspace(1)* nocapture readonly, i64, i32 immarg)
declare void @llvm.memcpy.element.unordered.atomic.p1.p1.i64(ptr addrspace(1) nocapture writeonly, ptr addrspace(1) nocapture readonly, i64, i32 immarg)

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions llvm/test/Transforms/RewriteStatepointsForGC/rewrite-invoke.ll
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
; RUN: opt -passes=rewrite-statepoints-for-gc,verify -S < %s | FileCheck %s

declare i8 addrspace(1)* @gc_call()
declare ptr addrspace(1) @gc_call()

declare i32* @fake_personality_function()
declare ptr @fake_personality_function()

define i8 addrspace(1)* @test(i1 %c) gc "statepoint-example" personality i32* ()* @fake_personality_function {
define ptr addrspace(1) @test(i1 %c) gc "statepoint-example" personality ptr @fake_personality_function {
; CHECK-LABEL: @test(
entry:
br i1 %c, label %gc_invoke, label %normal_dest

gc_invoke:
; CHECK: [[TOKEN:%[^ ]+]] = invoke token {{[^@]+}}@llvm.experimental.gc.statepoint{{[^@]+}}@gc_call
%obj = invoke i8 addrspace(1)* @gc_call() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
%obj = invoke ptr addrspace(1) @gc_call() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
to label %normal_dest unwind label %unwind_dest

unwind_dest:
; CHECK: unwind_dest:
%lpad = landingpad { i8*, i32 }
%lpad = landingpad { ptr, i32 }
cleanup
resume { i8*, i32 } undef
resume { ptr, i32 } undef

; CHECK: [[NORMAL_DEST_SPLIT:[^:]+:]]
; CHECK-NEXT: [[RET_VAL:%[^ ]+]] = call i8 addrspace(1)* @llvm.experimental.gc.result.p1i8(token [[TOKEN]])
; CHECK-NEXT: [[RET_VAL:%[^ ]+]] = call ptr addrspace(1) @llvm.experimental.gc.result.p1(token [[TOKEN]])
; CHECK-NEXT: br label %normal_dest

normal_dest:
; CHECK: normal_dest:
; CHECK-NEXT: %merge = phi i8 addrspace(1)* [ null, %entry ], [ %obj2, %normal_dest1 ]
%merge = phi i8 addrspace(1)* [ null, %entry ], [ %obj, %gc_invoke ]
ret i8 addrspace(1)* %merge
; CHECK-NEXT: %merge = phi ptr addrspace(1) [ null, %entry ], [ %obj2, %normal_dest1 ]
%merge = phi ptr addrspace(1) [ null, %entry ], [ %obj, %gc_invoke ]
ret ptr addrspace(1) %merge
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,68 +8,68 @@
define void @widget() gc "statepoint-example" {
; CHECK-LABEL: @widget(
; CHECK-NEXT: bb6:
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x i8 addrspace(1)*> zeroinitializer, i32 1, !is_base_value !0
; CHECK-NEXT: [[TMP:%.*]] = extractelement <2 x i8 addrspace(1)*> undef, i32 1
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x ptr addrspace(1)> zeroinitializer, i32 1, !is_base_value !0
; CHECK-NEXT: [[TMP:%.*]] = extractelement <2 x ptr addrspace(1)> undef, i32 1
; CHECK-NEXT: br i1 undef, label [[BB7:%.*]], label [[BB9:%.*]]
; CHECK: bb7:
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[TMP]], i64 12
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[TMP]], i64 12
; CHECK-NEXT: br label [[BB11:%.*]]
; CHECK: bb9:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[TMP]], i64 12
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[TMP]], i64 12
; CHECK-NEXT: br i1 undef, label [[BB11]], label [[BB15:%.*]]
; CHECK: bb11:
; CHECK-NEXT: [[TMP12_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE_EE]], [[BB7]] ], [ [[BASE_EE]], [[BB9]] ], !is_base_value !0
; CHECK-NEXT: [[TMP12:%.*]] = phi i8 addrspace(1)* [ [[TMP8]], [[BB7]] ], [ [[TMP10]], [[BB9]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @snork, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 undef), "gc-live"(i8 addrspace(1)* [[TMP12_BASE]], i8 addrspace(1)* [[TMP12]]) ]
; CHECK-NEXT: [[TMP12_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[TMP12_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 1)
; CHECK-NEXT: [[TMP12_BASE:%.*]] = phi ptr addrspace(1) [ [[BASE_EE]], [[BB7]] ], [ [[BASE_EE]], [[BB9]] ], !is_base_value !0
; CHECK-NEXT: [[TMP12:%.*]] = phi ptr addrspace(1) [ [[TMP8]], [[BB7]] ], [ [[TMP10]], [[BB9]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @snork, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 undef), "gc-live"(ptr addrspace(1) [[TMP12_BASE]], ptr addrspace(1) [[TMP12]]) ]
; CHECK-NEXT: [[TMP12_BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[TMP12_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 1)
; CHECK-NEXT: br label [[BB15]]
; CHECK: bb15:
; CHECK-NEXT: [[TMP16_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE_EE]], [[BB9]] ], [ [[TMP12_BASE_RELOCATED]], [[BB11]] ], !is_base_value !0
; CHECK-NEXT: [[TMP16:%.*]] = phi i8 addrspace(1)* [ [[TMP10]], [[BB9]] ], [ [[TMP12_RELOCATED]], [[BB11]] ]
; CHECK-NEXT: [[TMP16_BASE:%.*]] = phi ptr addrspace(1) [ [[BASE_EE]], [[BB9]] ], [ [[TMP12_BASE_RELOCATED]], [[BB11]] ], !is_base_value !0
; CHECK-NEXT: [[TMP16:%.*]] = phi ptr addrspace(1) [ [[TMP10]], [[BB9]] ], [ [[TMP12_RELOCATED]], [[BB11]] ]
; CHECK-NEXT: br i1 undef, label [[BB17:%.*]], label [[BB20:%.*]]
; CHECK: bb17:
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @snork, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 undef), "gc-live"(i8 addrspace(1)* [[TMP16_BASE]], i8 addrspace(1)* [[TMP16]]) ]
; CHECK-NEXT: [[TMP16_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 0, i32 0)
; CHECK-NEXT: [[TMP16_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 0, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @snork, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 undef), "gc-live"(ptr addrspace(1) [[TMP16_BASE]], ptr addrspace(1) [[TMP16]]) ]
; CHECK-NEXT: [[TMP16_BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN1]], i32 0, i32 0)
; CHECK-NEXT: [[TMP16_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN1]], i32 0, i32 1)
; CHECK-NEXT: br label [[BB20]]
; CHECK: bb20:
; CHECK-DAG: [[DOT05:%.*]] = phi i8 addrspace(1)* [ [[TMP16_BASE_RELOCATED]], [[BB17]] ], [ [[TMP16_BASE]], [[BB15]] ]
; CHECK-DAG: [[DOT0:%.*]] = phi i8 addrspace(1)* [ [[TMP16_RELOCATED]], [[BB17]] ], [ [[TMP16]], [[BB15]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64 2882400000, i32 0, void (i8 addrspace(1)*)* elementtype(void (i8 addrspace(1)*)) @foo, i32 1, i32 0, i8 addrspace(1)* [[DOT0]], i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[DOT05]], i8 addrspace(1)* [[DOT0]]) ]
; CHECK-NEXT: [[TMP16_BASE_RELOCATED3:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 0, i32 0)
; CHECK-NEXT: [[TMP16_RELOCATED4:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN2]], i32 0, i32 1)
; CHECK-DAG: [[DOT05:%.*]] = phi ptr addrspace(1) [ [[TMP16_BASE_RELOCATED]], [[BB17]] ], [ [[TMP16_BASE]], [[BB15]] ]
; CHECK-DAG: [[DOT0:%.*]] = phi ptr addrspace(1) [ [[TMP16_RELOCATED]], [[BB17]] ], [ [[TMP16]], [[BB15]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN2:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void (ptr addrspace(1))) @foo, i32 1, i32 0, ptr addrspace(1) [[DOT0]], i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[DOT05]], ptr addrspace(1) [[DOT0]]) ]
; CHECK-NEXT: [[TMP16_BASE_RELOCATED3:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN2]], i32 0, i32 0)
; CHECK-NEXT: [[TMP16_RELOCATED4:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN2]], i32 0, i32 1)
; CHECK-NEXT: ret void
;
bb6: ; preds = %bb3
%tmp = extractelement <2 x i8 addrspace(1)*> undef, i32 1
%tmp = extractelement <2 x ptr addrspace(1)> undef, i32 1
br i1 undef, label %bb7, label %bb9

bb7: ; preds = %bb6
%tmp8 = getelementptr inbounds i8, i8 addrspace(1)* %tmp, i64 12
%tmp8 = getelementptr inbounds i8, ptr addrspace(1) %tmp, i64 12
br label %bb11

bb9: ; preds = %bb6, %bb6
%tmp10 = getelementptr inbounds i8, i8 addrspace(1)* %tmp, i64 12
%tmp10 = getelementptr inbounds i8, ptr addrspace(1) %tmp, i64 12
br i1 undef, label %bb11, label %bb15

bb11: ; preds = %bb9, %bb7
%tmp12 = phi i8 addrspace(1)* [ %tmp8, %bb7 ], [ %tmp10, %bb9 ]
%tmp12 = phi ptr addrspace(1) [ %tmp8, %bb7 ], [ %tmp10, %bb9 ]
call void @snork() [ "deopt"(i32 undef) ]
br label %bb15

bb15: ; preds = %bb11, %bb9, %bb9
%tmp16 = phi i8 addrspace(1)* [ %tmp10, %bb9 ], [ %tmp12, %bb11 ]
%tmp16 = phi ptr addrspace(1) [ %tmp10, %bb9 ], [ %tmp12, %bb11 ]
br i1 undef, label %bb17, label %bb20

bb17: ; preds = %bb15
call void @snork() [ "deopt"(i32 undef) ]
br label %bb20

bb20: ; preds = %bb17, %bb15, %bb15
call void @foo(i8 addrspace(1)* %tmp16)
call void @foo(ptr addrspace(1) %tmp16)
ret void
}

declare void @snork()
declare void @foo(i8 addrspace(1)*)
declare void @foo(ptr addrspace(1))
194 changes: 89 additions & 105 deletions llvm/test/Transforms/RewriteStatepointsForGC/scalar-base-vector.ll

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions llvm/test/Transforms/RewriteStatepointsForGC/single-base.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,38 @@ target triple = "x86_64-unknown-linux-gnu"
declare void @foo() gc "statepoint-example"
declare i1 @runtime_value() "gc-leaf-function"

define i8 addrspace(1)* @test1(i8 addrspace(1)* %b1, i8 addrspace(1)* %b2) gc "statepoint-example" {
define ptr addrspace(1) @test1(ptr addrspace(1) %b1, ptr addrspace(1) %b2) gc "statepoint-example" {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[B5:%.*]] = phi i8 addrspace(1)* [ [[B1:%.*]], [[ENTRY:%.*]] ], [ [[B6:%.*]], [[INNER_LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[B5:%.*]] = phi ptr addrspace(1) [ [[B1:%.*]], [[ENTRY:%.*]] ], [ [[B6:%.*]], [[INNER_LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[C1:%.*]] = call i1 @runtime_value()
; CHECK-NEXT: br i1 [[C1]], label [[INNER_LOOP:%.*]], label [[EXIT:%.*]]
; CHECK: inner_loop:
; CHECK-NEXT: [[B6]] = phi i8 addrspace(1)* [ [[B5]], [[LOOP]] ], [ [[B6]], [[INNER_LOOP]] ]
; CHECK-NEXT: [[B6]] = phi ptr addrspace(1) [ [[B5]], [[LOOP]] ], [ [[B6]], [[INNER_LOOP]] ]
; CHECK-NEXT: [[C2:%.*]] = call i1 @runtime_value()
; CHECK-NEXT: br i1 [[C2]], label [[INNER_LOOP]], label [[INNER_LOOP_LATCH]]
; CHECK: inner_loop_latch:
; CHECK-NEXT: [[C3:%.*]] = call i1 @runtime_value()
; CHECK-NEXT: br i1 [[C3]], label [[LOOP]], label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: [[MERGE:%.*]] = phi i8 addrspace(1)* [ [[B5]], [[LOOP]] ], [ [[B6]], [[INNER_LOOP_LATCH]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i8 addrspace(1)* [[MERGE]], i8 addrspace(1)* [[B1]]) ]
; CHECK-NEXT: [[MERGE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[B1_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret i8 addrspace(1)* [[MERGE_RELOCATED]]
; CHECK-NEXT: [[MERGE:%.*]] = phi ptr addrspace(1) [ [[B5]], [[LOOP]] ], [ [[B6]], [[INNER_LOOP_LATCH]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[MERGE]], ptr addrspace(1) [[B1]]) ]
; CHECK-NEXT: [[MERGE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[B1_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[MERGE_RELOCATED]]
;
entry:
br label %loop

loop:
%b5 = phi i8 addrspace(1)* [ %b1, %entry ], [ %b6, %inner_loop_latch ]
%b5 = phi ptr addrspace(1) [ %b1, %entry ], [ %b6, %inner_loop_latch ]
%c1 = call i1 @runtime_value()
br i1 %c1, label %inner_loop, label %exit

inner_loop:
%b6 = phi i8 addrspace(1)* [ %b5, %loop ], [ %b6, %inner_loop ]
%b6 = phi ptr addrspace(1) [ %b5, %loop ], [ %b6, %inner_loop ]
%c2 = call i1 @runtime_value()
br i1 %c2, label %inner_loop, label %inner_loop_latch

Expand All @@ -47,36 +47,36 @@ inner_loop_latch:
br i1 %c3, label %loop, label %exit

exit:
%merge = phi i8 addrspace(1)* [ %b5, %loop ], [ %b6, %inner_loop_latch ]
%merge = phi ptr addrspace(1) [ %b5, %loop ], [ %b6, %inner_loop_latch ]
call void @foo() [ "deopt"() ]
ret i8 addrspace(1)* %merge
ret ptr addrspace(1) %merge
}

define i8 addrspace(1)* @swap(i8 addrspace(1)* %b1, i8 addrspace(1)* %b2) gc "statepoint-example" {
define ptr addrspace(1) @swap(ptr addrspace(1) %b1, ptr addrspace(1) %b2) gc "statepoint-example" {
; CHECK-LABEL: @swap(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[B5:%.*]] = phi i8 addrspace(1)* [ [[B1:%.*]], [[ENTRY:%.*]] ], [ [[B6:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[B6]] = phi i8 addrspace(1)* [ [[B1]], [[ENTRY]] ], [ [[B5]], [[LOOP]] ]
; CHECK-NEXT: [[B5:%.*]] = phi ptr addrspace(1) [ [[B1:%.*]], [[ENTRY:%.*]] ], [ [[B6:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[B6]] = phi ptr addrspace(1) [ [[B1]], [[ENTRY]] ], [ [[B5]], [[LOOP]] ]
; CHECK-NEXT: [[C1:%.*]] = call i1 @runtime_value()
; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i8 addrspace(1)* [[B6]], i8 addrspace(1)* [[B1]]) ]
; CHECK-NEXT: [[B6_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[B1_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret i8 addrspace(1)* [[B6_RELOCATED]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[B6]], ptr addrspace(1) [[B1]]) ]
; CHECK-NEXT: [[B6_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[B1_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[B6_RELOCATED]]
;
entry:
br label %loop

loop:
%b5 = phi i8 addrspace(1)* [ %b1, %entry ], [ %b6, %loop ]
%b6 = phi i8 addrspace(1)* [ %b1, %entry ], [ %b5, %loop ]
%b5 = phi ptr addrspace(1) [ %b1, %entry ], [ %b6, %loop ]
%b6 = phi ptr addrspace(1) [ %b1, %entry ], [ %b5, %loop ]
%c1 = call i1 @runtime_value()
br i1 %c1, label %loop, label %exit

exit:
call void @foo() [ "deopt"() ]
ret i8 addrspace(1)* %b6
ret ptr addrspace(1) %b6
}
10 changes: 5 additions & 5 deletions llvm/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
; Ensure statepoints copy (valid) attributes from callsites.

declare void @f(i8 addrspace(1)* %obj)
declare void @f(ptr addrspace(1) %obj)

; copy over norecurse noimplicitfloat to statepoint call
define void @test1(i8 addrspace(1)* %arg) gc "statepoint-example" {
define void @test1(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64 2882400000, i32 0, void (i8 addrspace(1)*)* elementtype(void (i8 addrspace(1)*)) @f, i32 1, i32 0, i8 addrspace(1)* [[ARG:%.*]], i32 0, i32 0) #[[ATTR1:[0-9]+]] [ "gc-live"(i8 addrspace(1)* [[ARG]]) ]
; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void (ptr addrspace(1))) @f, i32 1, i32 0, ptr addrspace(1) [[ARG:%.*]], i32 0, i32 0) #[[ATTR1:[0-9]+]] [ "gc-live"(ptr addrspace(1) [[ARG]]) ]
; CHECK-NEXT: [[ARG_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret void
;

call void @f(i8 addrspace(1)* %arg) #1
call void @f(ptr addrspace(1) %arg) #1
ret void
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,47 @@
; Ensure that the gc.statepoint calls / invokes we generate carry over
; the right calling conventions.

define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
define ptr addrspace(1) @test_invoke_format(ptr addrspace(1) %obj, ptr addrspace(1) %obj1) gc "statepoint-example" personality ptr @personality {
; CHECK-LABEL: @test_invoke_format(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* elementtype(i64 addrspace(1)* (i64 addrspace(1)*)) @callee, i32 1, i32 0, i64 addrspace(1)* [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(i64 addrspace(1)* [[OBJ1:%.*]], i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke coldcc token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(ptr addrspace(1) (ptr addrspace(1))) @callee, i32 1, i32 0, ptr addrspace(1) [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[OBJ1:%.*]], ptr addrspace(1) [[OBJ]]) ]
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: [[RET_VAL1:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ1_RELOCATED2:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ1_RELOCATED2_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ1_RELOCATED2]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_RELOCATED3:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_RELOCATED3_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED3]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[RET_VAL1]]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.result.p1(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ1_RELOCATED2:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED3:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[RET_VAL1]]
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad token
; CHECK-NEXT: cleanup
; CHECK-NEXT: [[OBJ1_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ1_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ1_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LANDING_PAD4]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ1_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ1_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[OBJ1_RELOCATED]]
;
entry:
%ret_val = invoke coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
%ret_val = invoke coldcc ptr addrspace(1) @callee(ptr addrspace(1) %obj)
to label %normal_return unwind label %exceptional_return

normal_return:
ret i64 addrspace(1)* %ret_val
ret ptr addrspace(1) %ret_val

exceptional_return:
%landing_pad4 = landingpad token
cleanup
ret i64 addrspace(1)* %obj1
ret ptr addrspace(1) %obj1
}

define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
define ptr addrspace(1) @test_call_format(ptr addrspace(1) %obj, ptr addrspace(1) %obj1) gc "statepoint-example" {
; CHECK-LABEL: @test_call_format(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* elementtype(i64 addrspace(1)* (i64 addrspace(1)*)) @callee, i32 1, i32 0, i64 addrspace(1)* [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[RET_VAL1]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call coldcc token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(ptr addrspace(1) (ptr addrspace(1))) @callee, i32 1, i32 0, ptr addrspace(1) [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[OBJ]]) ]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.result.p1(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret ptr addrspace(1) [[RET_VAL1]]
;
entry:
%ret_val = call coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
ret i64 addrspace(1)* %ret_val
%ret_val = call coldcc ptr addrspace(1) @callee(ptr addrspace(1) %obj)
ret ptr addrspace(1) %ret_val
}

; This function is inlined when inserting a poll.
Expand All @@ -65,5 +60,5 @@ entry:
ret void
}

declare coldcc i64 addrspace(1)* @callee(i64 addrspace(1)*)
declare coldcc ptr addrspace(1) @callee(ptr addrspace(1))
declare i32 @personality()
45 changes: 20 additions & 25 deletions llvm/test/Transforms/RewriteStatepointsForGC/statepoint-format.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,47 @@
; Ensure that the gc.statepoint calls / invokes we generate have the
; set of arguments we expect it to have.

define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
define ptr addrspace(1) @test_invoke_format(ptr addrspace(1) %obj, ptr addrspace(1) %obj1) gc "statepoint-example" personality ptr @personality {
; CHECK-LABEL: @test_invoke_format(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* elementtype(i64 addrspace(1)* (i64 addrspace(1)*)) @callee, i32 1, i32 0, i64 addrspace(1)* [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(i64 addrspace(1)* [[OBJ1:%.*]], i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(ptr addrspace(1) (ptr addrspace(1))) @callee, i32 1, i32 0, ptr addrspace(1) [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[OBJ1:%.*]], ptr addrspace(1) [[OBJ]]) ]
; CHECK-NEXT: to label [[NORMAL_RETURN:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
; CHECK: normal_return:
; CHECK-NEXT: [[RET_VAL1:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ1_RELOCATED2:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ1_RELOCATED2_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ1_RELOCATED2]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_RELOCATED3:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_RELOCATED3_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED3]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[RET_VAL1]]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.result.p1(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ1_RELOCATED2:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED3:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[RET_VAL1]]
; CHECK: exceptional_return:
; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad token
; CHECK-NEXT: cleanup
; CHECK-NEXT: [[OBJ1_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ1_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ1_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[LANDING_PAD4]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ1_RELOCATED_CASTED]]
; CHECK-NEXT: [[OBJ1_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 1, i32 1)
; CHECK-NEXT: ret ptr addrspace(1) [[OBJ1_RELOCATED]]
;
entry:
%ret_val = invoke i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
%ret_val = invoke ptr addrspace(1) @callee(ptr addrspace(1) %obj)
to label %normal_return unwind label %exceptional_return

normal_return:
ret i64 addrspace(1)* %ret_val
ret ptr addrspace(1) %ret_val

exceptional_return:
%landing_pad4 = landingpad token
cleanup
ret i64 addrspace(1)* %obj1
ret ptr addrspace(1) %obj1
}

define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
define ptr addrspace(1) @test_call_format(ptr addrspace(1) %obj, ptr addrspace(1) %obj1) gc "statepoint-example" {
; CHECK-LABEL: @test_call_format(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* elementtype(i64 addrspace(1)* (i64 addrspace(1)*)) @callee, i32 1, i32 0, i64 addrspace(1)* [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[RET_VAL1]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(ptr addrspace(1) (ptr addrspace(1))) @callee, i32 1, i32 0, ptr addrspace(1) [[OBJ:%.*]], i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[OBJ]]) ]
; CHECK-NEXT: [[RET_VAL1:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.result.p1(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret ptr addrspace(1) [[RET_VAL1]]
;
entry:
%ret_val = call i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
ret i64 addrspace(1)* %ret_val
%ret_val = call ptr addrspace(1) @callee(ptr addrspace(1) %obj)
ret ptr addrspace(1) %ret_val
}

; This function is inlined when inserting a poll.
Expand All @@ -65,5 +60,5 @@ entry:
ret void
}

declare i64 addrspace(1)* @callee(i64 addrspace(1)*)
declare ptr addrspace(1) @callee(ptr addrspace(1))
declare i32 @personality()
Original file line number Diff line number Diff line change
Expand Up @@ -6,87 +6,87 @@

declare void @f()

define i8 addrspace(1)* @deref_arg(i8 addrspace(1)* dereferenceable(16) %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @deref_arg(i8 addrspace(1)* %arg)
define ptr addrspace(1) @deref_arg(ptr addrspace(1) dereferenceable(16) %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @deref_arg(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define dereferenceable(16) i8 addrspace(1)* @deref_ret(i8 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @deref_ret(i8 addrspace(1)* %arg)
define dereferenceable(16) ptr addrspace(1) @deref_ret(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @deref_ret(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @deref_or_null_arg(i8 addrspace(1)* dereferenceable_or_null(16) %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @deref_or_null_arg(i8 addrspace(1)* %arg)
define ptr addrspace(1) @deref_or_null_arg(ptr addrspace(1) dereferenceable_or_null(16) %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @deref_or_null_arg(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define dereferenceable_or_null(16) i8 addrspace(1)* @deref_or_null_ret(i8 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @deref_or_null_ret(i8 addrspace(1)* %arg)
define dereferenceable_or_null(16) ptr addrspace(1) @deref_or_null_ret(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @deref_or_null_ret(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @noalias_arg(i8 addrspace(1)* noalias %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @noalias_arg(i8 addrspace(1)* %arg)
define ptr addrspace(1) @noalias_arg(ptr addrspace(1) noalias %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @noalias_arg(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define noalias i8 addrspace(1)* @noalias_ret(i8 addrspace(1)* %arg) gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @noalias_ret(i8 addrspace(1)* %arg)
define noalias ptr addrspace(1) @noalias_ret(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @noalias_ret(ptr addrspace(1) %arg)
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @nofree(i8 addrspace(1)* nofree %arg) nofree gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @nofree(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @nofree(ptr addrspace(1) nofree %arg) nofree gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @nofree(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @nosync(i8 addrspace(1)* %arg) nosync gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @nosync(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @nosync(ptr addrspace(1) %arg) nosync gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @nosync(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @readnone(i8 addrspace(1)* readnone %arg) readnone gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @readnone(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @readnone(ptr addrspace(1) readnone %arg) readnone gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @readnone(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @readonly(i8 addrspace(1)* readonly %arg) readonly gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @readonly(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @readonly(ptr addrspace(1) readonly %arg) readonly gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @readonly(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @writeonly(i8 addrspace(1)* writeonly %arg) writeonly gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @writeonly(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @writeonly(ptr addrspace(1) writeonly %arg) writeonly gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @writeonly(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @argmemonly(i8 addrspace(1)* %arg) argmemonly gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @argmemonly(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @argmemonly(ptr addrspace(1) %arg) argmemonly gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @argmemonly(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @inaccessiblememonly(i8 addrspace(1)* %arg) inaccessiblememonly gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @inaccessiblememonly(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @inaccessiblememonly(ptr addrspace(1) %arg) inaccessiblememonly gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @inaccessiblememonly(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

define i8 addrspace(1)* @inaccessiblemem_or_argmemonly(i8 addrspace(1)* %arg) inaccessiblemem_or_argmemonly gc "statepoint-example" {
; CHECK: define i8 addrspace(1)* @inaccessiblemem_or_argmemonly(i8 addrspace(1)* %arg) gc "statepoint-example" {
define ptr addrspace(1) @inaccessiblemem_or_argmemonly(ptr addrspace(1) %arg) inaccessiblemem_or_argmemonly gc "statepoint-example" {
; CHECK: define ptr addrspace(1) @inaccessiblemem_or_argmemonly(ptr addrspace(1) %arg) gc "statepoint-example" {
call void @f()
ret i8 addrspace(1)* %arg
ret ptr addrspace(1) %arg
}

Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s

declare void @some_call(i64 addrspace(1)*)
declare void @some_call(ptr addrspace(1))

declare i32 @dummy_personality_function()

define i64 addrspace(1)* @test(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
define ptr addrspace(1) @test(ptr addrspace(1) %obj, ptr addrspace(1) %obj1)
gc "statepoint-example"
personality i32 ()* @dummy_personality_function {
personality ptr @dummy_personality_function {
entry:
invoke void @some_call(i64 addrspace(1)* %obj) [ "deopt"() ]
invoke void @some_call(ptr addrspace(1) %obj) [ "deopt"() ]
to label %second_invoke unwind label %exceptional_return

second_invoke: ; preds = %entry
invoke void @some_call(i64 addrspace(1)* %obj) [ "deopt"() ]
invoke void @some_call(ptr addrspace(1) %obj) [ "deopt"() ]
to label %normal_return unwind label %exceptional_return

normal_return: ; preds = %second_invoke
ret i64 addrspace(1)* %obj
ret ptr addrspace(1) %obj

; CHECK: exceptional_return1:
; CHECK-NEXT: %lpad2 = landingpad token
Expand All @@ -29,5 +29,5 @@ normal_return: ; preds = %second_invoke

exceptional_return: ; preds = %second_invoke, %entry
%lpad = landingpad token cleanup
ret i64 addrspace(1)* %obj1
ret ptr addrspace(1) %obj1
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,49 @@
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.11.0"

declare void @llvm.memcpy.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)*, i8 addrspace(1)*, i32, i32 immarg)
declare void @llvm.memmove.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)*, i8 addrspace(1)*, i32, i32 immarg)
declare void @llvm.memcpy.element.unordered.atomic.p1.p1.i32(ptr addrspace(1), ptr addrspace(1), i32, i32 immarg)
declare void @llvm.memmove.element.unordered.atomic.p1.p1.i32(ptr addrspace(1), ptr addrspace(1), i32, i32 immarg)

define void @test_memcpy_no_deopt(i8 addrspace(1)* %src, i64 %src_offset, i8 addrspace(1)* %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
define void @test_memcpy_no_deopt(ptr addrspace(1) %src, i64 %src_offset, ptr addrspace(1) %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
; CHECK-LABEL: @test_memcpy_no_deopt
; CHECK-REQUIRE-DEOPT-NOT: @llvm.experimental.gc.statepoint
; CHECK-NO-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
entry:
%src_derived = getelementptr inbounds i8, i8 addrspace(1)* %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, i8 addrspace(1)* %dest, i64 %dest_offset
call void @llvm.memcpy.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)* align 16 %src_derived, i8 addrspace(1)* align 16 %dest_derived, i32 %len, i32 1)
%src_derived = getelementptr inbounds i8, ptr addrspace(1) %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %dest_offset
call void @llvm.memcpy.element.unordered.atomic.p1.p1.i32(ptr addrspace(1) align 16 %src_derived, ptr addrspace(1) align 16 %dest_derived, i32 %len, i32 1)
ret void
}

define void @test_memmove_no_deopt(i8 addrspace(1)* %src, i64 %src_offset, i8 addrspace(1)* %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
define void @test_memmove_no_deopt(ptr addrspace(1) %src, i64 %src_offset, ptr addrspace(1) %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
; CHECK-LABEL: @test_memmove_no_deopt
; CHECK-REQUIRE-DEOPT-NOT: @llvm.experimental.gc.statepoint
; CHECK-NO-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
entry:
%src_derived = getelementptr inbounds i8, i8 addrspace(1)* %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, i8 addrspace(1)* %dest, i64 %dest_offset
call void @llvm.memmove.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)* align 16 %src_derived, i8 addrspace(1)* align 16 %dest_derived, i32 %len, i32 1)
%src_derived = getelementptr inbounds i8, ptr addrspace(1) %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %dest_offset
call void @llvm.memmove.element.unordered.atomic.p1.p1.i32(ptr addrspace(1) align 16 %src_derived, ptr addrspace(1) align 16 %dest_derived, i32 %len, i32 1)
ret void
}

define void @test_memcpy_with_deopt(i8 addrspace(1)* %src, i64 %src_offset, i8 addrspace(1)* %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
define void @test_memcpy_with_deopt(ptr addrspace(1) %src, i64 %src_offset, ptr addrspace(1) %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
; CHECK-LABEL: @test_memcpy_with_deopt
; CHECK-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
; CHECK-NO-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
entry:
%src_derived = getelementptr inbounds i8, i8 addrspace(1)* %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, i8 addrspace(1)* %dest, i64 %dest_offset
call void @llvm.memcpy.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)* align 16 %src_derived, i8 addrspace(1)* align 16 %dest_derived, i32 %len, i32 1) [ "deopt"(i32 0) ]
%src_derived = getelementptr inbounds i8, ptr addrspace(1) %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %dest_offset
call void @llvm.memcpy.element.unordered.atomic.p1.p1.i32(ptr addrspace(1) align 16 %src_derived, ptr addrspace(1) align 16 %dest_derived, i32 %len, i32 1) [ "deopt"(i32 0) ]
ret void
}

define void @test_memmove_with_deopt(i8 addrspace(1)* %src, i64 %src_offset, i8 addrspace(1)* %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
define void @test_memmove_with_deopt(ptr addrspace(1) %src, i64 %src_offset, ptr addrspace(1) %dest, i64 %dest_offset, i32 %len) gc "statepoint-example" {
; CHECK-LABEL: @test_memmove_with_deopt
; CHECK-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
; CHECK-NO-REQUIRE-DEOPT: @llvm.experimental.gc.statepoint
entry:
%src_derived = getelementptr inbounds i8, i8 addrspace(1)* %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, i8 addrspace(1)* %dest, i64 %dest_offset
call void @llvm.memmove.element.unordered.atomic.p1i8.p1i8.i32(i8 addrspace(1)* align 16 %src_derived, i8 addrspace(1)* align 16 %dest_derived, i32 %len, i32 1) [ "deopt"(i32 0) ]
%src_derived = getelementptr inbounds i8, ptr addrspace(1) %src, i64 %src_offset
%dest_derived = getelementptr inbounds i8, ptr addrspace(1) %dest, i64 %dest_offset
call void @llvm.memmove.element.unordered.atomic.p1.p1.i32(ptr addrspace(1) align 16 %src_derived, ptr addrspace(1) align 16 %dest_derived, i32 %len, i32 1) [ "deopt"(i32 0) ]
ret void
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
; can remove some blocks for which isReachableFromEntry() returns true.
; This resulted in stale pointers to the collected but removed
; callsites. Such stale pointers caused crash when accessed.
declare void @f(i8 addrspace(1)* %obj)
declare void @f(ptr addrspace(1) %obj)

define void @test(i8 addrspace(1)* %arg) gc "statepoint-example" {
define void @test(ptr addrspace(1) %arg) gc "statepoint-example" {
; CHECK-LABEL: test(
; CHECK-NEXT: @f
call void @f(i8 addrspace(1)* %arg) #1
call void @f(ptr addrspace(1) %arg) #1
br i1 true, label %not_zero, label %zero

not_zero:
Expand All @@ -22,11 +22,11 @@ not_zero:
; This block is reachable but removed by removeUnreachableBlocks()
zero:
; CHECK-NOT: @f
call void @f(i8 addrspace(1)* %arg) #1
call void @f(ptr addrspace(1) %arg) #1
ret void

unreach:
call void @f(i8 addrspace(1)* %arg) #1
call void @f(ptr addrspace(1) %arg) #1
ret void
}

Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/RewriteStatepointsForGC/vector-bitcast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
target triple = "x86_64-unknown-linux-gnu"

declare i8 addrspace(1)* @foo()
declare ptr addrspace(1) @foo()

; Function Attrs: uwtable
define i32 @test() gc "statepoint-example" {
Expand All @@ -20,9 +20,9 @@ entry:
; CHECK: %[[p2]].relocated = {{.+}} @llvm.experimental.gc.relocate
; CHECK: %[[p1]].relocated = {{.+}} @llvm.experimental.gc.relocate
; CHECK: load atomic
%bc = bitcast <8 x i8 addrspace(1)*> undef to <8 x i32 addrspace(1)*>
%ptr= extractelement <8 x i32 addrspace(1)*> %bc, i32 7
%0 = call i8 addrspace(1)* @foo() [ "deopt"() ]
%1 = load atomic i32, i32 addrspace(1)* %ptr unordered, align 4
%bc = bitcast <8 x ptr addrspace(1)> undef to <8 x ptr addrspace(1)>
%ptr= extractelement <8 x ptr addrspace(1)> %bc, i32 7
%0 = call ptr addrspace(1) @foo() [ "deopt"() ]
%1 = load atomic i32, ptr addrspace(1) %ptr unordered, align 4
ret i32 %1
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,36 @@
; RUN: opt -S -passes=rewrite-statepoints-for-gc -rs4gc-clobber-non-live %s | FileCheck %s
; Make sure that clobber-non-live correctly handles vector types

define void @test_vector_clobber(i8 addrspace(1)* %ptr) gc "statepoint-example" {
define void @test_vector_clobber(ptr addrspace(1) %ptr) gc "statepoint-example" {
; CHECK-LABEL: @test_vector_clobber(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[PTR_CAST:%.*]] = bitcast i8 addrspace(1)* [[PTR:%.*]] to float addrspace(1)*
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 2, i32 0, i32 62, i32 0, i32 13, i32 0, i32 7, i8* null, i32 7, i8* null, i32 7, i8* null, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, i8 addrspace(1)* [[PTR]], i32 0, i8 addrspace(1)* [[PTR]], i32 7, i8* null), "gc-live"(i8 addrspace(1)* [[PTR]]) ]
; CHECK-NEXT: [[PTR_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[PTR_CAST_REMAT:%.*]] = bitcast i8 addrspace(1)* [[PTR_RELOCATED]] to float addrspace(1)*
; CHECK-NEXT: [[CAST:%.*]] = bitcast i8 addrspace(1)* [[PTR_RELOCATED]] to float addrspace(1)*
; CHECK-NEXT: [[DOTSPLATINSERT_BASE:%.*]] = insertelement <8 x float addrspace(1)*> zeroinitializer, float addrspace(1)* [[CAST]], i32 0, !is_base_value !0
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x float addrspace(1)*> poison, float addrspace(1)* [[PTR_CAST_REMAT]], i32 0
; CHECK-NEXT: [[DOTSPLAT_BASE:%.*]] = shufflevector <8 x float addrspace(1)*> [[DOTSPLATINSERT_BASE]], <8 x float addrspace(1)*> undef, <8 x i32> zeroinitializer, !is_base_value !0
; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x float addrspace(1)*> [[DOTSPLATINSERT]], <8 x float addrspace(1)*> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds float, <8 x float addrspace(1)*> [[DOTSPLAT]], <8 x i64> <i64 83, i64 81, i64 79, i64 77, i64 75, i64 73, i64 71, i64 69>
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 1, i32 0, i32 112, i32 0, i32 13, i32 0, i32 7, i8* null, i32 7, i8* null, i32 3, i32 undef, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, i8 addrspace(1)* [[PTR_RELOCATED]], i32 0, i8 addrspace(1)* [[PTR_RELOCATED]], i32 7, i8* null), "gc-live"(<8 x float addrspace(1)*> [[GEP]], i8 addrspace(1)* [[PTR_RELOCATED]], <8 x float addrspace(1)*> [[DOTSPLAT_BASE]]) ]
; CHECK-NEXT: [[GEP_RELOCATED:%.*]] = call coldcc <8 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v8p1i8(token [[STATEPOINT_TOKEN1]], i32 2, i32 0)
; CHECK-NEXT: [[GEP_RELOCATED_CASTED:%.*]] = bitcast <8 x i8 addrspace(1)*> [[GEP_RELOCATED]] to <8 x float addrspace(1)*>
; CHECK-NEXT: [[PTR_RELOCATED2:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 1, i32 1)
; CHECK-NEXT: [[DOTSPLAT_BASE_RELOCATED:%.*]] = call coldcc <8 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v8p1i8(token [[STATEPOINT_TOKEN1]], i32 2, i32 2)
; CHECK-NEXT: [[DOTSPLAT_BASE_RELOCATED_CASTED:%.*]] = bitcast <8 x i8 addrspace(1)*> [[DOTSPLAT_BASE_RELOCATED]] to <8 x float addrspace(1)*>
; CHECK-NEXT: [[RES:%.*]] = call <8 x float> @llvm.masked.gather.v8f32.v8p1f32(<8 x float addrspace(1)*> [[GEP_RELOCATED_CASTED]], i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x float> undef)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 2, i32 0, i32 62, i32 0, i32 13, i32 0, i32 7, ptr null, i32 7, ptr null, i32 7, ptr null, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, ptr addrspace(1) [[PTR:%.*]], i32 0, ptr addrspace(1) [[PTR]], i32 7, ptr null), "gc-live"(ptr addrspace(1) [[PTR]]) ]
; CHECK-NEXT: [[PTR_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[DOTSPLATINSERT_BASE:%.*]] = insertelement <8 x ptr addrspace(1)> zeroinitializer, ptr addrspace(1) [[PTR_RELOCATED]], i32 0, !is_base_value !0
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x ptr addrspace(1)> poison, ptr addrspace(1) [[PTR_RELOCATED]], i32 0
; CHECK-NEXT: [[DOTSPLAT_BASE:%.*]] = shufflevector <8 x ptr addrspace(1)> [[DOTSPLATINSERT_BASE]], <8 x ptr addrspace(1)> undef, <8 x i32> zeroinitializer, !is_base_value !0
; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x ptr addrspace(1)> [[DOTSPLATINSERT]], <8 x ptr addrspace(1)> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds float, <8 x ptr addrspace(1)> [[DOTSPLAT]], <8 x i64> <i64 83, i64 81, i64 79, i64 77, i64 75, i64 73, i64 71, i64 69>
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 1, i32 0, i32 112, i32 0, i32 13, i32 0, i32 7, ptr null, i32 7, ptr null, i32 3, i32 undef, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, ptr addrspace(1) [[PTR_RELOCATED]], i32 0, ptr addrspace(1) [[PTR_RELOCATED]], i32 7, ptr null), "gc-live"(<8 x ptr addrspace(1)> [[GEP]], ptr addrspace(1) [[PTR_RELOCATED]], <8 x ptr addrspace(1)> [[DOTSPLAT_BASE]]) ]
; CHECK-NEXT: [[GEP_RELOCATED:%.*]] = call coldcc <8 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v8p1(token [[STATEPOINT_TOKEN1]], i32 2, i32 0)
; CHECK-NEXT: [[PTR_RELOCATED2:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN1]], i32 1, i32 1)
; CHECK-NEXT: [[DOTSPLAT_BASE_RELOCATED:%.*]] = call coldcc <8 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v8p1(token [[STATEPOINT_TOKEN1]], i32 2, i32 2)
; CHECK-NEXT: [[RES:%.*]] = call <8 x float> @llvm.masked.gather.v8f32.v8p1(<8 x ptr addrspace(1)> [[GEP_RELOCATED]], i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x float> undef)
; CHECK-NEXT: unreachable
;
entry:
%ptr.cast = bitcast i8 addrspace(1)* %ptr to float addrspace(1)*
call void @foo() [ "deopt"(i32 0, i32 2, i32 0, i32 62, i32 0, i32 13, i32 0, i32 7, i8* null, i32 7, i8* null, i32 7, i8* null, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, i8 addrspace(1)* %ptr, i32 0, i8 addrspace(1)* %ptr, i32 7, i8* null) ]
%gep = getelementptr inbounds float, float addrspace(1)* %ptr.cast, <8 x i64> <i64 83, i64 81, i64 79, i64 77, i64 75, i64 73, i64 71, i64 69>
call void @bar() [ "deopt"(i32 0, i32 1, i32 0, i32 112, i32 0, i32 13, i32 0, i32 7, i8* null, i32 7, i8* null, i32 3, i32 undef, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, i8 addrspace(1)* %ptr, i32 0, i8 addrspace(1)* %ptr, i32 7, i8* null) ]
%res = call <8 x float> @llvm.masked.gather.v8f32.v8p1f32(<8 x float addrspace(1)*> %gep, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x float> undef)
call void @foo() [ "deopt"(i32 0, i32 2, i32 0, i32 62, i32 0, i32 13, i32 0, i32 7, ptr null, i32 7, ptr null, i32 7, ptr null, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, ptr addrspace(1) %ptr, i32 0, ptr addrspace(1) %ptr, i32 7, ptr null) ]
%gep = getelementptr inbounds float, ptr addrspace(1) %ptr, <8 x i64> <i64 83, i64 81, i64 79, i64 77, i64 75, i64 73, i64 71, i64 69>
call void @bar() [ "deopt"(i32 0, i32 1, i32 0, i32 112, i32 0, i32 13, i32 0, i32 7, ptr null, i32 7, ptr null, i32 3, i32 undef, i32 3, i32 14, i32 3, i32 -2406, i32 3, i32 28963, i32 3, i32 30401, i32 3, i32 -11, i32 3, i32 -5, i32 3, i32 1, i32 0, ptr addrspace(1) %ptr, i32 0, ptr addrspace(1) %ptr, i32 7, ptr null) ]
%res = call <8 x float> @llvm.masked.gather.v8f32.v8p1(<8 x ptr addrspace(1)> %gep, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x float> undef)
unreachable
}


declare void @foo() gc "statepoint-example"

; Function Attrs: nocallback nofree nosync nounwind readonly willreturn
declare <8 x float> @llvm.masked.gather.v8f32.v8p1f32(<8 x float addrspace(1)*>, i32 immarg, <8 x i1>, <8 x float>) #1
declare <8 x float> @llvm.masked.gather.v8f32.v8p1(<8 x ptr addrspace(1)>, i32 immarg, <8 x i1>, <8 x float>) #1

declare void @bar()

Expand Down