mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Summary: Once a gc.statepoint has been rewritten to relocate live references, the SSA values represent physical pointers instead of logical references. Logical dereferencability does not imply physical dereferencability and after RewriteStatepointsForGC has run any attributes that imply dereferencability of the logical references need to be stripped. This current approach is conservative, and can be made more precise later if needed. For starters, we need to strip dereferencable attributes only from pointers that live in the GC address space. Reviewers: reames, pgavlin Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10105 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238883 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			78 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
| ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
 | |
| 
 | |
| declare void @foo()
 | |
| declare i8 addrspace(1)* @some_function()
 | |
| declare void @some_function_consumer(i8 addrspace(1)*)
 | |
| declare dereferenceable(4) i8 addrspace(1)* @some_function_ret_deref()
 | |
| ; CHECK: declare i8 addrspace(1)* @some_function_ret_deref()
 | |
| 
 | |
| define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* dereferenceable(4) %a) gc "statepoint-example" {
 | |
| ; CHECK: define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* %a)
 | |
| entry:
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %a
 | |
| }
 | |
| 
 | |
| define i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* dereferenceable_or_null(4) %a) gc "statepoint-example" {
 | |
| ; CHECK: define i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* %a)
 | |
| entry:
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %a
 | |
| }
 | |
| 
 | |
| define i8 addrspace(1)* @test_deref_retval() gc "statepoint-example" {
 | |
| ; CHECK-LABEL: @test_deref_retval(
 | |
| entry:
 | |
|   %a = call dereferenceable(4) i8 addrspace(1)* @some_function()
 | |
| ; CHECK: %a = call i8 addrspace(1)* @some_function()
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %a
 | |
| }
 | |
| 
 | |
| define i8 addrspace(1)* @test_deref_or_null_retval() gc "statepoint-example" {
 | |
| ; CHECK-LABEL: @test_deref_or_null_retval(
 | |
| entry:
 | |
|   %a = call dereferenceable_or_null(4) i8 addrspace(1)* @some_function()
 | |
| ; CHECK: %a = call i8 addrspace(1)* @some_function()
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %a
 | |
| }
 | |
| 
 | |
| define i8 @test_md(i8 addrspace(1)* %ptr) gc "statepoint-example" {
 | |
| ; CHECK-LABEL: @test_md(
 | |
|  entry:
 | |
| ; CHECK: %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !0
 | |
|   %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !0
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 %tmp
 | |
| }
 | |
| 
 | |
| define i8 addrspace(1)* @test_decl_only_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
 | |
| ; CHECK-LABEL: @test_decl_only_attribute(
 | |
| entry:
 | |
| ; No change here, but the prototype of some_function_ret_deref should have changed.
 | |
| ; CHECK: call i8 addrspace(1)* @some_function_ret_deref()
 | |
|   %a = call i8 addrspace(1)* @some_function_ret_deref()
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %a
 | |
| }
 | |
| 
 | |
| define i8 addrspace(1)* @test_callsite_arg_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
 | |
| ; CHECK-LABEL: @test_callsite_arg_attribute(
 | |
| entry:
 | |
| ; CHECK: call void @some_function_consumer(i8 addrspace(1)* %ptr)
 | |
|   call void @some_function_consumer(i8 addrspace(1)* dereferenceable(4) %ptr)
 | |
|   call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
 | |
|   ret i8 addrspace(1)* %ptr
 | |
| }
 | |
| 
 | |
| declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
 | |
| 
 | |
| !0 = !{!1, !1, i64 0, i64 1}
 | |
| !1 = !{!"red", !2}
 | |
| !2 = !{!"blue"}
 | |
| 
 | |
| ; CHECK: !0 = !{!1, !1, i64 0}
 | |
| ; CHECK: !1 = !{!"red", !2}
 | |
| ; CHECK: !2 = !{!"blue"}
 |