523 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5%struct.T = type { i32, [10 x [20 x i8]] }6 7declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"8 9define i8 @select_offsets_simplifiable_1(i1 %cnd1, i1 %cnd2) {10; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_111; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {12; CHECK-NEXT: entry:13; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)14; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2315; CHECK-NEXT: store i8 23, ptr [[GEP23]], align 416; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2917; CHECK-NEXT: store i8 29, ptr [[GEP29]], align 418; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 719; CHECK-NEXT: store i8 7, ptr [[GEP7]], align 420; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3121; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 2922; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 723; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]24; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_SEL]], align 425; CHECK-NEXT: ret i8 [[I]]26;27entry:28 %Bytes = call ptr @calloc(i64 1024, i64 1)29 30 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 2331 store i8 23, ptr %gep23, align 432 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 2933 store i8 29, ptr %gep29, align 434 %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 735 store i8 7, ptr %gep7, align 436 37 ;; This store is redundant, hence removed.38 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 3139 store i8 42, ptr %gep31, align 440 41 %sel0 = select i1 %cnd1, i64 23, i64 2942 %sel1 = select i1 %cnd2, i64 %sel0, i64 743 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel144 %i = load i8, ptr %gep.sel, align 445 ret i8 %i46}47 48define i8 @select_offsets_simplifiable_2(i1 %cnd1, i1 %cnd2) {49; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)50; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_251; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1:[0-9]+]] {52; CHECK-NEXT: entry:53; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 1654; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2355; CHECK-NEXT: store i8 23, ptr [[GEP23]], align 456; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2957; CHECK-NEXT: store i8 29, ptr [[GEP29]], align 458; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 759; CHECK-NEXT: store i8 7, ptr [[GEP7]], align 460; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3161; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 20, i64 2662; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 463; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]64; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 365; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 466; CHECK-NEXT: ret i8 [[I]]67;68entry:69 %Bytes = alloca [1024 x i8], align 1670 71 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 2372 store i8 23, ptr %gep23, align 473 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 2974 store i8 29, ptr %gep29, align 475 %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 776 store i8 7, ptr %gep7, align 477 78 ;; This store is redundant, hence removed.79 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 3180 store i8 42, ptr %gep31, align 481 82 ;; Adjust the offsets so that they match the stores after adding 383 %sel0 = select i1 %cnd1, i64 20, i64 2684 %sel1 = select i1 %cnd2, i64 %sel0, i64 485 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel186 %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 387 %i = load i8, ptr %gep.plus, align 488 ret i8 %i89}90 91define i8 @select_offsets_simplifiable_3(i1 %cnd1, i1 %cnd2) {92; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)93; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_394; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {95; CHECK-NEXT: entry:96; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 6497; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 398; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 1199; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]100; CHECK-NEXT: ret i8 100101;102entry:103 %bundle = alloca %struct.T, align 64104 %gep.fixed = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 1, i64 1105 store i8 100, ptr %gep.fixed, align 4106 %sel1 = select i1 %cnd1, i64 1, i64 3107 %sel2 = select i1 %cnd2, i64 5, i64 11108 %gep.sel = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 %sel1, i64 %sel2109 store i8 42, ptr %gep.sel, align 4110 %i = load i8, ptr %gep.fixed, align 4111 ret i8 %i112}113 114; Similar to select_offsets_not_simplifiable_3 but with uninitialized memory.115define i8 @select_offsets_simplifiable_4(i1 %cnd1, i1 %cnd2) {116; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)117; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_4118; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {119; CHECK-NEXT: entry:120; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16121; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29122; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7123; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]124; CHECK-NEXT: ret i8 100125;126entry:127 %Bytes = alloca [1024 x i8], align 16128 %sel0 = select i1 %cnd1, i64 23, i64 29129 %sel1 = select i1 %cnd2, i64 %sel0, i64 7130 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1131 store i8 100, ptr %gep.sel, align 4132 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29133 %i = load i8, ptr %gep29, align 4134 ret i8 %i135}136 137define i8 @select_offsets_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {138; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)139; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1140; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {141; CHECK-NEXT: entry:142; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16143; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29144; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7145; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23146; CHECK-NEXT: store i8 100, ptr [[GEP23]], align 4147; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]148; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_SEL]], align 4149; CHECK-NEXT: ret i8 [[I]]150;151entry:152 %Bytes = alloca [1024 x i8], align 16153 %sel0 = select i1 %cnd1, i64 23, i64 29154 %sel1 = select i1 %cnd2, i64 %sel0, i64 7155 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23156 store i8 100, ptr %gep23, align 4157 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1158 %i = load i8, ptr %gep.sel, align 4159 ret i8 %i160}161 162define i8 @select_offsets_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {163; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)164; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_2165; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {166; CHECK-NEXT: entry:167; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16168; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29169; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7170; CHECK-NEXT: [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32171; CHECK-NEXT: store i8 100, ptr [[GEP32]], align 16172; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]173; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3174; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 4175; CHECK-NEXT: ret i8 [[I]]176;177entry:178 %Bytes = alloca [1024 x i8], align 16179 %sel0 = select i1 %cnd1, i64 23, i64 29180 %sel1 = select i1 %cnd2, i64 %sel0, i64 7181 %gep32 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 32182 store i8 100, ptr %gep32, align 4183 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1184 %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 3185 %i = load i8, ptr %gep.plus, align 4186 ret i8 %i187}188 189define i8 @select_offsets_not_simplifiable_3(i1 %cnd1, i1 %cnd2) {190; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_3191; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {192; CHECK-NEXT: entry:193; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)194; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29195; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7196; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]197; CHECK-NEXT: store i8 100, ptr [[GEP_SEL]], align 4198; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29199; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP29]], align 4200; CHECK-NEXT: ret i8 [[I]]201;202entry:203 %Bytes = call ptr @calloc(i64 1024, i64 1)204 %sel0 = select i1 %cnd1, i64 23, i64 29205 %sel1 = select i1 %cnd2, i64 %sel0, i64 7206 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1207 store i8 100, ptr %gep.sel, align 4208 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29209 %i = load i8, ptr %gep29, align 4210 ret i8 %i211}212 213define i8 @select_offsets_not_simplifiable_4(i1 %cnd1, i1 %cnd2) {214; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_4215; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {216; CHECK-NEXT: entry:217; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)218; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29219; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7220; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]221; CHECK-NEXT: [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3222; CHECK-NEXT: store i8 100, ptr [[GEP_PLUS]], align 4223; CHECK-NEXT: [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32224; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP32]], align 4225; CHECK-NEXT: ret i8 [[I]]226;227entry:228 %Bytes = call ptr @calloc(i64 1024, i64 1)229 %sel0 = select i1 %cnd1, i64 23, i64 29230 %sel1 = select i1 %cnd2, i64 %sel0, i64 7231 %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1232 %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 3233 store i8 100, ptr %gep.plus, align 4234 %gep32 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 32235 %i = load i8, ptr %gep32, align 4236 ret i8 %i237}238 239define i8 @select_offsets_not_simplifiable_5(i1 %cnd1, i1 %cnd2) {240; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)241; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5242; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {243; CHECK-NEXT: entry:244; CHECK-NEXT: [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64245; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 3, i64 5246; CHECK-NEXT: store i8 100, ptr [[GEP_FIXED]], align 4247; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3248; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11249; CHECK-NEXT: [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]250; CHECK-NEXT: store i8 42, ptr [[GEP_SEL]], align 4251; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP_FIXED]], align 4252; CHECK-NEXT: ret i8 [[I]]253;254entry:255 %bundle = alloca %struct.T, align 64256 %gep.fixed = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 3, i64 5257 store i8 100, ptr %gep.fixed, align 4258 %sel1 = select i1 %cnd1, i64 1, i64 3259 %sel2 = select i1 %cnd2, i64 5, i64 11260 %gep.sel = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 %sel1, i64 %sel2261 262 ;; This store prevents the constant 100 from being propagated to ret263 store i8 42, ptr %gep.sel, align 4264 265 %i = load i8, ptr %gep.fixed, align 4266 ret i8 %i267}268 269define i8 @select_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {270; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)271; CHECK-LABEL: define {{[^@]+}}@select_gep_simplifiable_1272; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {273; CHECK-NEXT: entry:274; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16275; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7276; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23277; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]278; CHECK-NEXT: ret i8 21279;280entry:281 %Bytes = alloca [1024 x i8], align 16282 %gep3 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 3283 store i8 21, ptr %gep3, align 4284 %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7285 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23286 %sel.ptr = select i1 %cnd1, ptr %gep7, ptr %gep23287 store i8 42, ptr %sel.ptr, align 4288 %i = load i8, ptr %gep3, align 4289 ret i8 %i290}291 292define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {293; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)294; CHECK-LABEL: define {{[^@]+}}@select_gep_not_simplifiable_1295; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {296; CHECK-NEXT: entry:297; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16298; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7299; CHECK-NEXT: store i8 1, ptr [[GEP7]], align 4300; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23301; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]302; CHECK-NEXT: store i8 42, ptr [[SEL_PTR]], align 4303; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP7]], align 4304; CHECK-NEXT: ret i8 [[I]]305;306entry:307 %Bytes = alloca [1024 x i8], align 16308 %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7309 store i8 1, ptr %gep7, align 4310 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23311 %sel.ptr = select i1 %cnd1, ptr %gep7, ptr %gep23312 store i8 42, ptr %sel.ptr, align 4313 %i = load i8, ptr %gep7, align 4314 ret i8 %i315}316 317; FIXME: The whole function is just "ret i8 21".318 319define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {320; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)321; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1322; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {323; CHECK-NEXT: entry:324; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16325; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]326; CHECK: then:327; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23328; CHECK-NEXT: store i8 21, ptr [[GEP23]], align 4329; CHECK-NEXT: br label [[JOIN:%.*]]330; CHECK: else:331; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31332; CHECK-NEXT: store i8 21, ptr [[GEP31]], align 4333; CHECK-NEXT: br label [[JOIN]]334; CHECK: join:335; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]336; CHECK-NEXT: [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29337; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4338; CHECK-NEXT: ret i8 [[I]]339;340entry:341 %Bytes = alloca [1024 x i8], align 16342 br i1 %cnd1, label %then, label %else343 344then:345 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23346 store i8 21, ptr %gep23, align 4347 br label %join348 349else:350 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31351 store i8 21, ptr %gep31, align 4352 br label %join353 354join:355 %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]356 ;; This store is eliminated357 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29358 store i8 42, ptr %gep29, align 4359 %i = load i8, ptr %phi.ptr, align 4360 ret i8 %i361}362 363; FIXME: The whole function is just "ret i8 42".364 365define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {366; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)367; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2368; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {369; CHECK-NEXT: entry:370; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16371; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]372; CHECK: then:373; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23374; CHECK-NEXT: br label [[JOIN:%.*]]375; CHECK: else:376; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31377; CHECK-NEXT: br label [[JOIN]]378; CHECK: join:379; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]380; CHECK-NEXT: ret i8 42381;382entry:383 %Bytes = alloca [1024 x i8], align 16384 %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29385 ;; This store is propagated to the load.386 store i8 42, ptr %gep29, align 4387 br i1 %cnd1, label %then, label %else388 389then:390 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23391 br label %join392 393else:394 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31395 br label %join396 397join:398 %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]399 store i8 21, ptr %phi.ptr, align 4400 ;; Replaced with the constant, and both store/load are eliminated.401 %i = load i8, ptr %gep29, align 4402 ret i8 %i403}404 405define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {406; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)407; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1408; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {409; CHECK-NEXT: entry:410; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16411; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23412; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]413; CHECK: then:414; CHECK-NEXT: br label [[JOIN:%.*]]415; CHECK: else:416; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31417; CHECK-NEXT: br label [[JOIN]]418; CHECK: join:419; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]420; CHECK-NEXT: store i8 42, ptr [[GEP23]], align 4421; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4422; CHECK-NEXT: ret i8 [[I]]423;424entry:425 %Bytes = alloca [1024 x i8], align 16426 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23427 br i1 %cnd1, label %then, label %else428 429then:430 br label %join431 432else:433 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31434 br label %join435 436join:437 %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]438 ;; This store cannot be eliminated439 store i8 42, ptr %gep23, align 4440 %i = load i8, ptr %phi.ptr, align 4441 ret i8 %i442}443 444define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {445; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_2446; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {447; CHECK-NEXT: entry:448; CHECK-NEXT: [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)449; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23450; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]451; CHECK: then:452; CHECK-NEXT: br label [[JOIN:%.*]]453; CHECK: else:454; CHECK-NEXT: [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31455; CHECK-NEXT: br label [[JOIN]]456; CHECK: join:457; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]458; CHECK-NEXT: store i8 21, ptr [[PHI_PTR]], align 4459; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[GEP23]], align 4460; CHECK-NEXT: ret i8 [[I]]461;462entry:463 %Bytes = call ptr @calloc(i64 1024, i64 1)464 %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23465 br i1 %cnd1, label %then, label %else466 467then:468 br label %join469 470else:471 %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31472 br label %join473 474join:475 %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]476 store i8 21, ptr %phi.ptr, align 4477 %i = load i8, ptr %gep23, align 4478 ret i8 %i479}480 481define i8 @phi_offsets(i1 %cnd1, i1 %cnd2) {482; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)483; CHECK-LABEL: define {{[^@]+}}@phi_offsets484; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {485; CHECK-NEXT: entry:486; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16487; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]488; CHECK: then:489; CHECK-NEXT: br label [[JOIN:%.*]]490; CHECK: else:491; CHECK-NEXT: br label [[JOIN]]492; CHECK: join:493; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 3, [[THEN]] ], [ 11, [[ELSE]] ]494; CHECK-NEXT: [[GEP_PHI:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[PHI]]495; CHECK-NEXT: ret i8 100496;497entry:498 %Bytes = alloca [1024 x i8], align 16499 store i8 100, ptr %Bytes, align 4500 br i1 %cnd1, label %then, label %else501 502then:503 br label %join504 505else:506 br label %join507 508join:509 %phi = phi i64 [ 3, %then ], [ 11, %else ]510 %gep.phi = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %phi511 store i8 42, ptr %gep.phi, align 4512 %i = load i8, ptr %Bytes, align 4513 ret i8 %i514}515 516;.517; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }518; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }519;.520;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:521; CGSCC: {{.*}}522; TUNIT: {{.*}}523