398 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s3 4 5declare void @use_obj16(ptr addrspace(1)) "gc-leaf-function"6declare void @use_obj32(ptr addrspace(1)) "gc-leaf-function"7declare void @use_obj64(ptr addrspace(1)) "gc-leaf-function"8 9declare void @do_safepoint()10 11define void @test_gep_const(ptr addrspace(1) %base) gc "statepoint-example" {12; CHECK-LABEL: @test_gep_const(13; CHECK-NEXT: entry:14; CHECK-NEXT: [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 1515; 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]]) ]16; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)17; CHECK-NEXT: [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 1518; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])19; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])20; CHECK-NEXT: ret void21;22entry:23 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 1524 call void @do_safepoint() [ "deopt"() ]25 call void @use_obj32(ptr addrspace(1) %base)26 call void @use_obj32(ptr addrspace(1) %ptr)27 ret void28}29 30define void @test_gep_idx(ptr addrspace(1) %base, i32 %idx) gc "statepoint-example" {31; CHECK-LABEL: @test_gep_idx(32; CHECK-NEXT: entry:33; CHECK-NEXT: [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 [[IDX:%.*]]34; 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]]) ]35; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)36; CHECK-NEXT: [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 [[IDX]]37; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])38; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])39; CHECK-NEXT: ret void40;41entry:42 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 %idx43 call void @do_safepoint() [ "deopt"() ]44 call void @use_obj32(ptr addrspace(1) %base)45 call void @use_obj32(ptr addrspace(1) %ptr)46 ret void47}48 49define void @test_bitcast(ptr addrspace(1) %base) gc "statepoint-example" {50; CHECK-LABEL: @test_bitcast(51; CHECK-NEXT: entry:52; 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:%.*]]) ]53; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)54; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])55; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[BASE_RELOCATED]])56; CHECK-NEXT: ret void57;58entry:59 call void @do_safepoint() [ "deopt"() ]60 call void @use_obj32(ptr addrspace(1) %base)61 call void @use_obj64(ptr addrspace(1) %base)62 ret void63}64 65define void @test_bitcast_bitcast(ptr addrspace(1) %base) gc "statepoint-example" {66; CHECK-LABEL: @test_bitcast_bitcast(67; CHECK-NEXT: entry:68; 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:%.*]]) ]69; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)70; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])71; CHECK-NEXT: call void @use_obj16(ptr addrspace(1) [[BASE_RELOCATED]])72; CHECK-NEXT: ret void73;74entry:75 call void @do_safepoint() [ "deopt"() ]76 77 call void @use_obj32(ptr addrspace(1) %base)78 call void @use_obj16(ptr addrspace(1) %base)79 ret void80}81 82define void @test_addrspacecast_addrspacecast(ptr addrspace(1) %base) gc "statepoint-example" {83; CHECK-LABEL: @test_addrspacecast_addrspacecast(84; CHECK-NEXT: entry:85; CHECK-NEXT: [[PTR1:%.*]] = addrspacecast ptr addrspace(1) [[BASE:%.*]] to ptr86; CHECK-NEXT: [[PTR2:%.*]] = addrspacecast ptr [[PTR1]] to ptr addrspace(1)87; 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) [[PTR2]], ptr addrspace(1) [[BASE]]) ]88; CHECK-NEXT: [[PTR2_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)89; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)90; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])91; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR2_RELOCATED]])92; CHECK-NEXT: ret void93;94entry:95 %ptr1 = addrspacecast ptr addrspace(1) %base to ptr96 %ptr2 = addrspacecast ptr %ptr1 to ptr addrspace(1)97 call void @do_safepoint() [ "deopt"() ]98 99 call void @use_obj32(ptr addrspace(1) %base)100 call void @use_obj32(ptr addrspace(1) %ptr2)101 ret void102}103 104define void @test_bitcast_gep(ptr addrspace(1) %base) gc "statepoint-example" {105; CHECK-LABEL: @test_bitcast_gep(106; CHECK-NEXT: entry:107; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15108; 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]]) ]109; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)110; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15111; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])112; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])113; CHECK-NEXT: ret void114;115entry:116 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15117 call void @do_safepoint() [ "deopt"() ]118 119 call void @use_obj32(ptr addrspace(1) %base)120 call void @use_obj64(ptr addrspace(1) %ptr.gep)121 ret void122}123 124define void @test_intersecting_chains(ptr addrspace(1) %base, i32 %idx) gc "statepoint-example" {125; CHECK-LABEL: @test_intersecting_chains(126; CHECK-NEXT: entry:127; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15128; 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]]) ]129; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)130; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15131; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])132; CHECK-NEXT: call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])133; CHECK-NEXT: ret void134;135entry:136 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15137 call void @do_safepoint() [ "deopt"() ]138 139 call void @use_obj64(ptr addrspace(1) %ptr.gep)140 call void @use_obj16(ptr addrspace(1) %ptr.gep)141 ret void142}143 144define void @test_cost_threshold(ptr addrspace(1) %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {145; CHECK-LABEL: @test_cost_threshold(146; CHECK-NEXT: entry:147; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15148; CHECK-NEXT: [[PTR_GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP]], i32 [[IDX1:%.*]]149; CHECK-NEXT: [[PTR_GEP3:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP2]], i32 [[IDX2:%.*]]150; CHECK-NEXT: [[PTR_GEP4:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP3]], i32 [[IDX3:%.*]]151; 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) [[PTR_GEP4]], ptr addrspace(1) [[BASE]]) ]152; CHECK-NEXT: [[PTR_GEP4_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)153; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)154; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP4_RELOCATED]])155; CHECK-NEXT: ret void156;157entry:158 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15159 %ptr.gep2 = getelementptr i32, ptr addrspace(1) %ptr.gep, i32 %idx1160 %ptr.gep3 = getelementptr i32, ptr addrspace(1) %ptr.gep2, i32 %idx2161 %ptr.gep4 = getelementptr i32, ptr addrspace(1) %ptr.gep3, i32 %idx3162 call void @do_safepoint() [ "deopt"() ]163 164 call void @use_obj64(ptr addrspace(1) %ptr.gep4)165 ret void166}167 168define void @test_two_derived(ptr addrspace(1) %base) gc "statepoint-example" {169; CHECK-LABEL: @test_two_derived(170; CHECK-NEXT: entry:171; CHECK-NEXT: [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15172; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE]], i32 12173; 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]]) ]174; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)175; CHECK-NEXT: [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15176; CHECK-NEXT: [[PTR2_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 12177; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])178; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR2_REMAT]])179; CHECK-NEXT: ret void180;181entry:182 %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15183 %ptr2 = getelementptr i32, ptr addrspace(1) %base, i32 12184 call void @do_safepoint() [ "deopt"() ]185 186 call void @use_obj32(ptr addrspace(1) %ptr)187 call void @use_obj32(ptr addrspace(1) %ptr2)188 ret void189}190 191define void @test_gep_smallint_array(ptr addrspace(1) %base) gc "statepoint-example" {192; CHECK-LABEL: @test_gep_smallint_array(193; CHECK-NEXT: entry:194; CHECK-NEXT: [[PTR:%.*]] = getelementptr [3 x i32], ptr addrspace(1) [[BASE:%.*]], i32 0, i32 2195; 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]]) ]196; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)197; CHECK-NEXT: [[PTR_REMAT:%.*]] = getelementptr [3 x i32], ptr addrspace(1) [[BASE_RELOCATED]], i32 0, i32 2198; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])199; CHECK-NEXT: ret void200;201entry:202 %ptr = getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 2203 call void @do_safepoint() [ "deopt"() ]204 205 call void @use_obj32(ptr addrspace(1) %ptr)206 ret void207}208 209declare i32 @fake_personality_function()210 211define void @test_invoke(ptr addrspace(1) %base) gc "statepoint-example" personality ptr @fake_personality_function {212; CHECK-LABEL: @test_invoke(213; CHECK-NEXT: entry:214; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15215; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = invoke 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]]) ]216; CHECK-NEXT: to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]217; CHECK: normal:218; CHECK-NEXT: [[BASE_RELOCATED2:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)219; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED2]], i32 15220; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])221; CHECK-NEXT: call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])222; CHECK-NEXT: ret void223; CHECK: exception:224; CHECK-NEXT: [[LANDING_PAD4:%.*]] = landingpad token225; CHECK-NEXT: cleanup226; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 0, i32 0)227; CHECK-NEXT: [[PTR_GEP_REMAT1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15228; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT1]])229; CHECK-NEXT: call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT1]])230; CHECK-NEXT: ret void231;232entry:233 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15234 invoke void @do_safepoint() [ "deopt"() ]235 to label %normal unwind label %exception236 237normal:238 call void @use_obj64(ptr addrspace(1) %ptr.gep)239 call void @use_obj16(ptr addrspace(1) %ptr.gep)240 ret void241 242exception:243 %landing_pad4 = landingpad token244 cleanup245 call void @use_obj64(ptr addrspace(1) %ptr.gep)246 call void @use_obj16(ptr addrspace(1) %ptr.gep)247 ret void248}249 250define void @test_loop(ptr addrspace(1) %base) gc "statepoint-example" {251; CHECK-LABEL: @test_loop(252; CHECK-NEXT: entry:253; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15254; CHECK-NEXT: br label [[LOOP:%.*]]255; CHECK: loop:256; CHECK-NEXT: [[DOT0:%.*]] = phi ptr addrspace(1) [ [[BASE]], [[ENTRY:%.*]] ], [ [[BASE_RELOCATED:%.*]], [[LOOP]] ]257; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[DOT0]], i32 15258; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP_REMAT]])259; 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) [[DOT0]]) ]260; CHECK-NEXT: [[BASE_RELOCATED]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)261; CHECK-NEXT: br label [[LOOP]]262;263entry:264 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15265 br label %loop266 267loop: ; preds = %loop, %entry268 call void @use_obj32(ptr addrspace(1) %ptr.gep)269 call void @do_safepoint() [ "deopt"() ]270 br label %loop271}272 273define void @test_too_long(ptr addrspace(1) %base) gc "statepoint-example" {274; CHECK-LABEL: @test_too_long(275; CHECK-NEXT: entry:276; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15277; CHECK-NEXT: [[PTR_GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP]], i32 15278; CHECK-NEXT: [[PTR_GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP1]], i32 15279; CHECK-NEXT: [[PTR_GEP3:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP2]], i32 15280; CHECK-NEXT: [[PTR_GEP4:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP3]], i32 15281; CHECK-NEXT: [[PTR_GEP5:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP4]], i32 15282; CHECK-NEXT: [[PTR_GEP6:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP5]], i32 15283; CHECK-NEXT: [[PTR_GEP7:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP6]], i32 15284; CHECK-NEXT: [[PTR_GEP8:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP7]], i32 15285; CHECK-NEXT: [[PTR_GEP9:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP8]], i32 15286; CHECK-NEXT: [[PTR_GEP10:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP9]], i32 15287; CHECK-NEXT: [[PTR_GEP11:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP10]], i32 15288; 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) [[PTR_GEP11]], ptr addrspace(1) [[BASE]]) ]289; CHECK-NEXT: [[PTR_GEP11_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)290; CHECK-NEXT: [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)291; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP11_RELOCATED]])292; CHECK-NEXT: ret void293;294entry:295 %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15296 %ptr.gep1 = getelementptr i32, ptr addrspace(1) %ptr.gep, i32 15297 %ptr.gep2 = getelementptr i32, ptr addrspace(1) %ptr.gep1, i32 15298 %ptr.gep3 = getelementptr i32, ptr addrspace(1) %ptr.gep2, i32 15299 %ptr.gep4 = getelementptr i32, ptr addrspace(1) %ptr.gep3, i32 15300 %ptr.gep5 = getelementptr i32, ptr addrspace(1) %ptr.gep4, i32 15301 %ptr.gep6 = getelementptr i32, ptr addrspace(1) %ptr.gep5, i32 15302 %ptr.gep7 = getelementptr i32, ptr addrspace(1) %ptr.gep6, i32 15303 %ptr.gep8 = getelementptr i32, ptr addrspace(1) %ptr.gep7, i32 15304 %ptr.gep9 = getelementptr i32, ptr addrspace(1) %ptr.gep8, i32 15305 %ptr.gep10 = getelementptr i32, ptr addrspace(1) %ptr.gep9, i32 15306 %ptr.gep11 = getelementptr i32, ptr addrspace(1) %ptr.gep10, i32 15307 call void @do_safepoint() [ "deopt"() ]308 call void @use_obj32(ptr addrspace(1) %ptr.gep11)309 ret void310}311 312 313declare ptr addrspace(1) @new_instance() nounwind "gc-leaf-function"314 315; remat the gep in presence of base pointer which is a phi node.316; FIXME: We should remove the extra basephi.base as well.317define void @contains_basephi(i1 %cond) gc "statepoint-example" {318; CHECK-LABEL: @contains_basephi(319; CHECK-NEXT: entry:320; CHECK-NEXT: [[BASE1:%.*]] = call ptr addrspace(1) @new_instance()321; CHECK-NEXT: [[BASE2:%.*]] = call ptr addrspace(1) @new_instance()322; CHECK-NEXT: br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]323; CHECK: here:324; CHECK-NEXT: br label [[MERGE:%.*]]325; CHECK: there:326; CHECK-NEXT: br label [[MERGE]]327; CHECK: merge:328; CHECK-NEXT: [[BASEPHI:%.*]] = phi ptr addrspace(1) [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]329; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI]], i32 15330; 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) [[BASEPHI]]) ]331; CHECK-NEXT: [[BASEPHI_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)332; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI_RELOCATED]], i32 15333; CHECK-NEXT: call void @use_obj32(ptr addrspace(1) [[PTR_GEP_REMAT]])334; CHECK-NEXT: ret void335;336entry:337 %base1 = call ptr addrspace(1) @new_instance()338 %base2 = call ptr addrspace(1) @new_instance()339 br i1 %cond, label %here, label %there340 341here:342 br label %merge343 344there:345 br label %merge346 347merge:348 349 350 351 %basephi = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ]352 %ptr.gep = getelementptr i32, ptr addrspace(1) %basephi, i32 15353 call void @do_safepoint() ["deopt"() ]354 call void @use_obj32(ptr addrspace(1) %ptr.gep)355 ret void356}357 358 359define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" {360; CHECK-LABEL: @test_intersecting_chains_with_phi(361; CHECK-NEXT: entry:362; CHECK-NEXT: [[BASE1:%.*]] = call ptr addrspace(1) @new_instance()363; CHECK-NEXT: [[BASE2:%.*]] = call ptr addrspace(1) @new_instance()364; CHECK-NEXT: br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]365; CHECK: here:366; CHECK-NEXT: br label [[MERGE:%.*]]367; CHECK: there:368; CHECK-NEXT: br label [[MERGE]]369; CHECK: merge:370; CHECK-NEXT: [[BASEPHI:%.*]] = phi ptr addrspace(1) [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]371; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI]], i32 15372; 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) [[BASEPHI]]) ]373; CHECK-NEXT: [[BASEPHI_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)374; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI_RELOCATED]], i32 15375; CHECK-NEXT: call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])376; CHECK-NEXT: call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])377; CHECK-NEXT: ret void378;379entry:380 %base1 = call ptr addrspace(1) @new_instance()381 %base2 = call ptr addrspace(1) @new_instance()382 br i1 %cond, label %here, label %there383 384here:385 br label %merge386 387there:388 br label %merge389 390merge:391 %basephi = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ]392 %ptr.gep = getelementptr i32, ptr addrspace(1) %basephi, i32 15393 call void @do_safepoint() [ "deopt"() ]394 call void @use_obj64(ptr addrspace(1) %ptr.gep)395 call void @use_obj16(ptr addrspace(1) %ptr.gep)396 ret void397}398