1; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S < %s | FileCheck %s 2 3target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 4target triple = "x86_64-pc-linux-gnu" 5 6declare zeroext i1 @return_i1() 7 8define i32 @test_sor_basic(ptr addrspace(1) %base) gc "statepoint-example" { 9; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 10; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 15 11entry: 12 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 13 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 14 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 15 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 16 %ret = load i32, ptr addrspace(1) %ptr-new 17 ret i32 %ret 18} 19 20define i32 @test_sor_two_derived(ptr addrspace(1) %base) gc "statepoint-example" { 21; CHECK-LABEL: @test_sor_two_derived( 22; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 23; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 12 24; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 15 25; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 12 26entry: 27 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 28 %ptr2 = getelementptr i32, ptr addrspace(1) %base, i32 12 29 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr, ptr addrspace(1) %ptr2)] 30 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 31 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 32 %ptr2-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 2) 33 %ret = load i32, ptr addrspace(1) %ptr-new 34 ret i32 %ret 35} 36 37define i32 @test_sor_ooo(ptr addrspace(1) %base) gc "statepoint-example" { 38; CHECK-LABEL: @test_sor_ooo( 39; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 40; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 15 41entry: 42 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 43 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 44 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 45 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 46 %ret = load i32, ptr addrspace(1) %ptr-new 47 ret i32 %ret 48} 49 50define i32 @test_sor_gep_smallint(ptr addrspace(1) %base) gc "statepoint-example" { 51; CHECK: getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 2 52; CHECK: getelementptr [3 x i32], ptr addrspace(1) %base-new, i32 0, i32 2 53entry: 54 %ptr = getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 2 55 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 56 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 57 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 58 %ret = load i32, ptr addrspace(1) %ptr-new 59 ret i32 %ret 60} 61 62define i32 @test_sor_gep_largeint(ptr addrspace(1) %base) gc "statepoint-example" { 63; CHECK: getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 21 64; CHECK-NOT: getelementptr [3 x i32], ptr addrspace(1) %base-new, i32 0, i32 21 65entry: 66 %ptr = getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 21 67 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 68 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 69 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 70 %ret = load i32, ptr addrspace(1) %ptr-new 71 ret i32 %ret 72} 73 74define i32 @test_sor_noop(ptr addrspace(1) %base) gc "statepoint-example" { 75; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 76; CHECK: call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 77; CHECK: call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 2) 78entry: 79 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 80 %ptr2 = getelementptr i32, ptr addrspace(1) %base, i32 12 81 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr, ptr addrspace(1) %ptr2)] 82 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 83 %ptr2-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 2) 84 %ret = load i32, ptr addrspace(1) %ptr-new 85 ret i32 %ret 86} 87 88define i32 @test_sor_basic_wrong_order(ptr addrspace(1) %base) gc "statepoint-example" { 89; CHECK-LABEL: @test_sor_basic_wrong_order 90; Here we have base relocate inserted after derived. Make sure that we don't 91; produce uses of the relocated base pointer before it's definition. 92entry: 93 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 94 ; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 95 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 96 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 97 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 98 ; CHECK: %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 99 ; CHECK-NEXT: getelementptr i32, ptr addrspace(1) %base-new, i32 15 100 %ret = load i32, ptr addrspace(1) %ptr-new 101 ret i32 %ret 102} 103 104define i32 @test_sor_noop_cross_bb(i1 %external-cond, ptr addrspace(1) %base) gc "statepoint-example" { 105; CHECK-LABEL: @test_sor_noop_cross_bb 106; Here base relocate doesn't dominate derived relocate. Make sure that we don't 107; produce undefined use of the relocated base pointer. 108entry: 109 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15 110 ; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 111 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr)] 112 br i1 %external-cond, label %left, label %right 113 114left: 115 %ptr-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 116 ; CHECK: call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 117 %ret-new = load i32, ptr addrspace(1) %ptr-new 118 ret i32 %ret-new 119 120right: 121 %ptr-base = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 122 ; CHECK: call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 123 %ret-base = load i32, ptr addrspace(1) %ptr-base 124 ret i32 %ret-base 125} 126 127define i32 @test_sor_noop_same_bb(i1 %external-cond, ptr addrspace(1) %base) gc "statepoint-example" { 128; CHECK-LABEL: @test_sor_noop_same_bb 129; Here base relocate doesn't dominate derived relocate. Make sure that we don't 130; produce undefined use of the relocated base pointer. 131entry: 132 %ptr1 = getelementptr i32, ptr addrspace(1) %base, i32 15 133 ; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 15 134 %ptr2 = getelementptr i32, ptr addrspace(1) %base, i32 5 135 ; CHECK: getelementptr i32, ptr addrspace(1) %base, i32 5 136 %tok = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %base, ptr addrspace(1) %ptr1, ptr addrspace(1) %ptr2)] 137 ; CHECK: call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 138 %ptr2-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 2) 139 %ret2-new = load i32, ptr addrspace(1) %ptr2-new 140 ; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 5 141 %ptr1-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 1) 142 %ret1-new = load i32, ptr addrspace(1) %ptr1-new 143 ; CHECK: getelementptr i32, ptr addrspace(1) %base-new, i32 15 144 %base-new = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0) 145 %ret-new = add i32 %ret2-new, %ret1-new 146 ret i32 %ret-new 147} 148 149declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 150declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) 151