1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s 3; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s 4 5 6define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" { 7; Note that the second extractelement is actually redundant here. A correct output would 8; be to reuse the existing obj as a base since it is actually a base pointer. 9; CHECK-LABEL: @test( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC:%.*]], i32 [[IDX:%.*]], !is_base_value !0 12; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX]] 13; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[BASE_EE]]) ] 14; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 15; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)* 16; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 17; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)* 18; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]] 19; 20entry: 21 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx 22 call void @do_safepoint() [ "deopt"() ] 23 ret i64 addrspace(1)* %obj 24} 25 26define i64 addrspace(1)* @test2(<2 x i64 addrspace(1)*>* %ptr, i1 %cnd, i32 %idx1, i32 %idx2) gc "statepoint-example" { 27; CHECK-LABEL: @test2( 28; CHECK-NEXT: entry: 29; CHECK-NEXT: br i1 [[CND:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 30; CHECK: taken: 31; CHECK-NEXT: [[OBJA:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR:%.*]], align 16 32; CHECK-NEXT: br label [[MERGE:%.*]] 33; CHECK: untaken: 34; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16 35; CHECK-NEXT: br label [[MERGE]] 36; CHECK: merge: 37; CHECK-NEXT: [[VEC_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ], !is_base_value !0 38; CHECK-NEXT: [[VEC:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ] 39; CHECK-NEXT: br i1 [[CND]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]] 40; CHECK: taken2: 41; CHECK-NEXT: [[OBJ0_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX1:%.*]], !is_base_value !0 42; CHECK-NEXT: [[OBJ0:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX1]] 43; CHECK-NEXT: br label [[MERGE2:%.*]] 44; CHECK: untaken2: 45; CHECK-NEXT: [[OBJ1_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX2:%.*]], !is_base_value !0 46; CHECK-NEXT: [[OBJ1:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX2]] 47; CHECK-NEXT: br label [[MERGE2]] 48; CHECK: merge2: 49; CHECK-NEXT: [[OBJ_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ0_BASE]], [[TAKEN2]] ], [ [[OBJ1_BASE]], [[UNTAKEN2]] ], !is_base_value !0 50; CHECK-NEXT: [[OBJ:%.*]] = phi i64 addrspace(1)* [ [[OBJ0]], [[TAKEN2]] ], [ [[OBJ1]], [[UNTAKEN2]] ] 51; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[OBJ_BASE]]) ] 52; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 53; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)* 54; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 55; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_BASE_RELOCATED]] to i64 addrspace(1)* 56; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]] 57; 58entry: 59 br i1 %cnd, label %taken, label %untaken 60 61taken: ; preds = %entry 62 %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 63 br label %merge 64 65untaken: ; preds = %entry 66 %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 67 br label %merge 68 69merge: ; preds = %untaken, %taken 70 %vec = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ] 71 br i1 %cnd, label %taken2, label %untaken2 72 73taken2: ; preds = %merge 74 %obj0 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx1 75 br label %merge2 76 77untaken2: ; preds = %merge 78 %obj1 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx2 79 br label %merge2 80 81merge2: ; preds = %untaken2, %taken2 82 %obj = phi i64 addrspace(1)* [ %obj0, %taken2 ], [ %obj1, %untaken2 ] 83 call void @do_safepoint() [ "deopt"() ] 84 ret i64 addrspace(1)* %obj 85} 86 87define i64 addrspace(1)* @test3(i64 addrspace(1)* %ptr) gc "statepoint-example" { 88; CHECK-LABEL: @test3( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[PTR:%.*]], i32 0, !is_base_value !0 91; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[PTR]], i32 0 92; CHECK-NEXT: [[OBJ_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 0, !is_base_value !0 93; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 0 94; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[OBJ_BASE]]) ] 95; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 96; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)* 97; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 98; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_BASE_RELOCATED]] to i64 addrspace(1)* 99; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]] 100; 101entry: 102 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %ptr, i32 0 103 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 104 call void @do_safepoint() [ "deopt"() ] 105 ret i64 addrspace(1)* %obj 106} 107 108define i64 addrspace(1)* @test4(i64 addrspace(1)* %ptr) gc "statepoint-example" { 109; When we can optimize an extractelement from a known 110; index and avoid introducing new base pointer instructions 111; CHECK-LABEL: @test4( 112; CHECK-NEXT: entry: 113; CHECK-NEXT: [[DERIVED:%.*]] = getelementptr i64, i64 addrspace(1)* [[PTR:%.*]], i64 16 114; CHECK-NEXT: [[VECA_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[PTR]], i32 0, !is_base_value !0 115; CHECK-NEXT: [[VECA:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[DERIVED]], i32 0 116; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> [[VECA_BASE]], i64 addrspace(1)* [[PTR]], i32 1, !is_base_value !0 117; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> [[VECA]], i64 addrspace(1)* [[PTR]], i32 1 118; CHECK-NEXT: [[OBJ_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 0, !is_base_value !0 119; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 0 120; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[OBJ_BASE]]) ] 121; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 122; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)* 123; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 124; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_BASE_RELOCATED]] to i64 addrspace(1)* 125; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]] 126; 127entry: 128 %derived = getelementptr i64, i64 addrspace(1)* %ptr, i64 16 129 %veca = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %derived, i32 0 130 %vec = insertelement <2 x i64 addrspace(1)*> %veca, i64 addrspace(1)* %ptr, i32 1 131 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 132 call void @do_safepoint() [ "deopt"() ] 133 ret i64 addrspace(1)* %obj 134} 135 136declare void @use(i64 addrspace(1)*) "gc-leaf-function" 137declare void @use_vec(<4 x i64 addrspace(1)*>) "gc-leaf-function" 138 139define void @test5(i1 %cnd, i64 addrspace(1)* %obj) gc "statepoint-example" { 140; When we fundementally have to duplicate 141; CHECK-LABEL: @test5( 142; CHECK-NEXT: entry: 143; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, i64 addrspace(1)* [[OBJ:%.*]], i64 1 144; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ]], i32 0, !is_base_value !0 145; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[GEP]], i32 0 146; CHECK-NEXT: [[BDV_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 0, !is_base_value !0 147; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 0 148; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ] 149; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 150; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)* 151; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 152; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)* 153; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]) 154; CHECK-NEXT: ret void 155; 156entry: 157 %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1 158 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 159 %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 160 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 161 call void @use(i64 addrspace(1)* %bdv) 162 ret void 163} 164 165define void @test6(i1 %cnd, i64 addrspace(1)* %obj, i64 %idx) gc "statepoint-example" { 166; A more complicated example involving vector and scalar bases. 167; This is derived from a failing test case when we didn't have correct 168; insertelement handling. 169; CHECK-LABEL: @test6( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, i64 addrspace(1)* [[OBJ:%.*]], i64 1 172; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ]], i32 0, !is_base_value !0 173; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[GEP]], i32 0 174; CHECK-NEXT: [[BDV_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i64 [[IDX:%.*]], !is_base_value !0 175; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX]] 176; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ] 177; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 178; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)* 179; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 180; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)* 181; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]) 182; CHECK-NEXT: ret void 183; 184entry: 185 %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1 186 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 187 %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx 188 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 189 call void @use(i64 addrspace(1)* %bdv) 190 ret void 191} 192 193define i64 addrspace(1)* @test7(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" { 194; CHECK-LABEL: @test7( 195; CHECK-NEXT: entry: 196; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ2:%.*]], i32 0, !is_base_value !0 197; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[OBJ2]], i32 0 198; CHECK-NEXT: br label [[MERGE1:%.*]] 199; CHECK: merge1: 200; CHECK-NEXT: [[VEC2_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[VEC_BASE]], [[ENTRY:%.*]] ], [ [[VEC3_BASE:%.*]], [[MERGE1]] ], !is_base_value !0 201; CHECK-NEXT: [[VEC2:%.*]] = phi <2 x i64 addrspace(1)*> [ [[VEC]], [[ENTRY]] ], [ [[VEC3:%.*]], [[MERGE1]] ] 202; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, i64 addrspace(1)* [[OBJ2]], i64 1 203; CHECK-NEXT: [[VEC3_BASE]] = insertelement <2 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ2]], i32 0, !is_base_value !0 204; CHECK-NEXT: [[VEC3]] = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[GEP]], i32 0 205; CHECK-NEXT: br i1 [[CND:%.*]], label [[MERGE1]], label [[NEXT1:%.*]] 206; CHECK: next1: 207; CHECK-NEXT: [[BDV_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC2_BASE]], i32 0, !is_base_value !0 208; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC2]], i32 0 209; CHECK-NEXT: br label [[MERGE:%.*]] 210; CHECK: merge: 211; CHECK-NEXT: [[OBJB_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[NEXT1]] ], [ [[BDV_BASE]], [[MERGE]] ], !is_base_value !0 212; CHECK-NEXT: [[OBJB:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[NEXT1]] ], [ [[BDV]], [[MERGE]] ] 213; CHECK-NEXT: br i1 [[CND]], label [[MERGE]], label [[NEXT:%.*]] 214; CHECK: next: 215; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[OBJB]], i64 addrspace(1)* [[OBJB_BASE]]) ] 216; CHECK-NEXT: [[OBJB_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 217; CHECK-NEXT: [[OBJB_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJB_RELOCATED]] to i64 addrspace(1)* 218; CHECK-NEXT: [[OBJB_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 219; CHECK-NEXT: [[OBJB_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJB_BASE_RELOCATED]] to i64 addrspace(1)* 220; CHECK-NEXT: ret i64 addrspace(1)* [[OBJB_RELOCATED_CASTED]] 221; 222entry: 223 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj2, i32 0 224 br label %merge1 225 226merge1: ; preds = %merge1, %entry 227 %vec2 = phi <2 x i64 addrspace(1)*> [ %vec, %entry ], [ %vec3, %merge1 ] 228 %gep = getelementptr i64, i64 addrspace(1)* %obj2, i64 1 229 %vec3 = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 230 br i1 %cnd, label %merge1, label %next1 231 232next1: ; preds = %merge1 233 %bdv = extractelement <2 x i64 addrspace(1)*> %vec2, i32 0 234 br label %merge 235 236merge: ; preds = %merge, %next1 237 %objb = phi i64 addrspace(1)* [ %obj, %next1 ], [ %bdv, %merge ] 238 br i1 %cnd, label %merge, label %next 239 240next: ; preds = %merge 241 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 242 ret i64 addrspace(1)* %objb 243} 244 245; identify base for shufflevector 246define void @test8(i64 addrspace(1)* %obj, i64 %idx) gc "statepoint-example" { 247; CHECK-LABEL: @test8( 248; CHECK-NEXT: entry: 249; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, i64 addrspace(1)* [[OBJ:%.*]], i64 1 250; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i64, i64 addrspace(1)* [[OBJ]], i64 2 251; CHECK-NEXT: [[VEC1_BASE:%.*]] = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ]], i32 0, !is_base_value !0 252; CHECK-NEXT: [[VEC1:%.*]] = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[GEP]], i32 0 253; CHECK-NEXT: [[VEC2_BASE:%.*]] = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ]], i32 2, !is_base_value !0 254; CHECK-NEXT: [[VEC2:%.*]] = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[GEP2]], i32 2 255; CHECK-NEXT: [[VEC_BASE:%.*]] = shufflevector <4 x i64 addrspace(1)*> [[VEC1_BASE]], <4 x i64 addrspace(1)*> [[VEC2_BASE]], <2 x i32> <i32 0, i32 2>, !is_base_value !0 256; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i64 addrspace(1)*> [[VEC1]], <4 x i64 addrspace(1)*> [[VEC2]], <2 x i32> <i32 0, i32 2> 257; CHECK-NEXT: [[BDV_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i64 [[IDX:%.*]], !is_base_value !0 258; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX]] 259; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ] 260; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 261; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)* 262; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 263; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)* 264; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]) 265; CHECK-NEXT: ret void 266; 267entry: 268 %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1 269 %gep2 = getelementptr i64, i64 addrspace(1)* %obj, i64 2 270 %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 271 %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep2, i32 2 272 %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec2, <2 x i32> <i32 0, i32 2> 273 %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx 274 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 275 call void @use(i64 addrspace(1)* %bdv) 276 ret void 277} 278 279; Since the same 'base' vector is used in the shuffle operands, we do not need 280; create a shufflevector base. 281define void @test9(<4 x i64 addrspace(1)*> %vec1, i64 %idx) gc "statepoint-example" { 282; CHECK-LABEL: @test9( 283; CHECK-NEXT: entry: 284; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i64 addrspace(1)*> [[VEC1:%.*]], <4 x i64 addrspace(1)*> [[VEC1]], <2 x i32> <i32 0, i32 2> 285; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <4 x i64 addrspace(1)*> [[VEC1]], i64 [[IDX:%.*]], !is_base_value !0 286; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX]] 287; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BASE_EE]]) ] 288; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 289; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)* 290; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 291; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)* 292; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]) 293; CHECK-NEXT: ret void 294; 295entry: 296 ; shrinking vec1 into vec 297 %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec1, <2 x i32> <i32 0, i32 2> 298 %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx 299 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 300 call void @use(i64 addrspace(1)* %bdv) 301 ret void 302} 303 304; vector operand of shufflevector is a phi 305define i64 addrspace(1)* @test10(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" { 306; CHECK-LABEL: @test10( 307; CHECK-NEXT: entry: 308; CHECK-NEXT: [[VEC1_BASE:%.*]] = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ:%.*]], i32 0, !is_base_value !0 309; CHECK-NEXT: [[VEC1:%.*]] = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[OBJ]], i32 0 310; CHECK-NEXT: br i1 [[CND:%.*]], label [[HERE:%.*]], label [[MERGE:%.*]] 311; CHECK: here: 312; CHECK-NEXT: [[VEC2_BASE:%.*]] = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* [[OBJ2:%.*]], i32 2, !is_base_value !0 313; CHECK-NEXT: [[VEC2:%.*]] = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* [[OBJ2]], i32 2 314; CHECK-NEXT: br label [[MERGE]] 315; CHECK: merge: 316; CHECK-NEXT: [[VEC_BASE:%.*]] = phi <4 x i64 addrspace(1)*> [ [[VEC1_BASE]], [[ENTRY:%.*]] ], [ [[VEC2_BASE]], [[HERE]] ], [ [[VEC3_BASE:%.*]], [[MERGE]] ], !is_base_value !0 317; CHECK-NEXT: [[VEC:%.*]] = phi <4 x i64 addrspace(1)*> [ [[VEC1]], [[ENTRY]] ], [ [[VEC2]], [[HERE]] ], [ [[VEC3:%.*]], [[MERGE]] ] 318; CHECK-NEXT: [[VEC3_BASE]] = shufflevector <4 x i64 addrspace(1)*> [[VEC_BASE]], <4 x i64 addrspace(1)*> [[VEC_BASE]], <4 x i32> <i32 2, i32 0, i32 1, i32 3>, !is_base_value !0 319; CHECK-NEXT: [[VEC3]] = shufflevector <4 x i64 addrspace(1)*> [[VEC]], <4 x i64 addrspace(1)*> [[VEC]], <4 x i32> <i32 2, i32 0, i32 1, i32 3> 320; CHECK-NEXT: [[BDV_BASE:%.*]] = extractelement <4 x i64 addrspace(1)*> [[VEC3_BASE]], i32 0, !is_base_value !0 321; CHECK-NEXT: [[BDV:%.*]] = extractelement <4 x i64 addrspace(1)*> [[VEC3]], i32 0 322; CHECK-NEXT: br i1 [[CND]], label [[MERGE]], label [[NEXT:%.*]] 323; CHECK: next: 324; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ] 325; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0) 326; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)* 327; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1) 328; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)* 329; CHECK-NEXT: ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]] 330; 331entry: 332 %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj, i32 0 333 br i1 %cnd, label %here, label %merge 334 335here: 336 %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj2, i32 2 337 br label %merge 338 339merge: ; preds = %merge, %entry, %here 340 %vec = phi <4 x i64 addrspace(1)*> [ %vec1, %entry ], [ %vec2, %here], [ %vec3, %merge] 341 %vec3 = shufflevector <4 x i64 addrspace(1)*> %vec, <4 x i64 addrspace(1)*> %vec, <4 x i32> <i32 2, i32 0, i32 1, i32 3> 342 %bdv = extractelement <4 x i64 addrspace(1)*> %vec3, i32 0 343 br i1 %cnd, label %merge, label %next 344 345next: 346 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 347 ret i64 addrspace(1)* %bdv 348} 349declare void @do_safepoint() 350 351define void @test11(<4 x i64 addrspace(1)*> %vec1) gc "statepoint-example" { 352; CHECK-LABEL: @test11( 353; CHECK-NEXT: entry: 354; CHECK-NEXT: [[VEC2:%.*]] = getelementptr i64, <4 x i64 addrspace(1)*> [[VEC1:%.*]], i32 1024 355; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(<4 x i64 addrspace(1)*> [[VEC1]]) ] 356; CHECK-NEXT: [[VEC1_RELOCATED:%.*]] = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0) 357; CHECK-NEXT: [[VEC1_RELOCATED_CASTED:%.*]] = bitcast <4 x i8 addrspace(1)*> [[VEC1_RELOCATED]] to <4 x i64 addrspace(1)*> 358; CHECK-NEXT: [[VEC2_REMAT:%.*]] = getelementptr i64, <4 x i64 addrspace(1)*> [[VEC1_RELOCATED_CASTED]], i32 1024 359; CHECK-NEXT: call void @use_vec(<4 x i64 addrspace(1)*> [[VEC2_REMAT]]) 360; CHECK-NEXT: ret void 361; 362entry: 363 %vec2 = getelementptr i64, <4 x i64 addrspace(1)*> %vec1, i32 1024 364 call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] 365 call void @use_vec(<4 x i64 addrspace(1) *> %vec2) 366 ret void 367} 368 369declare <4 x i64 addrspace(1)*> @def_vec() "gc-leaf-function" 370 371define void @test12(<4 x i64 addrspace(1)*> %vec1) gc "statepoint-example" { 372; CHECK-LABEL: @test12( 373; CHECK-NEXT: entry: 374; CHECK-NEXT: [[VEC:%.*]] = call <4 x i64 addrspace(1)*> @def_vec() 375; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<4 x i64 addrspace(1)*> [[VEC]]) ] 376; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0) 377; CHECK-NEXT: [[VEC_RELOCATED_CASTED:%.*]] = bitcast <4 x i8 addrspace(1)*> [[VEC_RELOCATED]] to <4 x i64 addrspace(1)*> 378; CHECK-NEXT: call void @use_vec(<4 x i64 addrspace(1)*> [[VEC_RELOCATED_CASTED]]) 379; CHECK-NEXT: ret void 380; 381entry: 382 %vec = call <4 x i64 addrspace(1)*> @def_vec() 383 call void @do_safepoint() [ "deopt"() ] 384 call void @use_vec(<4 x i64 addrspace(1)*> %vec) 385 ret void 386} 387