289 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=dse -enable-dse-partial-store-merging=false < %s | FileCheck --check-prefixes=CHECK %s3target datalayout = "E-m:e-i64:64-n32:64"4target triple = "powerpc64le-unknown-linux"5 6%"struct.std::complex" = type { { float, float } }7 8define void @_Z4testSt7complexIfE(ptr noalias nocapture sret(%"struct.std::complex") %agg.result, i64 %c.coerce) {9; CHECK-LABEL: @_Z4testSt7complexIfE(10; CHECK-NEXT: entry:11; CHECK-NEXT: [[REF_TMP:%.*]] = alloca i64, align 812; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[C_COERCE:%.*]], 3213; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_SROA_0_0_EXTRACT_SHIFT]] to i3214; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[C_SROA_0_0_EXTRACT_TRUNC]] to float15; CHECK-NEXT: [[C_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_COERCE]] to i3216; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[C_SROA_2_0_EXTRACT_TRUNC]] to float17; CHECK-NEXT: call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") [[REF_TMP]], i64 [[C_COERCE]])18; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[REF_TMP]], align 819; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 3220; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i3221; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float22; CHECK-NEXT: [[_M_VALUE_IMAGP_I_I:%.*]] = getelementptr inbounds %"struct.std::complex", ptr [[AGG_RESULT:%.*]], i64 0, i32 0, i32 123; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP2]] to i3224; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32 [[TMP6]] to float25; CHECK-NEXT: [[MUL_AD_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP1]]26; CHECK-NEXT: [[MUL_BC_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP0]]27; CHECK-NEXT: [[MUL_I_I_I:%.*]] = fadd fast float [[MUL_AD_I_I]], [[MUL_BC_I_I]]28; CHECK-NEXT: [[MUL_AC_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP0]]29; CHECK-NEXT: [[MUL_BD_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP1]]30; CHECK-NEXT: [[MUL_R_I_I:%.*]] = fsub fast float [[MUL_AC_I_I]], [[MUL_BD_I_I]]31; CHECK-NEXT: store float [[MUL_R_I_I]], ptr [[AGG_RESULT]], align 432; CHECK-NEXT: store float [[MUL_I_I_I]], ptr [[_M_VALUE_IMAGP_I_I]], align 433; CHECK-NEXT: ret void34;35entry:36 37 %ref.tmp = alloca i64, align 838 %c.sroa.0.0.extract.shift = lshr i64 %c.coerce, 3239 %c.sroa.0.0.extract.trunc = trunc i64 %c.sroa.0.0.extract.shift to i3240 %0 = bitcast i32 %c.sroa.0.0.extract.trunc to float41 %c.sroa.2.0.extract.trunc = trunc i64 %c.coerce to i3242 %1 = bitcast i32 %c.sroa.2.0.extract.trunc to float43 call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") %ref.tmp, i64 %c.coerce)44 %2 = load i64, ptr %ref.tmp, align 845 store i64 %2, ptr %agg.result, align 446 47 %3 = lshr i64 %2, 3248 %4 = trunc i64 %3 to i3249 %5 = bitcast i32 %4 to float50 %_M_value.imagp.i.i = getelementptr inbounds %"struct.std::complex", ptr %agg.result, i64 0, i32 0, i32 151 %6 = trunc i64 %2 to i3252 %7 = bitcast i32 %6 to float53 %mul_ad.i.i = fmul fast float %5, %154 %mul_bc.i.i = fmul fast float %7, %055 %mul_i.i.i = fadd fast float %mul_ad.i.i, %mul_bc.i.i56 %mul_ac.i.i = fmul fast float %5, %057 %mul_bd.i.i = fmul fast float %7, %158 %mul_r.i.i = fsub fast float %mul_ac.i.i, %mul_bd.i.i59 store float %mul_r.i.i, ptr %agg.result, align 460 store float %mul_i.i.i, ptr %_M_value.imagp.i.i, align 461 ret void62}63 64declare void @_Z3barSt7complexIfE(ptr sret(%"struct.std::complex"), i64)65 66define void @test1(ptr %ptr) {67; CHECK-LABEL: @test1(68; CHECK-NEXT: entry:69; CHECK-NEXT: store i16 -30062, ptr [[PTR:%.*]], align 270; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 371; CHECK-NEXT: store i8 47, ptr [[BPTR3]], align 172; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 173; CHECK-NEXT: store i16 2020, ptr [[BPTR1]], align 174; CHECK-NEXT: ret void75;76entry:77 78 store i32 5, ptr %ptr79 store i8 7, ptr %ptr80 store i16 -30062, ptr %ptr81 %bptr2 = getelementptr inbounds i8, ptr %ptr, i64 282 store i8 25, ptr %bptr283 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 384 store i8 47, ptr %bptr385 %bptr1 = getelementptr inbounds i8, ptr %ptr, i64 186 store i16 2020, ptr %bptr1, align 187 ret void88 89 90}91 92define void @test2(ptr %ptr) {93; CHECK-LABEL: @test2(94; CHECK-NEXT: entry:95; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -196; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 197; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 298; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 399; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1100; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1101; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1102; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1103; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1104; CHECK-NEXT: ret void105;106entry:107 108 store i32 5, ptr %ptr109 110 %bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1111 %bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1112 %bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2113 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3114 115 116 store i16 1456, ptr %bptrm1, align 1117 store i16 1346, ptr %ptr, align 1118 store i16 1756, ptr %bptr1, align 1119 store i16 1126, ptr %bptr2, align 1120 store i16 5656, ptr %bptr3, align 1121 122 123 124 ret void125 126}127 128define signext i8 @test3(ptr %ptr) {129; CHECK-LABEL: @test3(130; CHECK-NEXT: entry:131; CHECK-NEXT: store i32 5, ptr [[PTR:%.*]], align 4132; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 -1133; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1134; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2135; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3136; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[PTR]], align 1137; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1138; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1139; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1140; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1141; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1142; CHECK-NEXT: ret i8 [[V]]143;144entry:145 146 store i32 5, ptr %ptr147 148 %bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1149 %bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1150 %bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2151 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3152 153 154 %v = load i8, ptr %ptr, align 1155 store i16 1456, ptr %bptrm1, align 1156 store i16 1346, ptr %ptr, align 1157 store i16 1756, ptr %bptr1, align 1158 store i16 1126, ptr %bptr2, align 1159 store i16 5656, ptr %bptr3, align 1160 161 162 ret i8 %v163 164}165 166%struct.foostruct = type {167ptr,168ptr,169ptr,170ptr,171ptr172}173declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)174declare void @goFunc(ptr)175declare i32 @fa(ptr, ptr, i32, i8, ptr)176 177; We miss this case, because of an aggressive limit of partial overlap analysis.178; With a larger partial store limit, we remove the memset.179define void @test4() {180; CHECK-LABEL: @test4(181; CHECK-NEXT: entry:182; CHECK-NEXT: [[BANG:%.*]] = alloca [[STRUCT_FOOSTRUCT:%.*]], align 8183; CHECK-NEXT: store ptr @fa, ptr [[BANG]], align 8184; CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 1185; CHECK-NEXT: store ptr @fa, ptr [[V3]], align 8186; CHECK-NEXT: [[V4:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 2187; CHECK-NEXT: store ptr @fa, ptr [[V4]], align 8188; CHECK-NEXT: [[V5:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 3189; CHECK-NEXT: store ptr @fa, ptr [[V5]], align 8190; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 4191; CHECK-NEXT: store ptr null, ptr [[V6]], align 8192; CHECK-NEXT: call void @goFunc(ptr [[BANG]])193; CHECK-NEXT: ret void194entry:195 196 %bang = alloca %struct.foostruct, align 8197 call void @llvm.memset.p0.i64(ptr align 8 %bang, i8 0, i64 40, i1 false)198 store ptr @fa, ptr %bang, align 8199 %v3 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 1200 store ptr @fa, ptr %v3, align 8201 %v4 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 2202 store ptr @fa, ptr %v4, align 8203 %v5 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 3204 store ptr @fa, ptr %v5, align 8205 %v6 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 4206 store ptr null, ptr %v6, align 8207 call void @goFunc(ptr %bang)208 ret void209 210}211 212define signext i8 @test5(ptr %ptr) {213; CHECK-LABEL: @test5(214; CHECK-NEXT: entry:215; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 1216; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2217; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3218; CHECK-NEXT: store i16 -1, ptr [[BPTR2]], align 1219; CHECK-NEXT: store i16 1456, ptr [[BPTR1]], align 1220; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1221; CHECK-NEXT: ret i8 0222;223entry:224 225 store i32 0, ptr %ptr226 227 %bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1228 %bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2229 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3230 231 232 store i16 65535, ptr %bptr2, align 1233 store i16 1456, ptr %bptr1, align 1234 store i16 1346, ptr %ptr, align 1235 236 237 ret i8 0238}239 240define signext i8 @test6(ptr %ptr) {241; CHECK-LABEL: @test6(242; CHECK-NEXT: entry:243; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1244; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1245; CHECK-NEXT: store i16 -1, ptr [[PTR]], align 1246; CHECK-NEXT: ret i8 0247;248entry:249 250 store i32 0, ptr %ptr251 252 %bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1253 254 store i16 1456, ptr %bptr2, align 1255 store i16 65535, ptr %ptr, align 1256 257 258 ret i8 0259}260 261define signext i8 @test7(ptr %ptr) {262; CHECK-LABEL: @test7(263; CHECK-NEXT: entry:264; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1265; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 2266; CHECK-NEXT: [[BPTR4:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 3267; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1268; CHECK-NEXT: store i16 1756, ptr [[BPTR3]], align 1269; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1270; CHECK-NEXT: store i16 5656, ptr [[BPTR4]], align 1271; CHECK-NEXT: ret i8 0272;273entry:274 275 store i64 0, ptr %ptr276 277 %bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1278 %bptr3 = getelementptr inbounds i16, ptr %ptr, i64 2279 %bptr4 = getelementptr inbounds i16, ptr %ptr, i64 3280 281 store i16 1346, ptr %ptr, align 1282 store i16 1756, ptr %bptr3, align 1283 store i16 1456, ptr %bptr2, align 1284 store i16 5656, ptr %bptr4, align 1285 286 287 ret i8 0288}289