As a pragmatic tradeoff, the ease of updating the tests outweighs the slightly easier to understand test conditions. Where revevant, debug output was converted to comments to help human understanding.
70 lines
4.6 KiB
LLVM
70 lines
4.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
|
|
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
|
|
|
|
; derived %next_element_ptr base %array_obj
|
|
define i32 @null_in_array(i64 addrspace(1)* %array_obj) gc "statepoint-example" {
|
|
; CHECK-LABEL: @null_in_array(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ARRAY_LEN_POINTER_I64:%.*]] = getelementptr i64, i64 addrspace(1)* [[ARRAY_OBJ:%.*]], i32 1
|
|
; CHECK-NEXT: [[ARRAY_LEN_POINTER_I32:%.*]] = bitcast i64 addrspace(1)* [[ARRAY_LEN_POINTER_I64]] to i32 addrspace(1)*
|
|
; CHECK-NEXT: [[ARRAY_LEN:%.*]] = load i32, i32 addrspace(1)* [[ARRAY_LEN_POINTER_I32]], align 4
|
|
; CHECK-NEXT: [[ARRAY_ELEMS:%.*]] = bitcast i32 addrspace(1)* [[ARRAY_LEN_POINTER_I32]] to i64 addrspace(1)* addrspace(1)*
|
|
; CHECK-NEXT: br label [[LOOP_CHECK:%.*]]
|
|
; CHECK: loop_check:
|
|
; CHECK-NEXT: [[DOT0:%.*]] = phi i64 addrspace(1)* [ [[ARRAY_OBJ]], [[ENTRY:%.*]] ], [ [[ARRAY_OBJ_RELOCATED_CASTED:%.*]], [[LOOP_BACK:%.*]] ]
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[NEXT_INDEX:%.*]], [[LOOP_BACK]] ]
|
|
; CHECK-NEXT: [[CURRENT_ELEMENT_PTR:%.*]] = phi i64 addrspace(1)* addrspace(1)* [ [[ARRAY_ELEMS]], [[ENTRY]] ], [ [[NEXT_ELEMENT_PTR_RELOCATED_CASTED:%.*]], [[LOOP_BACK]] ]
|
|
; CHECK-NEXT: [[INDEX_LT:%.*]] = icmp ult i32 [[INDEX]], [[ARRAY_LEN]]
|
|
; CHECK-NEXT: br i1 [[INDEX_LT]], label [[CHECK_FOR_NULL:%.*]], label [[NOT_FOUND:%.*]]
|
|
; CHECK: check_for_null:
|
|
; CHECK-NEXT: [[CURRENT_ELEMENT:%.*]] = load i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* [[CURRENT_ELEMENT_PTR]], align 8
|
|
; CHECK-NEXT: [[IS_NULL:%.*]] = icmp eq i64 addrspace(1)* [[CURRENT_ELEMENT]], null
|
|
; CHECK-NEXT: br i1 [[IS_NULL]], label [[FOUND:%.*]], label [[LOOP_BACK]]
|
|
; CHECK: loop_back:
|
|
; CHECK-NEXT: [[NEXT_ELEMENT_PTR:%.*]] = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* [[CURRENT_ELEMENT_PTR]], i32 1
|
|
; CHECK-NEXT: [[NEXT_INDEX]] = add i32 [[INDEX]], 1
|
|
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* addrspace(1)* [[NEXT_ELEMENT_PTR]], i64 addrspace(1)* [[DOT0]]) ]
|
|
; CHECK-NEXT: [[NEXT_ELEMENT_PTR_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
|
|
; CHECK-NEXT: [[NEXT_ELEMENT_PTR_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[NEXT_ELEMENT_PTR_RELOCATED]] to i64 addrspace(1)* addrspace(1)*
|
|
; CHECK-NEXT: [[ARRAY_OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
|
|
; CHECK-NEXT: [[ARRAY_OBJ_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[ARRAY_OBJ_RELOCATED]] to i64 addrspace(1)*
|
|
; CHECK-NEXT: br label [[LOOP_CHECK]]
|
|
; CHECK: not_found:
|
|
; CHECK-NEXT: ret i32 -1
|
|
; CHECK: found:
|
|
; CHECK-NEXT: ret i32 [[INDEX]]
|
|
;
|
|
entry:
|
|
%array_len_pointer.i64 = getelementptr i64, i64 addrspace(1)* %array_obj, i32 1
|
|
%array_len_pointer.i32 = bitcast i64 addrspace(1)* %array_len_pointer.i64 to i32 addrspace(1)*
|
|
%array_len = load i32, i32 addrspace(1)* %array_len_pointer.i32
|
|
%array_elems = bitcast i32 addrspace(1)* %array_len_pointer.i32 to i64 addrspace(1)* addrspace(1)*
|
|
br label %loop_check
|
|
|
|
loop_check: ; preds = %loop_back, %entry
|
|
%index = phi i32 [ 0, %entry ], [ %next_index, %loop_back ]
|
|
%current_element_ptr = phi i64 addrspace(1)* addrspace(1)* [ %array_elems, %entry ], [ %next_element_ptr, %loop_back ]
|
|
%index_lt = icmp ult i32 %index, %array_len
|
|
br i1 %index_lt, label %check_for_null, label %not_found
|
|
|
|
check_for_null: ; preds = %loop_check
|
|
%current_element = load i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr
|
|
%is_null = icmp eq i64 addrspace(1)* %current_element, null
|
|
br i1 %is_null, label %found, label %loop_back
|
|
|
|
loop_back: ; preds = %check_for_null
|
|
%next_element_ptr = getelementptr i64 addrspace(1)*, i64 addrspace(1)* addrspace(1)* %current_element_ptr, i32 1
|
|
%next_index = add i32 %index, 1
|
|
call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
|
|
br label %loop_check
|
|
|
|
not_found: ; preds = %loop_check
|
|
ret i32 -1
|
|
|
|
found: ; preds = %check_for_null
|
|
ret i32 %index
|
|
}
|
|
|
|
declare void @do_safepoint()
|