372 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG4 5target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"6 7declare void @llvm.memcpy.p0.p1.i32(ptr nocapture writeonly, ptr addrspace(1) nocapture readonly, i32, i1 immarg) #08declare void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) nocapture writeonly, ptr nocapture readonly, i32, i1 immarg) #09 10define i64 @alloca_addrspacecast_bitcast(i64 %X) {11; CHECK-LABEL: @alloca_addrspacecast_bitcast(12; CHECK-NEXT: entry:13; CHECK-NEXT: ret i64 [[X:%.*]]14;15entry:16 %A = alloca [8 x i8]17 %A.cast = addrspacecast ptr %A to ptr addrspace(1)18 store i64 %X, ptr addrspace(1) %A.cast19 %Z = load i64, ptr addrspace(1) %A.cast20 ret i64 %Z21}22 23define i64 @alloca_bitcast_addrspacecast(i64 %X) {24; CHECK-LABEL: @alloca_bitcast_addrspacecast(25; CHECK-NEXT: entry:26; CHECK-NEXT: ret i64 [[X:%.*]]27;28entry:29 %A = alloca [8 x i8]30 %B = addrspacecast ptr %A to ptr addrspace(1)31 store i64 %X, ptr addrspace(1) %B32 %Z = load i64, ptr addrspace(1) %B33 ret i64 %Z34}35 36define i64 @alloca_addrspacecast_gep(i64 %X) {37; CHECK-LABEL: @alloca_addrspacecast_gep(38; CHECK-NEXT: entry:39; CHECK-NEXT: ret i64 [[X:%.*]]40;41entry:42 %A.as0 = alloca [256 x i8], align 443 44 %gepA.as0 = getelementptr [256 x i8], ptr %A.as0, i16 0, i16 3245 store i64 %X, ptr %gepA.as0, align 446 47 %A.as1 = addrspacecast ptr %A.as0 to ptr addrspace(1)48 %gepA.as1 = getelementptr [256 x i8], ptr addrspace(1) %A.as1, i16 0, i16 3249 %Z = load i64, ptr addrspace(1) %gepA.as1, align 450 51 ret i64 %Z52}53 54define i64 @alloca_gep_addrspacecast(i64 %X) {55; CHECK-LABEL: @alloca_gep_addrspacecast(56; CHECK-NEXT: entry:57; CHECK-NEXT: ret i64 [[X:%.*]]58;59entry:60 %A.as0 = alloca [256 x i8], align 461 62 %gepA.as0 = getelementptr [256 x i8], ptr %A.as0, i16 0, i16 3263 store i64 %X, ptr %gepA.as0, align 464 65 %gepA.as1.bc = addrspacecast ptr %gepA.as0 to ptr addrspace(1)66 %Z = load i64, ptr addrspace(1) %gepA.as1.bc, align 467 ret i64 %Z68}69 70define i64 @alloca_gep_addrspacecast_gep(i64 %X) {71; CHECK-LABEL: @alloca_gep_addrspacecast_gep(72; CHECK-NEXT: entry:73; CHECK-NEXT: ret i64 [[X:%.*]]74;75entry:76 %A.as0 = alloca [256 x i8], align 477 78 %gepA.as0 = getelementptr [256 x i8], ptr %A.as0, i16 0, i16 3279 store i64 %X, ptr %gepA.as0, align 480 81 82 %gepB.as0 = getelementptr [256 x i8], ptr %A.as0, i16 0, i16 1683 %gepB.as1 = addrspacecast ptr %gepB.as0 to ptr addrspace(1)84 %gepC.as1 = getelementptr i8, ptr addrspace(1) %gepB.as1, i16 1685 %Z = load i64, ptr addrspace(1) %gepC.as1, align 486 87 ret i64 %Z88}89 90define i64 @getAdjustedPtr_addrspacecast_gep(ptr %x) {91; CHECK-LABEL: @getAdjustedPtr_addrspacecast_gep(92; CHECK-NEXT: entry:93; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(1)94; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[CAST1]], align 195; CHECK-NEXT: [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i16 896; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[A_SROA_2_0_CAST1_SROA_IDX]], align 197; CHECK-NEXT: ret i64 [[A_SROA_0_0_COPYLOAD]]98;99entry:100 %a = alloca [32 x i8], align 8101 %cast1 = addrspacecast ptr %x to ptr addrspace(1)102 call void @llvm.memcpy.p0.p1.i32(ptr %a, ptr addrspace(1) %cast1, i32 16, i1 false)103 %val = load i64, ptr %a104 ret i64 %val105}106 107define i64 @getAdjustedPtr_gep_addrspacecast(ptr %x) {108; CHECK-LABEL: @getAdjustedPtr_gep_addrspacecast(109; CHECK-NEXT: entry:110; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr [32 x i8], ptr [[X:%.*]], i32 0, i32 16111; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[GEP_X]] to ptr addrspace(1)112; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[CAST1]], align 1113; CHECK-NEXT: [[A_SROA_2_0_CAST1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i16 8114; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[A_SROA_2_0_CAST1_SROA_IDX]], align 1115; CHECK-NEXT: ret i64 [[A_SROA_0_0_COPYLOAD]]116;117entry:118 %a = alloca [32 x i8], align 8119 %gep.x = getelementptr [32 x i8], ptr %x, i32 0, i32 16120 %cast1 = addrspacecast ptr %gep.x to ptr addrspace(1)121 122 call void @llvm.memcpy.p0.p1.i32(ptr %a, ptr addrspace(1) %cast1, i32 16, i1 false)123 %val = load i64, ptr %a124 ret i64 %val125}126 127define i64 @getAdjustedPtr_gep_addrspacecast_gep(ptr %x) {128; CHECK-LABEL: @getAdjustedPtr_gep_addrspacecast_gep(129; CHECK-NEXT: entry:130; CHECK-NEXT: [[GEP0_X:%.*]] = getelementptr [32 x i8], ptr [[X:%.*]], i32 0, i32 8131; CHECK-NEXT: [[CAST1:%.*]] = addrspacecast ptr [[GEP0_X]] to ptr addrspace(1)132; CHECK-NEXT: [[GEP1_X:%.*]] = getelementptr i8, ptr addrspace(1) [[CAST1]], i32 8133; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[GEP1_X]], align 1134; CHECK-NEXT: [[A_SROA_2_0_GEP1_X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[GEP1_X]], i16 8135; CHECK-NEXT: [[A_SROA_2_0_COPYLOAD:%.*]] = load i64, ptr addrspace(1) [[A_SROA_2_0_GEP1_X_SROA_IDX]], align 1136; CHECK-NEXT: ret i64 [[A_SROA_0_0_COPYLOAD]]137;138entry:139 %a = alloca [32 x i8], align 8140 %gep0.x = getelementptr [32 x i8], ptr %x, i32 0, i32 8141 %cast1 = addrspacecast ptr %gep0.x to ptr addrspace(1)142 %gep1.x = getelementptr i8, ptr addrspace(1) %cast1, i32 8143 144 call void @llvm.memcpy.p0.p1.i32(ptr %a, ptr addrspace(1) %gep1.x, i32 16, i1 false)145 %val = load i64, ptr %a146 ret i64 %val147}148 149; Don't change the address space of a volatile operation150define i64 @alloca_addrspacecast_bitcast_volatile_store(i64 %X) {151; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_store(152; CHECK-NEXT: entry:153; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8154; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)155; CHECK-NEXT: store volatile i64 [[X:%.*]], ptr addrspace(1) [[TMP0]], align 8156; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 8157; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]158;159entry:160 %A = alloca [8 x i8]161 %A.cast = addrspacecast ptr %A to ptr addrspace(1)162 store volatile i64 %X, ptr addrspace(1) %A.cast163 %Z = load i64, ptr addrspace(1) %A.cast164 ret i64 %Z165}166 167%struct = type { [256 x i8], i32 }168 169define i65 @volatile_store_addrspacecast_slice(i65 %X, i16 %idx) {170; CHECK-LABEL: @volatile_store_addrspacecast_slice(171; CHECK-NEXT: entry:172; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 4173; CHECK-NEXT: [[A_SROA_1:%.*]] = alloca [9 x i8], align 8174; CHECK-NEXT: [[A_SROA_1_0_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_1]] to ptr addrspace(1)175; CHECK-NEXT: store volatile i65 [[X:%.*]], ptr addrspace(1) [[A_SROA_1_0_GEPB_SROA_CAST]], align 8176; CHECK-NEXT: br label [[L2:%.*]]177; CHECK: L2:178; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load i65, ptr [[A_SROA_0]], align 4179; CHECK-NEXT: ret i65 [[A_SROA_0_0_A_SROA_0_20_Z]]180;181entry:182 %A = alloca %struct183 %B = addrspacecast ptr %A to ptr addrspace(1)184 %gepA = getelementptr %struct, ptr %A, i32 0, i32 0, i16 20185 %gepB = getelementptr i65, ptr addrspace(1) %B, i16 6186 store volatile i65 %X, ptr addrspace(1) %gepB, align 1187 br label %L2188 189L2:190 %Z = load i65, ptr %gepA, align 1191 ret i65 %Z192}193 194; Don't change the address space of a volatile operation195define i64 @alloca_addrspacecast_bitcast_volatile_load(i64 %X) {196; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_load(197; CHECK-NEXT: entry:198; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8199; CHECK-NEXT: store i64 [[X:%.*]], ptr [[A_SROA_0]], align 8200; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)201; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load volatile i64, ptr addrspace(1) [[TMP0]], align 8202; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]203;204entry:205 %A = alloca [8 x i8]206 %A.cast = addrspacecast ptr %A to ptr addrspace(1)207 store i64 %X, ptr addrspace(1) %A.cast208 %Z = load volatile i64, ptr addrspace(1) %A.cast209 ret i64 %Z210}211 212declare void @llvm.memset.p1.i32(ptr addrspace(1) nocapture, i8, i32, i1) nounwind213 214define i65 @volatile_load_addrspacecast_slice(i65 %X, i16 %idx) {215; CHECK-LABEL: @volatile_load_addrspacecast_slice(216; CHECK-NEXT: entry:217; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 4218; CHECK-NEXT: [[A_SROA_1:%.*]] = alloca [9 x i8], align 8219; CHECK-NEXT: [[A_SROA_1_0_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_1]] to ptr addrspace(1)220; CHECK-NEXT: store i65 [[X:%.*]], ptr addrspace(1) [[A_SROA_1_0_GEPB_SROA_CAST]], align 8221; CHECK-NEXT: br label [[L2:%.*]]222; CHECK: L2:223; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load volatile i65, ptr [[A_SROA_0]], align 4224; CHECK-NEXT: ret i65 [[A_SROA_0_0_A_SROA_0_20_Z]]225;226entry:227 %A = alloca %struct228 %B = addrspacecast ptr %A to ptr addrspace(1)229 %gepA = getelementptr %struct, ptr %A, i32 0, i32 0, i16 20230 %gepB = getelementptr i65, ptr addrspace(1) %B, i16 6231 store i65 %X, ptr addrspace(1) %gepB, align 1232 br label %L2233 234L2:235 %Z = load volatile i65, ptr %gepA, align 1236 ret i65 %Z237}238 239; Don't change the address space of a volatile operation240define i32 @volatile_memset() {241; CHECK-LABEL: @volatile_memset(242; CHECK-NEXT: entry:243; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4244; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)245; CHECK-NEXT: store volatile i32 707406378, ptr addrspace(1) [[TMP0]], align 4246; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 4247; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_VAL]]248;249entry:250 %a = alloca [4 x i8]251 %asc = addrspacecast ptr %a to ptr addrspace(1)252 call void @llvm.memset.p1.i32(ptr addrspace(1) %asc, i8 42, i32 4, i1 true)253 %val = load i32, ptr %a254 ret i32 %val255}256 257; Don't change the address space of a volatile operation258define void @volatile_memcpy(ptr %src, ptr %dst) {259; CHECK-LABEL: @volatile_memcpy(260; CHECK-NEXT: entry:261; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4262; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0:![0-9]+]]263; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)264; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr addrspace(1) [[TMP0]], align 4, !tbaa [[TBAA0]]265; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)266; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr addrspace(1) [[TMP1]], align 4, !tbaa [[TBAA3:![0-9]+]]267; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]]268; CHECK-NEXT: ret void269;270entry:271 %a = alloca [4 x i8]272 %asc = addrspacecast ptr %a to ptr addrspace(1)273 call void @llvm.memcpy.p1.p0.i32(ptr addrspace(1) %asc, ptr %src, i32 4, i1 true), !tbaa !0274 call void @llvm.memcpy.p0.p1.i32(ptr %dst, ptr addrspace(1) %asc, i32 4, i1 true), !tbaa !3275 ret void276}277 278define void @select_addrspacecast(i1 %a, i1 %b) {279; CHECK-LABEL: @select_addrspacecast(280; CHECK-NEXT: ret void281;282 %c = alloca i64, align 8283 %p.0.c = select i1 %a, ptr %c, ptr %c284 %asc = addrspacecast ptr %p.0.c to ptr addrspace(1)285 286 %cond.in = select i1 %b, ptr addrspace(1) %asc, ptr addrspace(1) %asc287 %cond = load i64, ptr addrspace(1) %cond.in, align 8288 ret void289}290 291define void @select_addrspacecast_const_op(i1 %a, i1 %b) {292; CHECK-PRESERVE-CFG-LABEL: @select_addrspacecast_const_op(293; CHECK-PRESERVE-CFG-NEXT: [[C:%.*]] = alloca i64, align 8294; CHECK-PRESERVE-CFG-NEXT: [[C_0_ASC_SROA_CAST:%.*]] = addrspacecast ptr [[C]] to ptr addrspace(1)295; CHECK-PRESERVE-CFG-NEXT: [[COND_IN:%.*]] = select i1 [[B:%.*]], ptr addrspace(1) [[C_0_ASC_SROA_CAST]], ptr addrspace(1) null296; CHECK-PRESERVE-CFG-NEXT: [[COND:%.*]] = load i64, ptr addrspace(1) [[COND_IN]], align 8297; CHECK-PRESERVE-CFG-NEXT: ret void298;299; CHECK-MODIFY-CFG-LABEL: @select_addrspacecast_const_op(300; CHECK-MODIFY-CFG-NEXT: br i1 [[B:%.*]], label [[DOTCONT:%.*]], label [[DOTELSE:%.*]]301; CHECK-MODIFY-CFG: .else:302; CHECK-MODIFY-CFG-NEXT: [[COND_ELSE_VAL:%.*]] = load i64, ptr addrspace(1) null, align 8303; CHECK-MODIFY-CFG-NEXT: br label [[DOTCONT]]304; CHECK-MODIFY-CFG: .cont:305; CHECK-MODIFY-CFG-NEXT: [[COND:%.*]] = phi i64 [ undef, [[TMP0:%.*]] ], [ [[COND_ELSE_VAL]], [[DOTELSE]] ]306; CHECK-MODIFY-CFG-NEXT: ret void307;308 %c = alloca i64, align 8309 %p.0.c = select i1 %a, ptr %c, ptr %c310 %asc = addrspacecast ptr %p.0.c to ptr addrspace(1)311 312 %cond.in = select i1 %b, ptr addrspace(1) %asc, ptr addrspace(1) null313 %cond = load i64, ptr addrspace(1) %cond.in, align 8314 ret void315}316 317;; If this was external, we wouldn't be able to prove dereferenceability318;; of the location.319@gv = addrspace(1) global i64 zeroinitializer320 321define void @select_addrspacecast_gv(i1 %a, i1 %b) {322; CHECK-LABEL: @select_addrspacecast_gv(323; CHECK-NEXT: [[COND_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i64, ptr addrspace(1) @gv, align 8324; CHECK-NEXT: [[COND_SROA_SPECULATED:%.*]] = select i1 [[B:%.*]], i64 undef, i64 [[COND_SROA_SPECULATE_LOAD_FALSE]]325; CHECK-NEXT: ret void326;327 %c = alloca i64, align 8328 %p.0.c = select i1 %a, ptr %c, ptr %c329 %asc = addrspacecast ptr %p.0.c to ptr addrspace(1)330 331 %cond.in = select i1 %b, ptr addrspace(1) %asc, ptr addrspace(1) @gv332 %cond = load i64, ptr addrspace(1) %cond.in, align 8333 ret void334}335 336define void @select_addrspacecast_gv_constexpr(i1 %a, i1 %b) {337; CHECK-LABEL: @select_addrspacecast_gv_constexpr(338; CHECK-NEXT: [[COND_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i64, ptr addrspace(2) addrspacecast (ptr addrspace(1) @gv to ptr addrspace(2)), align 8339; CHECK-NEXT: [[COND_SROA_SPECULATED:%.*]] = select i1 [[B:%.*]], i64 undef, i64 [[COND_SROA_SPECULATE_LOAD_FALSE]]340; CHECK-NEXT: ret void341;342 %c = alloca i64, align 8343 %p.0.c = select i1 %a, ptr %c, ptr %c344 %asc = addrspacecast ptr %p.0.c to ptr addrspace(2)345 346 %cond.in = select i1 %b, ptr addrspace(2) %asc, ptr addrspace(2) addrspacecast (ptr addrspace(1) @gv to ptr addrspace(2))347 %cond = load i64, ptr addrspace(2) %cond.in, align 8348 ret void349}350 351define i8 @select_addrspacecast_i8(i1 %c) {352; CHECK-LABEL: @select_addrspacecast_i8(353; CHECK-NEXT: [[RET_SROA_SPECULATED:%.*]] = select i1 [[C:%.*]], i8 undef, i8 undef354; CHECK-NEXT: ret i8 [[RET_SROA_SPECULATED]]355;356 %a = alloca i8357 %b = alloca i8358 359 %a.ptr = addrspacecast ptr %a to ptr addrspace(1)360 %b.ptr = addrspacecast ptr %b to ptr addrspace(1)361 362 %ptr = select i1 %c, ptr addrspace(1) %a.ptr, ptr addrspace(1) %b.ptr363 %ret = load i8, ptr addrspace(1) %ptr364 ret i8 %ret365}366 367!0 = !{!1, !1, i64 0, i64 1}368!1 = !{!2, i64 1, !"type_0"}369!2 = !{!"root"}370!3 = !{!4, !4, i64 0, i64 1}371!4 = !{!2, i64 1, !"type_3"}372