464 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -passes=inline %s | FileCheck %s3; RUN: opt -S -passes='cgscc(inline)' %s | FileCheck %s4; RUN: opt -S -passes='module-inline' %s | FileCheck %s5 6declare ptr @foo()7declare void @use.ptr(ptr) willreturn nounwind8declare void @use.val(i8) willreturn nounwind9declare void @bar()10declare void @baz()11declare ptr @llvm.ptrmask.p0.i64(ptr, i64)12declare i1 @val()13declare i8 @val8()14 15define ptr @callee0123() {16; CHECK-LABEL: define ptr @callee0123() {17; CHECK-NEXT: [[R:%.*]] = call ptr @foo()18; CHECK-NEXT: ret ptr [[R]]19;20 %r = call ptr @foo()21 ret ptr %r22}23 24define ptr @caller0() {25; CHECK-LABEL: define ptr @caller0() {26; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(16) ptr @foo()27; CHECK-NEXT: ret ptr [[R_I]]28;29 %r = call dereferenceable(16) ptr @callee0123()30 ret ptr %r31}32 33define ptr @caller1() {34; CHECK-LABEL: define ptr @caller1() {35; CHECK-NEXT: [[R_I:%.*]] = call align 16 ptr @foo()36; CHECK-NEXT: ret ptr [[R_I]]37;38 %r = call align(16) ptr @callee0123()39 ret ptr %r40}41 42define ptr @caller2() {43; CHECK-LABEL: define ptr @caller2() {44; CHECK-NEXT: [[R_I:%.*]] = call noundef ptr @foo()45; CHECK-NEXT: ret ptr [[R_I]]46;47 %r = call noundef ptr @callee0123()48 ret ptr %r49}50 51define ptr @caller3() {52; CHECK-LABEL: define ptr @caller3() {53; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()54; CHECK-NEXT: ret ptr [[R_I]]55;56 %r = call dereferenceable_or_null(32) ptr @callee0123()57 ret ptr %r58}59 60define ptr @caller_0123_dornull() {61; CHECK-LABEL: define ptr @caller_0123_dornull() {62; CHECK-NEXT: [[R_I:%.*]] = call noundef align 32 dereferenceable_or_null(16) ptr @foo()63; CHECK-NEXT: ret ptr [[R_I]]64;65 %r = call noundef align(32) dereferenceable_or_null(16) ptr @callee0123()66 ret ptr %r67}68 69define ptr @caller_0123_d() {70; CHECK-LABEL: define ptr @caller_0123_d() {71; CHECK-NEXT: [[R_I:%.*]] = call noundef align 32 dereferenceable(16) ptr @foo()72; CHECK-NEXT: ret ptr [[R_I]]73;74 %r = call noundef align(32) dereferenceable(16) ptr @callee0123()75 ret ptr %r76}77 78define ptr @callee4() {79; CHECK-LABEL: define ptr @callee4() {80; CHECK-NEXT: [[R:%.*]] = call ptr @foo()81; CHECK-NEXT: call void @bar()82; CHECK-NEXT: ret ptr [[R]]83;84 %r = call ptr @foo()85 call void @bar()86 ret ptr %r87}88 89define ptr @caller4_fail() {90; CHECK-LABEL: define ptr @caller4_fail() {91; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()92; CHECK-NEXT: call void @bar()93; CHECK-NEXT: ret ptr [[R_I]]94;95 %r = call noundef align(256) ptr @callee4()96 ret ptr %r97}98 99define ptr @callee5() {100; CHECK-LABEL: define ptr @callee5() {101; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @foo()102; CHECK-NEXT: ret ptr [[R]]103;104 %r = call align(64) ptr @foo()105 ret ptr %r106}107 108define ptr @caller5_fail() {109; CHECK-LABEL: define ptr @caller5_fail() {110; CHECK-NEXT: [[R_I:%.*]] = call noundef align 64 ptr @foo()111; CHECK-NEXT: ret ptr [[R_I]]112;113 %r = call noundef align(32) ptr @callee5()114 ret ptr %r115}116 117define ptr @caller5_okay() {118; CHECK-LABEL: define ptr @caller5_okay() {119; CHECK-NEXT: [[R_I:%.*]] = call noundef align 128 ptr @foo()120; CHECK-NEXT: ret ptr [[R_I]]121;122 %r = call noundef align(128) ptr @callee5()123 ret ptr %r124}125 126define ptr @callee6() {127; CHECK-LABEL: define ptr @callee6() {128; CHECK-NEXT: [[R:%.*]] = call dereferenceable(16) ptr @foo()129; CHECK-NEXT: ret ptr [[R]]130;131 %r = call dereferenceable(16) ptr @foo()132 ret ptr %r133}134 135define ptr @caller6_fail() {136; CHECK-LABEL: define ptr @caller6_fail() {137; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(16) ptr @foo()138; CHECK-NEXT: ret ptr [[R_I]]139;140 %r = call dereferenceable(8) ptr @callee6()141 ret ptr %r142}143 144define ptr @caller6_okay() {145; CHECK-LABEL: define ptr @caller6_okay() {146; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable(32) ptr @foo()147; CHECK-NEXT: ret ptr [[R_I]]148;149 %r = call dereferenceable(32) ptr @callee6()150 ret ptr %r151}152 153define ptr @callee7() {154; CHECK-LABEL: define ptr @callee7() {155; CHECK-NEXT: [[R:%.*]] = call dereferenceable_or_null(16) ptr @foo()156; CHECK-NEXT: ret ptr [[R]]157;158 %r = call dereferenceable_or_null(16) ptr @foo()159 ret ptr %r160}161 162define ptr @caller7_fail() {163; CHECK-LABEL: define ptr @caller7_fail() {164; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(16) ptr @foo()165; CHECK-NEXT: ret ptr [[R_I]]166;167 %r = call dereferenceable_or_null(8) ptr @callee7()168 ret ptr %r169}170 171define ptr @caller7_okay() {172; CHECK-LABEL: define ptr @caller7_okay() {173; CHECK-NEXT: [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()174; CHECK-NEXT: ret ptr [[R_I]]175;176 %r = call dereferenceable_or_null(32) ptr @callee7()177 ret ptr %r178}179 180define ptr @callee8() {181; CHECK-LABEL: define ptr @callee8() {182; CHECK-NEXT: [[R:%.*]] = call ptr @foo()183; CHECK-NEXT: ret ptr [[R]]184;185 %r = call ptr @foo()186 ret ptr %r187}188 189define ptr @caller8_okay_use_after_poison_anyways() {190; CHECK-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {191; CHECK-NEXT: [[R_I:%.*]] = call nonnull ptr @foo()192; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])193; CHECK-NEXT: ret ptr [[R_I]]194;195 %r = call nonnull ptr @callee8()196 call void @use.ptr(ptr %r)197 ret ptr %r198}199 200define ptr @callee9() {201; CHECK-LABEL: define ptr @callee9() {202; CHECK-NEXT: [[R:%.*]] = call noundef ptr @foo()203; CHECK-NEXT: ret ptr [[R]]204;205 %r = call noundef ptr @foo()206 ret ptr %r207}208 209define ptr @caller9_fail_creates_ub() {210; CHECK-LABEL: define ptr @caller9_fail_creates_ub() {211; CHECK-NEXT: [[R_I:%.*]] = call noundef ptr @foo()212; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])213; CHECK-NEXT: ret ptr [[R_I]]214;215 %r = call nonnull ptr @callee9()216 call void @use.ptr(ptr %r)217 ret ptr %r218}219 220define ptr @caller9_okay_is_ub_anyways() {221; CHECK-LABEL: define ptr @caller9_okay_is_ub_anyways() {222; CHECK-NEXT: [[R_I:%.*]] = call noundef nonnull ptr @foo()223; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])224; CHECK-NEXT: ret ptr [[R_I]]225;226 %r = call noundef nonnull ptr @callee9()227 call void @use.ptr(ptr %r)228 ret ptr %r229}230 231define ptr @callee10() {232; CHECK-LABEL: define ptr @callee10() {233; CHECK-NEXT: [[R:%.*]] = call ptr @foo()234; CHECK-NEXT: call void @use.ptr(ptr [[R]])235; CHECK-NEXT: ret ptr [[R]]236;237 %r = call ptr @foo()238 call void @use.ptr(ptr %r)239 ret ptr %r240}241 242define ptr @caller10_fail_maybe_poison() {243; CHECK-LABEL: define ptr @caller10_fail_maybe_poison() {244; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()245; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])246; CHECK-NEXT: ret ptr [[R_I]]247;248 %r = call nonnull ptr @callee10()249 ret ptr %r250}251 252define ptr @caller10_okay_will_be_ub() {253; CHECK-LABEL: define ptr @caller10_okay_will_be_ub() {254; CHECK-NEXT: [[R_I:%.*]] = call noundef nonnull ptr @foo()255; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])256; CHECK-NEXT: ret ptr [[R_I]]257;258 %r = call noundef nonnull ptr @callee10()259 ret ptr %r260}261 262define noundef ptr @caller10_okay_will_be_ub_todo() {263; CHECK-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {264; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()265; CHECK-NEXT: call void @use.ptr(ptr [[R_I]])266; CHECK-NEXT: ret ptr [[R_I]]267;268 %r = call nonnull ptr @callee10()269 ret ptr %r270}271 272define ptr @callee11() {273; CHECK-LABEL: define ptr @callee11() {274; CHECK-NEXT: [[R:%.*]] = call ptr @foo()275; CHECK-NEXT: [[COND:%.*]] = call i1 @val() #[[ATTR0:[0-9]+]]276; CHECK-NEXT: br i1 [[COND]], label [[TRUE:%.*]], label [[FALSE:%.*]]277; CHECK: True:278; CHECK-NEXT: call void @baz() #[[ATTR0]]279; CHECK-NEXT: ret ptr [[R]]280; CHECK: False:281; CHECK-NEXT: call void @bar() #[[ATTR0]]282; CHECK-NEXT: [[COND2:%.*]] = call i1 @val()283; CHECK-NEXT: ret ptr [[R]]284;285 %r = call ptr @foo()286 %cond = call i1 @val() nounwind willreturn287 br i1 %cond, label %True, label %False288True:289 call void @baz() nounwind willreturn290 ret ptr %r291False:292 call void @bar() nounwind willreturn293 %cond2 = call i1 @val()294 ret ptr %r295}296 297define ptr @caller11_todo() {298; CHECK-LABEL: define ptr @caller11_todo() {299; CHECK-NEXT: [[R_I:%.*]] = call ptr @foo()300; CHECK-NEXT: [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]301; CHECK-NEXT: br i1 [[COND_I]], label [[TRUE_I:%.*]], label [[FALSE_I:%.*]]302; CHECK: True.i:303; CHECK-NEXT: call void @baz() #[[ATTR0]]304; CHECK-NEXT: br label [[CALLEE11_EXIT:%.*]]305; CHECK: False.i:306; CHECK-NEXT: call void @bar() #[[ATTR0]]307; CHECK-NEXT: [[COND2_I:%.*]] = call i1 @val()308; CHECK-NEXT: br label [[CALLEE11_EXIT]]309; CHECK: callee11.exit:310; CHECK-NEXT: ret ptr [[R_I]]311;312 %r = call nonnull ptr @callee11()313 ret ptr %r314}315 316define ptr @callee12() {317; CHECK-LABEL: define ptr @callee12() {318; CHECK-NEXT: [[P:%.*]] = call ptr @foo()319; CHECK-NEXT: [[COND:%.*]] = call i1 @val() #[[ATTR0]]320; CHECK-NEXT: [[PP:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -4)321; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], ptr [[P]], ptr [[PP]]322; CHECK-NEXT: ret ptr [[R]]323;324 %p = call ptr @foo()325 %cond = call i1 @val() nounwind willreturn326 %pp = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -4)327 %r = select i1 %cond, ptr %p, ptr %pp328 ret ptr %r329}330 331define ptr @caller12_todo() {332; CHECK-LABEL: define ptr @caller12_todo() {333; CHECK-NEXT: [[P_I:%.*]] = call ptr @foo()334; CHECK-NEXT: [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]335; CHECK-NEXT: [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)336; CHECK-NEXT: [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]337; CHECK-NEXT: ret ptr [[R_I]]338;339 %r = call nonnull ptr @callee12()340 ret ptr %r341}342 343define i8 @callee13() {344; CHECK-LABEL: define i8 @callee13() {345; CHECK-NEXT: [[R:%.*]] = call i8 @val8()346; CHECK-NEXT: ret i8 [[R]]347;348 %r = call i8 @val8()349 ret i8 %r350}351 352define i8 @caller13_okay_use_after_poison_anyways() {353; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() {354; CHECK-NEXT: [[R_I:%.*]] = call range(i8 0, 10) i8 @val8()355; CHECK-NEXT: call void @use.val(i8 [[R_I]])356; CHECK-NEXT: ret i8 [[R_I]]357;358 %r = call range(i8 0, 10) i8 @callee13()359 call void @use.val(i8 %r)360 ret i8 %r361}362 363define i8 @callee14() {364; CHECK-LABEL: define i8 @callee14() {365; CHECK-NEXT: [[R:%.*]] = call noundef i8 @val8()366; CHECK-NEXT: ret i8 [[R]]367;368 %r = call noundef i8 @val8()369 ret i8 %r370}371 372define i8 @caller14_fail_creates_ub() {373; CHECK-LABEL: define i8 @caller14_fail_creates_ub() {374; CHECK-NEXT: [[R_I:%.*]] = call noundef i8 @val8()375; CHECK-NEXT: call void @use.val(i8 [[R_I]])376; CHECK-NEXT: ret i8 [[R_I]]377;378 %r = call range(i8 0, 10) i8 @callee14()379 call void @use.val(i8 %r)380 ret i8 %r381}382 383define i8 @caller14_okay_is_ub_anyways() {384; CHECK-LABEL: define i8 @caller14_okay_is_ub_anyways() {385; CHECK-NEXT: [[R_I:%.*]] = call noundef range(i8 0, 10) i8 @val8()386; CHECK-NEXT: call void @use.val(i8 [[R_I]])387; CHECK-NEXT: ret i8 [[R_I]]388;389 %r = call noundef range(i8 0, 10) i8 @callee14()390 call void @use.val(i8 %r)391 ret i8 %r392}393 394define i8 @callee15() {395; CHECK-LABEL: define i8 @callee15() {396; CHECK-NEXT: [[R:%.*]] = call range(i8 5, 10) i8 @val8()397; CHECK-NEXT: ret i8 [[R]]398;399 %r = call range(i8 5, 10) i8 @val8()400 ret i8 %r401}402 403define i8 @caller15_okay_intersect_ranges() {404; CHECK-LABEL: define i8 @caller15_okay_intersect_ranges() {405; CHECK-NEXT: [[R_I:%.*]] = call range(i8 5, 7) i8 @val8()406; CHECK-NEXT: call void @use.val(i8 [[R_I]])407; CHECK-NEXT: ret i8 [[R_I]]408;409 %r = call range(i8 0, 7) i8 @callee15()410 call void @use.val(i8 %r)411 ret i8 %r412}413 414define i8 @caller16_not_intersecting_ranges() {415; CHECK-LABEL: define i8 @caller16_not_intersecting_ranges() {416; CHECK-NEXT: [[R_I:%.*]] = call range(i8 0, 0) i8 @val8()417; CHECK-NEXT: call void @use.val(i8 [[R_I]])418; CHECK-NEXT: ret i8 [[R_I]]419;420 %r = call range(i8 0, 5) i8 @callee15()421 call void @use.val(i8 %r)422 ret i8 %r423}424 425 426define ptr @caller_bad_ret_prop(ptr %p1, ptr %p2, i64 %x, ptr %other) {427; CHECK-LABEL: define ptr @caller_bad_ret_prop428; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]], i64 [[X:%.*]], ptr [[OTHER:%.*]]) {429; CHECK-NEXT: [[TMP1:%.*]] = call noundef ptr [[P1]](i64 [[X]], ptr [[P2]])430; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq ptr [[TMP1]], null431; CHECK-NEXT: br i1 [[CMP_I]], label [[T_I:%.*]], label [[F_I:%.*]]432; CHECK: T.i:433; CHECK-NEXT: br label [[CALLEE_BAD_RET_PROP_EXIT:%.*]]434; CHECK: F.i:435; CHECK-NEXT: br label [[CALLEE_BAD_RET_PROP_EXIT]]436; CHECK: callee_bad_ret_prop.exit:437; CHECK-NEXT: [[TMP2:%.*]] = phi ptr [ [[OTHER]], [[T_I]] ], [ [[TMP1]], [[F_I]] ]438; CHECK-NEXT: ret ptr [[TMP2]]439;440 %1 = call noundef ptr %p1(i64 %x, ptr %p2)441 %2 = call nonnull ptr @callee_bad_ret_prop(ptr %1, ptr %other)442 ret ptr %2443}444 445define ptr @callee_bad_ret_prop(ptr %x, ptr %other) {446; CHECK-LABEL: define ptr @callee_bad_ret_prop447; CHECK-SAME: (ptr [[X:%.*]], ptr [[OTHER:%.*]]) {448; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[X]], null449; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]450; CHECK: T:451; CHECK-NEXT: ret ptr [[OTHER]]452; CHECK: F:453; CHECK-NEXT: [[R:%.*]] = tail call ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 -1)454; CHECK-NEXT: ret ptr [[R]]455;456 %cmp = icmp eq ptr %x, null457 br i1 %cmp, label %T, label %F458T:459 ret ptr %other460F:461 %r = tail call ptr @llvm.ptrmask(ptr %x, i64 -1)462 ret ptr %r463}464