1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; These tests check the optimizations specific to 4; pointers being relocated at a statepoint. 5 6 7declare ptr @fake_personality_function() 8declare void @func() 9 10define i1 @test_negative(ptr addrspace(1) %p) gc "statepoint-example" { 11; CHECK-LABEL: @test_negative( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[P:%.*]]) ] 14; CHECK-NEXT: [[PNEW:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[SAFEPOINT_TOKEN]], i32 0, i32 0) 15; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(1) [[PNEW]], null 16; CHECK-NEXT: ret i1 [[CMP]] 17; 18entry: 19 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p)] 20 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 21 %cmp = icmp eq ptr addrspace(1) %pnew, null 22 ret i1 %cmp 23} 24 25define i1 @test_nonnull(ptr addrspace(1) nonnull %p) gc "statepoint-example" { 26; CHECK-LABEL: @test_nonnull( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 29; CHECK-NEXT: ret i1 false 30; 31entry: 32 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p)] 33 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 34 %cmp = icmp eq ptr addrspace(1) %pnew, null 35 ret i1 %cmp 36} 37 38define i1 @test_null() gc "statepoint-example" { 39; CHECK-LABEL: @test_null( 40; CHECK-NEXT: entry: 41; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 42; CHECK-NEXT: ret i1 true 43; 44entry: 45 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) null)] 46 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 47 %cmp = icmp eq ptr addrspace(1) %pnew, null 48 ret i1 %cmp 49} 50 51define i1 @test_undef() gc "statepoint-example" { 52; CHECK-LABEL: @test_undef( 53; CHECK-NEXT: entry: 54; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 55; CHECK-NEXT: ret i1 undef 56; 57entry: 58 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) undef)] 59 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 60 %cmp = icmp eq ptr addrspace(1) %pnew, null 61 ret i1 %cmp 62} 63 64define i1 @test_negative_invoke(ptr addrspace(1) %p) gc "statepoint-example" personality ptr @fake_personality_function { 65; CHECK-LABEL: @test_negative_invoke( 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[P:%.*]]) ] 68; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] 69; CHECK: normal_dest: 70; CHECK-NEXT: [[PNEW:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[SAFEPOINT_TOKEN]], i32 0, i32 0) 71; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(1) [[PNEW]], null 72; CHECK-NEXT: ret i1 [[CMP]] 73; CHECK: unwind_dest: 74; CHECK-NEXT: [[LPAD:%.*]] = landingpad token 75; CHECK-NEXT: cleanup 76; CHECK-NEXT: [[PNEW2:%.*]] = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LPAD]], i32 0, i32 0) 77; CHECK-NEXT: [[CMP2:%.*]] = icmp ne ptr addrspace(1) [[PNEW2]], null 78; CHECK-NEXT: ret i1 [[CMP2]] 79; 80entry: 81 %safepoint_token = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p)] 82 to label %normal_dest unwind label %unwind_dest 83 84normal_dest: 85 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 86 %cmp = icmp eq ptr addrspace(1) %pnew, null 87 ret i1 %cmp 88unwind_dest: 89 %lpad = landingpad token 90 cleanup 91 %pnew2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lpad, i32 0, i32 0) 92 %cmp2 = icmp ne ptr addrspace(1) %pnew2, null 93 ret i1 %cmp2 94} 95 96define i1 @test_nonnull_invoke(ptr addrspace(1) nonnull %p) gc "statepoint-example" personality ptr @fake_personality_function { 97; CHECK-LABEL: @test_nonnull_invoke( 98; CHECK-NEXT: entry: 99; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 100; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] 101; CHECK: normal_dest: 102; CHECK-NEXT: ret i1 false 103; CHECK: unwind_dest: 104; CHECK-NEXT: [[LPAD:%.*]] = landingpad token 105; CHECK-NEXT: cleanup 106; CHECK-NEXT: ret i1 true 107; 108entry: 109 %safepoint_token = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p)] 110 to label %normal_dest unwind label %unwind_dest 111 112normal_dest: 113 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 114 %cmp = icmp eq ptr addrspace(1) %pnew, null 115 ret i1 %cmp 116unwind_dest: 117 %lpad = landingpad token 118 cleanup 119 %pnew2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lpad, i32 0, i32 0) 120 %cmp2 = icmp ne ptr addrspace(1) %pnew2, null 121 ret i1 %cmp2 122} 123 124define i1 @test_null_invoke() gc "statepoint-example" personality ptr @fake_personality_function { 125; CHECK-LABEL: @test_null_invoke( 126; CHECK-NEXT: entry: 127; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 128; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] 129; CHECK: normal_dest: 130; CHECK-NEXT: ret i1 true 131; CHECK: unwind_dest: 132; CHECK-NEXT: [[LPAD:%.*]] = landingpad token 133; CHECK-NEXT: cleanup 134; CHECK-NEXT: ret i1 false 135; 136entry: 137 %safepoint_token = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) null)] 138 to label %normal_dest unwind label %unwind_dest 139 140normal_dest: 141 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 142 %cmp = icmp eq ptr addrspace(1) %pnew, null 143 ret i1 %cmp 144unwind_dest: 145 %lpad = landingpad token 146 cleanup 147 %pnew2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lpad, i32 0, i32 0) 148 %cmp2 = icmp ne ptr addrspace(1) %pnew2, null 149 ret i1 %cmp2 150} 151 152define i1 @test_undef_invoke() gc "statepoint-example" personality ptr @fake_personality_function { 153; CHECK-LABEL: @test_undef_invoke( 154; CHECK-NEXT: entry: 155; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr nonnull elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"() ] 156; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]] 157; CHECK: normal_dest: 158; CHECK-NEXT: ret i1 undef 159; CHECK: unwind_dest: 160; CHECK-NEXT: [[LPAD:%.*]] = landingpad token 161; CHECK-NEXT: cleanup 162; CHECK-NEXT: ret i1 undef 163; 164entry: 165 %safepoint_token = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) undef)] 166 to label %normal_dest unwind label %unwind_dest 167 168normal_dest: 169 %pnew = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0) 170 %cmp = icmp eq ptr addrspace(1) %pnew, null 171 ret i1 %cmp 172unwind_dest: 173 %lpad = landingpad token 174 cleanup 175 %pnew2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %lpad, i32 0, i32 0) 176 %cmp2 = icmp ne ptr addrspace(1) %pnew2, null 177 ret i1 %cmp2 178} 179 180declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 181declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) #3 182