brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.1 KiB · b6c7e4c Raw
524 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 22; 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.Foo = type { i32, i32, i8 }6 7@.str = private unnamed_addr constant [17 x i8] c"The value is %d\0A\00", align 18 9;.10; CHECK: @.str = private unnamed_addr constant [17 x i8] c"The value is %d\0A\00", align 111;.12define dso_local void @positive_alloca_1(i32 noundef %val) #0 {13; CHECK-LABEL: define dso_local void @positive_alloca_114; CHECK-SAME: (i32 noundef [[VAL:%.*]]) {15; CHECK-NEXT:  entry:16; CHECK-NEXT:    [[VAL_ADDR1:%.*]] = alloca i8, i32 4, align 417; CHECK-NEXT:    [[F2:%.*]] = alloca i8, i32 4, align 418; CHECK-NEXT:    store i32 [[VAL]], ptr [[VAL_ADDR1]], align 419; CHECK-NEXT:    store i32 10, ptr [[F2]], align 420; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[F2]], align 421; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP0]], 122; CHECK-NEXT:    store i32 [[ADD]], ptr [[F2]], align 423; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[F2]], align 424; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 [[TMP1]], [[VAL]]25; CHECK-NEXT:    [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[ADD3]])26; CHECK-NEXT:    ret void27;28entry:29  %val.addr = alloca i64, align 430  %f = alloca %struct.Foo, align 431  store i32 %val, ptr %val.addr, align 432  %field1 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 033  store i32 10, ptr %field1, align 434  %field11 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 035  %0 = load i32, ptr %field11, align 436  %add = add nsw i32 %0, 137  store i32 %add, ptr %field11, align 438  %field12 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 039  %1 = load i32, ptr %field12, align 440  %2 = load i32, ptr %val.addr, align 441  %add3 = add nsw i32 %1, %242  %call = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %add3)43  ret void44}45 46; TODO: change malloc like call47; Function Attrs: noinline nounwind uwtable48define dso_local void @positive_malloc_1(ptr noundef %val) #0 {49; CHECK-LABEL: define dso_local void @positive_malloc_150; CHECK-SAME: (ptr nofree noundef readonly captures(none) [[VAL:%.*]]) {51; CHECK-NEXT:  entry:52; CHECK-NEXT:    [[VAL_ADDR:%.*]] = alloca ptr, align 853; CHECK-NEXT:    [[F:%.*]] = alloca ptr, align 854; CHECK-NEXT:    store ptr [[VAL]], ptr [[VAL_ADDR]], align 855; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 12)56; CHECK-NEXT:    store ptr [[CALL]], ptr [[F]], align 857; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[VAL]], align 458; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP0]], 1059; CHECK-NEXT:    store i32 [[ADD]], ptr [[CALL]], align 460; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 461; CHECK-NEXT:    [[CALL2:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP1]])62; CHECK-NEXT:    ret void63;64entry:65  %val.addr = alloca ptr, align 866  %f = alloca ptr, align 867  store ptr %val, ptr %val.addr, align 868  %call = call noalias ptr @malloc(i64 noundef 12) #369  store ptr %call, ptr %f, align 870  %0 = load ptr, ptr %val.addr, align 871  %1 = load i32, ptr %0, align 472  %add = add nsw i32 %1, 1073  %2 = load ptr, ptr %f, align 874  %a = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 075  store i32 %add, ptr %a, align 476  %3 = load ptr, ptr %f, align 877  %a1 = getelementptr inbounds %struct.Foo, ptr %3, i32 0, i32 078  %4 = load i32, ptr %a1, align 479  %call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %4)80  ret void81}82 83; TODO: change malloc like call84; Function Attrs: noinline nounwind uwtable85define dso_local void @positive_malloc_2(ptr noundef %val) #0 {86; CHECK-LABEL: define dso_local void @positive_malloc_287; CHECK-SAME: (ptr nofree noundef readonly captures(none) [[VAL:%.*]]) {88; CHECK-NEXT:  entry:89; CHECK-NEXT:    [[VAL_ADDR:%.*]] = alloca ptr, align 890; CHECK-NEXT:    [[F:%.*]] = alloca ptr, align 891; CHECK-NEXT:    store ptr [[VAL]], ptr [[VAL_ADDR]], align 892; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 60)93; CHECK-NEXT:    store ptr [[CALL]], ptr [[F]], align 894; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[VAL]], align 495; CHECK-NEXT:    store i32 [[TMP0]], ptr [[CALL]], align 496; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 497; CHECK-NEXT:    [[CALL2:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP1]])98; CHECK-NEXT:    ret void99;100entry:101  %val.addr = alloca ptr, align 8102  %x = alloca i32, align 4103  %f = alloca ptr, align 8104  store ptr %val, ptr %val.addr, align 8105  store i32 15, ptr %x, align 4106  %0 = load i32, ptr %x, align 4107  %conv = sext i32 %0 to i64108  %mul = mul i64 4, %conv109  %call = call noalias ptr @malloc(i64 noundef %mul)110  store ptr %call, ptr %f, align 8111  %1 = load ptr, ptr %val.addr, align 8112  %2 = load i32, ptr %1, align 4113  %3 = load ptr, ptr %f, align 8114  %arrayidx = getelementptr inbounds i32, ptr %3, i64 0115  store i32 %2, ptr %arrayidx, align 4116  %4 = load ptr, ptr %f, align 8117  %arrayidx1 = getelementptr inbounds i32, ptr %4, i64 0118  %5 = load i32, ptr %arrayidx1, align 4119  %call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %5)120  ret void121}122 123; Function Attrs: noinline nounwind uwtable124define dso_local ptr @negative_test_escaping_pointer(i32 noundef %val) #0 {125; CHECK-LABEL: define dso_local ptr @negative_test_escaping_pointer126; CHECK-SAME: (i32 noundef [[VAL:%.*]]) {127; CHECK-NEXT:  entry:128; CHECK-NEXT:    [[VAL_ADDR:%.*]] = alloca i32, align 4129; CHECK-NEXT:    [[F:%.*]] = alloca ptr, align 8130; CHECK-NEXT:    store i32 [[VAL]], ptr [[VAL_ADDR]], align 4131; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 16)132; CHECK-NEXT:    store ptr [[CALL]], ptr [[F]], align 8133; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[F]], align 8134; CHECK-NEXT:    store i32 2, ptr [[TMP0]], align 8135; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 10, [[VAL]]136; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[F]], align 8137; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 8138; CHECK-NEXT:    [[ADD2:%.*]] = add nsw i32 [[TMP2]], [[ADD]]139; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP1]], align 8140; CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[F]], align 8141; CHECK-NEXT:    ret ptr [[TMP3]]142;143entry:144  %val.addr = alloca i32, align 4145  %f = alloca ptr, align 8146  store i32 %val, ptr %val.addr, align 4147  %call = call noalias ptr @malloc(i64 noundef 16) #2148  store ptr %call, ptr %f, align 8149  %0 = load ptr, ptr %f, align 8150  %field1 = getelementptr inbounds %struct.Foo, ptr %0, i32 0, i32 0151  store i32 2, ptr %field1, align 8152  %1 = load i32, ptr %val.addr, align 4153  %add = add nsw i32 10, %1154  %2 = load ptr, ptr %f, align 8155  %field11 = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 0156  %3 = load i32, ptr %field11, align 8157  %add2 = add nsw i32 %3, %add158  store i32 %add2, ptr %field11, align 8159  %4 = load ptr, ptr %f, align 8160  ret ptr %4161}162 163 164;TODO: The allocation can be reduced here.165;However, the offsets (load/store etc.) Need to be changed.166; Function Attrs: noinline nounwind uwtable167define dso_local { i64, ptr } @positive_test_not_a_single_start_offset(i32 noundef %val) #0 {168; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)169; CHECK-LABEL: define dso_local { i64, ptr } @positive_test_not_a_single_start_offset170; CHECK-SAME: (i32 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {171; CHECK-NEXT:  entry:172; CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8173; CHECK-NEXT:    [[VAL_ADDR:%.*]] = alloca i32, align 4174; CHECK-NEXT:    store i32 [[VAL]], ptr [[VAL_ADDR]], align 4175; CHECK-NEXT:    store i32 2, ptr [[RETVAL]], align 8176; CHECK-NEXT:    [[FIELD3:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[RETVAL]], i32 0, i32 2177; CHECK-NEXT:    store ptr [[VAL_ADDR]], ptr [[FIELD3]], align 8178; CHECK-NEXT:    [[TMP0:%.*]] = load { i64, ptr }, ptr [[RETVAL]], align 8179; CHECK-NEXT:    ret { i64, ptr } [[TMP0]]180;181entry:182  %retval = alloca %struct.Foo, align 8183  %val.addr = alloca i32, align 4184  store i32 %val, ptr %val.addr, align 4185  %field1 = getelementptr inbounds %struct.Foo, ptr %retval, i32 0, i32 0186  store i32 2, ptr %field1, align 8187  %field3 = getelementptr inbounds %struct.Foo, ptr %retval, i32 0, i32 2188  store ptr %val.addr, ptr %field3, align 8189  %0 = load { i64, ptr }, ptr %retval, align 8190  ret { i64, ptr } %0191}192 193; Function Attrs: noinline nounwind uwtable194define dso_local void @positive_test_reduce_array_allocation_1() {195; CHECK-LABEL: define dso_local void @positive_test_reduce_array_allocation_1() {196; CHECK-NEXT:  entry:197; CHECK-NEXT:    [[ARRAY1:%.*]] = alloca i8, i32 4, align 8198; CHECK-NEXT:    store i32 0, ptr [[ARRAY1]], align 8199; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAY1]], align 8200; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], 2201; CHECK-NEXT:    store i32 [[TMP1]], ptr [[ARRAY1]], align 8202; CHECK-NEXT:    [[TMP2:%.*]] = add i32 1, 2203; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAY1]], align 8204; CHECK-NEXT:    [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]205; CHECK-NEXT:    store i32 [[TMP4]], ptr [[ARRAY1]], align 8206; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAY1]], align 8207; CHECK-NEXT:    [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP5]])208; CHECK-NEXT:    ret void209;210entry:211  %array = alloca ptr, i32 10212  store i32 0, ptr %array213  %0 = load i32, ptr %array214  %1 = add i32 %0, 2215  store i32 %1, ptr %array216  %2 = add i32 1, 2217  %3 = load i32, ptr %array218  %4 = add i32 %2, %3219  store i32 %4, ptr %array220  %5 = load i32, ptr %array221  %call = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %5)222  ret void223}224 225 226; Function Attrs: noinline nounwind uwtable227; TODO: Here the array size is not known at compile time.228; However the array does not escape and is only partially used.229; Should the optimization reduce the allocation size regardless? Based on AAPointerInfo.230define dso_local void @baz(ptr noundef %val, i32 noundef %arrayLength) #0 {231; CHECK-LABEL: define dso_local void @baz232; CHECK-SAME: (ptr nofree noundef readonly captures(none) [[VAL:%.*]], i32 noundef [[ARRAYLENGTH:%.*]]) {233; CHECK-NEXT:  entry:234; CHECK-NEXT:    [[VAL_ADDR:%.*]] = alloca ptr, align 8235; CHECK-NEXT:    [[ARRAYLENGTH_ADDR:%.*]] = alloca i32, align 4236; CHECK-NEXT:    [[F:%.*]] = alloca ptr, align 8237; CHECK-NEXT:    store ptr [[VAL]], ptr [[VAL_ADDR]], align 8238; CHECK-NEXT:    store i32 [[ARRAYLENGTH]], ptr [[ARRAYLENGTH_ADDR]], align 4239; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARRAYLENGTH]] to i64240; CHECK-NEXT:    [[MUL:%.*]] = mul i64 4, [[CONV]]241; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef [[MUL]])242; CHECK-NEXT:    store ptr [[CALL]], ptr [[F]], align 8243; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[VAL]], align 4244; CHECK-NEXT:    store i32 [[TMP0]], ptr [[CALL]], align 4245; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[CALL]], align 4246; CHECK-NEXT:    [[CALL2:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP1]])247; CHECK-NEXT:    ret void248;249entry:250  %val.addr = alloca ptr, align 8251  %arrayLength.addr = alloca i32, align 4252  %f = alloca ptr, align 8253  store ptr %val, ptr %val.addr, align 8254  store i32 %arrayLength, ptr %arrayLength.addr, align 4255  %0 = load i32, ptr %arrayLength.addr, align 4256  %conv = sext i32 %0 to i64257  %mul = mul i64 4, %conv258  %call = call noalias ptr @malloc(i64 noundef %mul) #3259  store ptr %call, ptr %f, align 8260  %1 = load ptr, ptr %val.addr, align 8261  %2 = load i32, ptr %1, align 4262  %3 = load ptr, ptr %f, align 8263  %arrayidx = getelementptr inbounds i32, ptr %3, i64 0264  store i32 %2, ptr %arrayidx, align 4265  %4 = load ptr, ptr %f, align 8266  %arrayidx1 = getelementptr inbounds i32, ptr %4, i64 0267  %5 = load i32, ptr %arrayidx1, align 4268  %call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %5)269  ret void270}271 272;TODO: Here since only even indexes of the array are part of the output273;We can reduce the allocation by half and make an array that's accessed contiguously274; Function Attrs: noinline nounwind uwtable275define dso_local void @positive_test_reduce_array_allocation_2() #0 {276; CHECK-LABEL: define dso_local void @positive_test_reduce_array_allocation_2() {277; CHECK-NEXT:  entry:278; CHECK-NEXT:    [[ARRAY:%.*]] = alloca ptr, align 8279; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4280; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 noundef 40000)281; CHECK-NEXT:    store ptr [[CALL]], ptr [[ARRAY]], align 8282; CHECK-NEXT:    store i32 0, ptr [[I]], align 4283; CHECK-NEXT:    br label [[FOR_COND:%.*]]284; CHECK:       for.cond:285; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4286; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 10000287; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]288; CHECK:       for.body:289; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[I]], align 4290; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[I]], align 4291; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP2]] to i64292; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM]]293; CHECK-NEXT:    store i32 [[TMP1]], ptr [[ARRAYIDX]], align 4294; CHECK-NEXT:    br label [[FOR_INC:%.*]]295; CHECK:       for.inc:296; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[I]], align 4297; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], 2298; CHECK-NEXT:    store i32 [[ADD]], ptr [[I]], align 4299; CHECK-NEXT:    br label [[FOR_COND]]300; CHECK:       for.end:301; CHECK-NEXT:    store i32 0, ptr [[I]], align 4302; CHECK-NEXT:    br label [[FOR_COND1:%.*]]303; CHECK:       for.cond1:304; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I]], align 4305; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP4]], 10000306; CHECK-NEXT:    br i1 [[CMP2]], label [[FOR_BODY3:%.*]], label [[FOR_END9:%.*]]307; CHECK:       for.body3:308; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I]], align 4309; CHECK-NEXT:    [[IDXPROM4:%.*]] = sext i32 [[TMP5]] to i64310; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM4]]311; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4312; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP6]], 1313; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX5]], align 4314; CHECK-NEXT:    br label [[FOR_INC7:%.*]]315; CHECK:       for.inc7:316; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[I]], align 4317; CHECK-NEXT:    [[ADD8:%.*]] = add nsw i32 [[TMP7]], 2318; CHECK-NEXT:    store i32 [[ADD8]], ptr [[I]], align 4319; CHECK-NEXT:    br label [[FOR_COND1]]320; CHECK:       for.end9:321; CHECK-NEXT:    store i32 0, ptr [[I]], align 4322; CHECK-NEXT:    br label [[FOR_COND10:%.*]]323; CHECK:       for.cond10:324; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[I]], align 4325; CHECK-NEXT:    [[CMP11:%.*]] = icmp slt i32 [[TMP8]], 10000326; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY12:%.*]], label [[FOR_END18:%.*]]327; CHECK:       for.body12:328; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[I]], align 4329; CHECK-NEXT:    [[IDXPROM13:%.*]] = sext i32 [[TMP9]] to i64330; CHECK-NEXT:    [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 [[IDXPROM13]]331; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX14]], align 4332; CHECK-NEXT:    [[CALL15:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP10]])333; CHECK-NEXT:    br label [[FOR_INC16:%.*]]334; CHECK:       for.inc16:335; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[I]], align 4336; CHECK-NEXT:    [[ADD17:%.*]] = add nsw i32 [[TMP11]], 2337; CHECK-NEXT:    store i32 [[ADD17]], ptr [[I]], align 4338; CHECK-NEXT:    br label [[FOR_COND10]]339; CHECK:       for.end18:340; CHECK-NEXT:    ret void341;342entry:343  %array = alloca ptr, align 8344  %i = alloca i32, align 4345  %call = call noalias ptr @malloc(i64 noundef 40000) #3346  store ptr %call, ptr %array, align 8347  store i32 0, ptr %i, align 4348  br label %for.cond349 350for.cond:351  %0 = load i32, ptr %i, align 4352  %cmp = icmp slt i32 %0, 10000353  br i1 %cmp, label %for.body, label %for.end354 355for.body:356  %1 = load i32, ptr %i, align 4357  %2 = load ptr, ptr %array, align 8358  %3 = load i32, ptr %i, align 4359  %idxprom = sext i32 %3 to i64360  %arrayidx = getelementptr inbounds i32, ptr %2, i64 %idxprom361  store i32 %1, ptr %arrayidx, align 4362  br label %for.inc363 364for.inc:365  %4 = load i32, ptr %i, align 4366  %add = add nsw i32 %4, 2367  store i32 %add, ptr %i, align 4368  br label %for.cond369 370for.end:371  store i32 0, ptr %i, align 4372  br label %for.cond1373 374for.cond1:375  %5 = load i32, ptr %i, align 4376  %cmp2 = icmp slt i32 %5, 10000377  br i1 %cmp2, label %for.body3, label %for.end9378 379for.body3:380  %6 = load ptr, ptr %array, align 8381  %7 = load i32, ptr %i, align 4382  %idxprom4 = sext i32 %7 to i64383  %arrayidx5 = getelementptr inbounds i32, ptr %6, i64 %idxprom4384  %8 = load i32, ptr %arrayidx5, align 4385  %add6 = add nsw i32 %8, 1386  store i32 %add6, ptr %arrayidx5, align 4387  br label %for.inc7388 389for.inc7:390  %9 = load i32, ptr %i, align 4391  %add8 = add nsw i32 %9, 2392  store i32 %add8, ptr %i, align 4393  br label %for.cond1394 395for.end9:396  store i32 0, ptr %i, align 4397  br label %for.cond10398 399for.cond10:400  %10 = load i32, ptr %i, align 4401  %cmp11 = icmp slt i32 %10, 10000402  br i1 %cmp11, label %for.body12, label %for.end18403 404for.body12:405  %11 = load ptr, ptr %array, align 8406  %12 = load i32, ptr %i, align 4407  %idxprom13 = sext i32 %12 to i64408  %arrayidx14 = getelementptr inbounds i32, ptr %11, i64 %idxprom13409  %13 = load i32, ptr %arrayidx14, align 4410  %call15 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %13)411  br label %for.inc16412 413for.inc16:414  %14 = load i32, ptr %i, align 4415  %add17 = add nsw i32 %14, 2416  store i32 %add17, ptr %i, align 4417  br label %for.cond10418 419for.end18:420  ret void421}422 423 424define dso_local void @pthread_test(){425; TUNIT-LABEL: define dso_local void @pthread_test() {426; TUNIT-NEXT:    [[ARG1:%.*]] = alloca i8, align 8427; TUNIT-NEXT:    [[THREAD:%.*]] = alloca i64, align 8428; TUNIT-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_allocation_should_remain_same, ptr noundef nonnull align 8 dereferenceable(1) [[ARG1]])429; TUNIT-NEXT:    [[F1:%.*]] = alloca i8, i32 4, align 4430; TUNIT-NEXT:    [[CALL2:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_allocation_should_be_reduced, ptr noalias nofree nonnull readnone align 4 captures(none) dereferenceable(12) undef)431; TUNIT-NEXT:    [[F2:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4432; TUNIT-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_check_captured_pointer, ptr noundef nonnull align 4 dereferenceable(12) [[F2]])433; TUNIT-NEXT:    ret void434;435; CGSCC-LABEL: define dso_local void @pthread_test() {436; CGSCC-NEXT:    [[ARG1:%.*]] = alloca i8, align 8437; CGSCC-NEXT:    [[THREAD:%.*]] = alloca i64, align 8438; CGSCC-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_allocation_should_remain_same, ptr noundef nonnull align 8 dereferenceable(1) [[ARG1]])439; CGSCC-NEXT:    [[F:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4440; CGSCC-NEXT:    [[CALL2:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_allocation_should_be_reduced, ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(12) [[F]])441; CGSCC-NEXT:    [[F2:%.*]] = alloca [[STRUCT_FOO]], align 4442; CGSCC-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef null, ptr noundef nonnull @pthread_check_captured_pointer, ptr noundef nonnull align 4 dereferenceable(12) [[F2]])443; CGSCC-NEXT:    ret void444;445  %arg1 = alloca i8, align 8446  %thread = alloca i64, align 8447  %call1 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @pthread_allocation_should_remain_same, ptr %arg1)448  %f = alloca %struct.Foo, align 4449  %call2 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @pthread_allocation_should_be_reduced, ptr %f)450  %f2 = alloca %struct.Foo, align 4451  %call3 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @pthread_check_captured_pointer, ptr %f2)452  ret void453}454 455define internal ptr @pthread_allocation_should_remain_same(ptr %arg) {456; CHECK-LABEL: define internal noundef nonnull align 8 dereferenceable(1) ptr @pthread_allocation_should_remain_same457; CHECK-SAME: (ptr noundef nonnull returned align 8 dereferenceable(1) [[ARG:%.*]]) {458; CHECK-NEXT:  entry:459; CHECK-NEXT:    [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, ptr noundef nonnull align 8 dereferenceable(1) [[ARG]])460; CHECK-NEXT:    ret ptr [[ARG]]461;462entry:463  %call = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arg)464  ret ptr %arg465}466 467define internal void @pthread_allocation_should_be_reduced(ptr %arg) {468;469; TUNIT-LABEL: define internal void @pthread_allocation_should_be_reduced470; TUNIT-SAME: (ptr noalias nofree nonnull readnone align 4 captures(none) dereferenceable(12) [[ARG:%.*]]) {471; TUNIT-NEXT:  entry:472; TUNIT-NEXT:    [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 undef)473; TUNIT-NEXT:    ret void474;475; CGSCC-LABEL: define internal void @pthread_allocation_should_be_reduced476; CGSCC-SAME: (ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(12) [[ARG:%.*]]) {477; CGSCC-NEXT:  entry:478; CGSCC-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARG]], align 4479; CGSCC-NEXT:    [[CALL:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(17) @.str, i32 noundef [[TMP0]])480; CGSCC-NEXT:    ret void481;482entry:483  %field1 = getelementptr inbounds %struct.Foo, ptr %arg, i32 0, i32 0484  %0 = load i32, ptr %field1, align 4485  %call = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %0)486  ret void487}488 489define internal void @pthread_check_captured_pointer(ptr %arg){490; CHECK-LABEL: define internal void @pthread_check_captured_pointer491; CHECK-SAME: (ptr noundef nonnull align 4 dereferenceable(12) [[ARG:%.*]]) {492; CHECK-NEXT:  entry:493; CHECK-NEXT:    call void @external_call(ptr noundef nonnull align 4 dereferenceable(12) [[ARG]])494; CHECK-NEXT:    ret void495;496entry:497  %field1 = getelementptr inbounds %struct.Foo, ptr %arg, i32 0, i32 0498  call void @external_call(ptr %field1)499  ret void500}501 502 503declare external void @external_call(ptr)504 505declare !callback !0 dso_local i32 @pthread_create(ptr, ptr, ptr, ptr)506!1 = !{i64 2, i64 3, i1 false}507!0 = !{!1}508 509declare i32 @printf(ptr noundef, ...) #1510 511; Function Attrs: nounwind allocsize(0)512declare noalias ptr @malloc(i64 noundef) #1513;.514; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }515;.516; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }517;.518; TUNIT: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}519; TUNIT: [[META1]] = !{i64 2, i64 3, i1 false}520;.521; CGSCC: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}522; CGSCC: [[META1]] = !{i64 2, i64 3, i1 false}523;.524