[llvm] 0dfe53b - [RS4GC] Add few tests for derived pointer rematerialization. NFC.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 13 02:43:18 PST 2022


Author: Denis Antrushin
Date: 2022-12-13T13:43:10+03:00
New Revision: 0dfe53b614593275017d6256f66483320a90defd

URL: https://github.com/llvm/llvm-project/commit/0dfe53b614593275017d6256f66483320a90defd
DIFF: https://github.com/llvm/llvm-project/commit/0dfe53b614593275017d6256f66483320a90defd.diff

LOG: [RS4GC] Add few tests for derived pointer rematerialization. NFC.

Precommit few tests for the upcoming 'rematerialize derived pointers
at uses' feature.

Reviewed By: skatkov

Differential Revision: https://reviews.llvm.org/D138911

Added: 
    llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers-at-uses.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers-at-uses.ll b/llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers-at-uses.ll
new file mode 100644
index 0000000000000..f760ed961e394
--- /dev/null
+++ b/llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers-at-uses.ll
@@ -0,0 +1,223 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes='rewrite-statepoints-for-gc,verify<safepoint-ir>' -S | FileCheck %s
+
+declare void @use_obj(ptr addrspace(1)) "gc-leaf-function"
+declare void @do_safepoint()
+
+
+; Profitable test
+define i32 @test_remat(ptr addrspace(1) %base, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test_remat(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[DERIVED:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 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"(ptr addrspace(1) [[BASE]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 16
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
+; CHECK:       here:
+; CHECK-NEXT:    [[STATEPOINT_TOKEN3:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED4:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN3]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED4]], i32 16
+; CHECK-NEXT:    br label [[MERGE:%.*]]
+; CHECK:       there:
+; CHECK-NEXT:    [[STATEPOINT_TOKEN5:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED6:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN5]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED6]], i32 16
+; CHECK-NEXT:    br label [[MERGE]]
+; CHECK:       merge:
+; CHECK-NEXT:    [[DOT0:%.*]] = phi ptr addrspace(1) [ [[DERIVED_REMAT1]], [[HERE]] ], [ [[DERIVED_REMAT2]], [[THERE]] ]
+; CHECK-NEXT:    [[RET:%.*]] = load i32, ptr addrspace(1) [[DOT0]], align 4
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+entry:
+  %derived = getelementptr i32, ptr addrspace(1) %base, i32 16
+  call void @do_safepoint() [ "deopt"() ]
+  br i1 %cond, label %here, label %there
+
+here:
+  call void @do_safepoint() [ "deopt"() ]
+  br label %merge
+
+there:
+  call void @do_safepoint() [ "deopt"() ]
+  br label %merge
+
+merge:
+  %ret = load i32, ptr addrspace(1) %derived
+  ret i32 %ret
+}
+
+; Unprofitable test
+define i32 @test_many_uses(ptr addrspace(1) %base, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test_many_uses(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[DERIVED:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 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"(ptr addrspace(1) [[BASE]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 16
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
+; CHECK:       here:
+; CHECK-NEXT:    [[STATEPOINT_TOKEN3:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED4:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN3]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED4]], i32 16
+; CHECK-NEXT:    call void @use_obj(ptr addrspace(1) [[DERIVED_REMAT1]])
+; CHECK-NEXT:    br label [[MERGE:%.*]]
+; CHECK:       there:
+; CHECK-NEXT:    call void @use_obj(ptr addrspace(1) [[DERIVED_REMAT]])
+; CHECK-NEXT:    [[STATEPOINT_TOKEN5:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED6:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN5]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED6]], i32 16
+; CHECK-NEXT:    br label [[MERGE]]
+; CHECK:       merge:
+; CHECK-NEXT:    [[DOT0:%.*]] = phi ptr addrspace(1) [ [[DERIVED_REMAT1]], [[HERE]] ], [ [[DERIVED_REMAT2]], [[THERE]] ]
+; CHECK-NEXT:    call void @use_obj(ptr addrspace(1) [[DOT0]])
+; CHECK-NEXT:    [[RET:%.*]] = load i32, ptr addrspace(1) [[DOT0]], align 4
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+entry:
+  %derived = getelementptr i32, ptr addrspace(1) %base, i32 16
+  call void @do_safepoint() [ "deopt" () ]
+  br i1 %cond, label %here, label %there
+
+here:
+  call void @do_safepoint() [ "deopt"() ]
+  call void @use_obj(ptr addrspace(1) %derived)
+  br label %merge
+
+there:
+  call void @use_obj(ptr addrspace(1) %derived)
+  call void @do_safepoint() [ "deopt"() ]
+  br label %merge
+
+merge:
+  call void @use_obj(ptr addrspace(1) %derived)
+  %ret = load i32, ptr addrspace(1) %derived
+  ret i32 %ret
+}
+
+; Remat before phi - not implemented
+define i32 @test_phi(ptr addrspace(1) %base, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test_phi(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[DERIVED1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 16
+; CHECK-NEXT:    [[DERIVED2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE]], i32 32
+; 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) [[BASE]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED2_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 32
+; CHECK-NEXT:    [[DERIVED1_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 16
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
+; CHECK:       here:
+; CHECK-NEXT:    br label [[MERGE:%.*]]
+; CHECK:       there:
+; CHECK-NEXT:    br label [[MERGE]]
+; CHECK:       merge:
+; CHECK-NEXT:    [[PHI1:%.*]] = phi ptr addrspace(1) [ [[DERIVED1_REMAT]], [[HERE]] ], [ [[DERIVED2_REMAT]], [[THERE]] ]
+; CHECK-NEXT:    [[RET:%.*]] = load i32, ptr addrspace(1) [[PHI1]], align 4
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+entry:
+  %derived1 = getelementptr i32, ptr addrspace(1) %base, i32 16
+  %derived2 = getelementptr i32, ptr addrspace(1) %base, i32 32
+  call void @do_safepoint() [ "deopt"() ]
+  br i1 %cond, label %here, label %there
+
+here:
+  br label %merge
+
+there:
+  br label %merge
+
+merge:
+  %phi1 = phi ptr addrspace(1) [ %derived1, %here ], [ %derived2, %there ]
+  %ret = load i32, ptr addrspace(1) %phi1
+  ret i32 %ret
+}
+
+; Several uses per block
+; TODO: We could rematerialize once per block for several uses if there is not statepoint between
+define i32 @test_same_block_with_statepoint(ptr addrspace(1) %base, i1 %cond) gc "statepoint-example" {
+; CHECK-LABEL: @test_same_block_with_statepoint(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[DERIVED:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 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"(ptr addrspace(1) [[BASE]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 16
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
+; CHECK:       here:
+; CHECK-NEXT:    call void @use_obj(ptr addrspace(1) [[DERIVED_REMAT]])
+; CHECK-NEXT:    [[STATEPOINT_TOKEN4:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED5:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN4]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED5]], i32 16
+; CHECK-NEXT:    call void @use_obj(ptr addrspace(1) [[DERIVED_REMAT1]])
+; CHECK-NEXT:    [[DUMMY:%.*]] = load i32, ptr addrspace(1) [[DERIVED_REMAT1]], align 4
+; CHECK-NEXT:    [[STATEPOINT_TOKEN6:%.*]] = 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) [[BASE_RELOCATED5]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED7:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN6]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED7]], i32 16
+; CHECK-NEXT:    br label [[MERGE:%.*]]
+; CHECK:       there:
+; CHECK-NEXT:    [[STATEPOINT_TOKEN8:%.*]] = 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) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED9:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN8]], i32 0, i32 0)
+; CHECK-NEXT:    [[DERIVED_REMAT3:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED9]], i32 16
+; CHECK-NEXT:    br label [[MERGE]]
+; CHECK:       merge:
+; CHECK-NEXT:    [[DOT0:%.*]] = phi ptr addrspace(1) [ [[DERIVED_REMAT2]], [[HERE]] ], [ [[DERIVED_REMAT3]], [[THERE]] ]
+; CHECK-NEXT:    [[RET:%.*]] = load i32, ptr addrspace(1) [[DOT0]], align 4
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+entry:
+  %derived = getelementptr i32, ptr addrspace(1) %base, i32 16
+  call void @do_safepoint() [ "deopt" () ]
+  br i1 %cond, label %here, label %there
+
+here:
+  call void @use_obj(ptr addrspace(1) %derived)
+  call void @do_safepoint() [ "deopt"() ]
+  call void @use_obj(ptr addrspace(1) %derived)
+  %dummy = load i32, ptr addrspace(1) %derived
+  call void @do_safepoint() [ "deopt" () ]
+  br label %merge
+
+there:
+  call void @do_safepoint() [ "deopt"() ]
+  br label %merge
+
+merge:
+  %ret = load i32, ptr addrspace(1) %derived
+  ret i32 %ret
+}
+
+; Test long chain with sub-chain rematerialized
+; TODO: If we rematerialized longer chain first (%v4), then shorter on (%v0) would become dead
+define void @test_chain(ptr addrspace(1) %base, i1 %cond1) gc "statepoint-example" {
+; CHECK-LABEL: @test_chain(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V0:%.*]] = getelementptr i8, ptr addrspace(1) [[BASE:%.*]], 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 ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(ptr addrspace(1) [[BASE]]), "gc-live"(ptr addrspace(1) [[BASE]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
+; CHECK-NEXT:    [[V0_REMAT:%.*]] = getelementptr i8, ptr addrspace(1) [[BASE_RELOCATED]], i64 16
+; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[BLOCK3:%.*]], label [[COMMON_RET:%.*]]
+; CHECK:       block3:
+; CHECK-NEXT:    [[V4:%.*]] = getelementptr i8, ptr addrspace(1) [[V0_REMAT]], i64 70
+; CHECK-NEXT:    [[STATEPOINT_TOKEN2:%.*]] = 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"(ptr addrspace(1) [[BASE_RELOCATED]]), "gc-live"(ptr addrspace(1) [[BASE_RELOCATED]]) ]
+; CHECK-NEXT:    [[BASE_RELOCATED3:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN2]], i32 0, i32 0)
+; CHECK-NEXT:    [[V0_REMAT1:%.*]] = getelementptr i8, ptr addrspace(1) [[BASE_RELOCATED3]], i64 16
+; CHECK-NEXT:    [[V4_REMAT:%.*]] = getelementptr i8, ptr addrspace(1) [[V0_REMAT1]], i64 70
+; CHECK-NEXT:    [[V5:%.*]] = load atomic i8, ptr addrspace(1) [[V4_REMAT]] unordered, align 2
+; CHECK-NEXT:    br label [[COMMON_RET]]
+; CHECK:       common.ret:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %v0 = getelementptr i8, ptr addrspace(1) %base, i64 16
+  call void @do_safepoint() [ "deopt"(ptr addrspace(1) %base) ]
+  br i1 %cond1, label %block3, label %common.ret
+
+block3:
+  %v4 = getelementptr i8, ptr addrspace(1) %v0, i64 70
+  call void @do_safepoint() [ "deopt"(ptr addrspace(1) %base) ]
+  %v5 = load atomic i8, ptr addrspace(1) %v4 unordered, align 2
+  br label %common.ret
+
+common.ret:
+  ret void
+}


        


More information about the llvm-commits mailing list