246 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes=function-attrs < %s | FileCheck %s3 4declare noalias ptr @malloc(i64 %size)5declare ptr @not_malloc(i64 %size)6declare void @capture(ptr)7 8@g = external global i89 10define ptr @return_malloc(i64 %size) {11; CHECK-LABEL: define noalias ptr @return_malloc(12; CHECK-SAME: i64 [[SIZE:%.*]]) {13; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])14; CHECK-NEXT: ret ptr [[A]]15;16 %a = call ptr @malloc(i64 %size)17 ret ptr %a18}19 20define ptr @return_not_malloc(i64 %size) {21; CHECK-LABEL: define ptr @return_not_malloc(22; CHECK-SAME: i64 [[SIZE:%.*]]) {23; CHECK-NEXT: [[A:%.*]] = call ptr @not_malloc(i64 [[SIZE]])24; CHECK-NEXT: ret ptr [[A]]25;26 %a = call ptr @not_malloc(i64 %size)27 ret ptr %a28}29 30define ptr @return_null() {31; CHECK-LABEL: define noalias noundef ptr @return_null(32; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {33; CHECK-NEXT: ret ptr null34;35 ret ptr null36}37 38define ptr @return_poison() {39; CHECK-LABEL: define noalias ptr @return_poison(40; CHECK-SAME: ) #[[ATTR0]] {41; CHECK-NEXT: ret ptr poison42;43 ret ptr poison44}45 46define ptr @return_alloca() {47; CHECK-LABEL: define noalias noundef nonnull ptr @return_alloca(48; CHECK-SAME: ) #[[ATTR0]] {49; CHECK-NEXT: [[A:%.*]] = alloca i8, align 150; CHECK-NEXT: ret ptr [[A]]51;52 %a = alloca i853 ret ptr %a54}55 56; noalias arg does not imply noalias return57define ptr @return_noalias_arg(ptr noalias %arg) {58; CHECK-LABEL: define ptr @return_noalias_arg(59; CHECK-SAME: ptr noalias readnone returned captures(ret: address, provenance) [[ARG:%.*]]) #[[ATTR0]] {60; CHECK-NEXT: ret ptr [[ARG]]61;62 ret ptr %arg63}64 65define ptr @return_global() {66; CHECK-LABEL: define noundef nonnull ptr @return_global(67; CHECK-SAME: ) #[[ATTR0]] {68; CHECK-NEXT: ret ptr @g69;70 ret ptr @g71}72 73define ptr @no_return() {74; CHECK-LABEL: define noalias noundef nonnull ptr @no_return(75; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {76; CHECK-NEXT: unreachable77;78 unreachable79}80 81define ptr @return_multiple(i1 %c, i64 %size) {82; CHECK-LABEL: define noalias ptr @return_multiple(83; CHECK-SAME: i1 [[C:%.*]], i64 [[SIZE:%.*]]) {84; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]85; CHECK: [[IF]]:86; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])87; CHECK-NEXT: ret ptr [[A]]88; CHECK: [[ELSE]]:89; CHECK-NEXT: [[B:%.*]] = call ptr @malloc(i64 [[SIZE]])90; CHECK-NEXT: ret ptr [[B]]91;92br i1 %c, label %if, label %else93 94if:95 %a = call ptr @malloc(i64 %size)96 ret ptr %a97 98else:99 %b = call ptr @malloc(i64 %size)100 ret ptr %b101}102 103define ptr @return_select(i1 %c, i64 %size) {104; CHECK-LABEL: define noalias ptr @return_select(105; CHECK-SAME: i1 [[C:%.*]], i64 [[SIZE:%.*]]) {106; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])107; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], ptr [[A]], ptr null108; CHECK-NEXT: ret ptr [[SEL]]109;110 %a = call ptr @malloc(i64 %size)111 %sel = select i1 %c, ptr %a, ptr null112 ret ptr %sel113}114 115define ptr @return_phi(i1 %c, i64 %size) {116; CHECK-LABEL: define noalias ptr @return_phi(117; CHECK-SAME: i1 [[C:%.*]], i64 [[SIZE:%.*]]) {118; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]119; CHECK: [[IF]]:120; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])121; CHECK-NEXT: br label %[[JOIN:.*]]122; CHECK: [[ELSE]]:123; CHECK-NEXT: br label %[[JOIN]]124; CHECK: [[JOIN]]:125; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[A]], %[[IF]] ], [ null, %[[ELSE]] ]126; CHECK-NEXT: ret ptr [[PHI]]127;128 br i1 %c, label %if, label %else129 130if:131 %a = call ptr @malloc(i64 %size)132 br label %join133 134else:135 br label %join136 137join:138 %phi = phi ptr [ %a, %if ], [ null, %else ]139 ret ptr %phi140}141 142define ptr @return_phi_wrong(i1 %c, i64 %size) {143; CHECK-LABEL: define ptr @return_phi_wrong(144; CHECK-SAME: i1 [[C:%.*]], i64 [[SIZE:%.*]]) {145; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]146; CHECK: [[IF]]:147; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])148; CHECK-NEXT: br label %[[JOIN:.*]]149; CHECK: [[ELSE]]:150; CHECK-NEXT: [[B:%.*]] = call ptr @not_malloc(i64 [[SIZE]])151; CHECK-NEXT: br label %[[JOIN]]152; CHECK: [[JOIN]]:153; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[A]], %[[IF]] ], [ [[B]], %[[ELSE]] ]154; CHECK-NEXT: ret ptr [[PHI]]155;156 br i1 %c, label %if, label %else157 158if:159 %a = call ptr @malloc(i64 %size)160 br label %join161 162else:163 %b = call ptr @not_malloc(i64 %size)164 br label %join165 166join:167 %phi = phi ptr [ %a, %if ], [ %b, %else ]168 ret ptr %phi169}170 171define ptr @return_malloc_with_store(i64 %size) {172; CHECK-LABEL: define noalias noundef ptr @return_malloc_with_store(173; CHECK-SAME: i64 [[SIZE:%.*]]) {174; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])175; CHECK-NEXT: store i8 0, ptr [[A]], align 1176; CHECK-NEXT: ret ptr [[A]]177;178 %a = call ptr @malloc(i64 %size)179 store i8 0, ptr %a180 ret ptr %a181}182 183define ptr @return_malloc_captured(i64 %size) {184; CHECK-LABEL: define ptr @return_malloc_captured(185; CHECK-SAME: i64 [[SIZE:%.*]]) {186; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 [[SIZE]])187; CHECK-NEXT: call void @capture(ptr [[A]])188; CHECK-NEXT: ret ptr [[A]]189;190 %a = call ptr @malloc(i64 %size)191 call void @capture(ptr %a)192 ret ptr %a193}194 195define ptr @scc1(i1 %c) {196; CHECK-LABEL: define noalias ptr @scc1(197; CHECK-SAME: i1 [[C:%.*]]) {198; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]199; CHECK: [[IF]]:200; CHECK-NEXT: [[A:%.*]] = call ptr @malloc(i64 4)201; CHECK-NEXT: ret ptr [[A]]202; CHECK: [[ELSE]]:203; CHECK-NEXT: [[B:%.*]] = call ptr @scc2(i1 [[C]])204; CHECK-NEXT: ret ptr [[B]]205;206 br i1 %c, label %if, label %else207 208if:209 %a = call ptr @malloc(i64 4)210 ret ptr %a211 212else:213 %b = call ptr @scc2(i1 %c)214 ret ptr %b215}216 217define ptr @scc2(i1 %c) {218; CHECK-LABEL: define noalias ptr @scc2(219; CHECK-SAME: i1 [[C:%.*]]) {220; CHECK-NEXT: [[A:%.*]] = call ptr @scc1(i1 [[C]])221; CHECK-NEXT: ret ptr [[A]]222;223 %a = call ptr @scc1(i1 %c)224 ret ptr %a225}226 227define ptr @return_unknown_call(ptr %fn) {228; CHECK-LABEL: define ptr @return_unknown_call(229; CHECK-SAME: ptr readonly captures(none) [[FN:%.*]]) {230; CHECK-NEXT: [[A:%.*]] = call ptr [[FN]]()231; CHECK-NEXT: ret ptr [[A]]232;233 %a = call ptr %fn()234 ret ptr %a235}236 237define ptr @return_unknown_noalias_call(ptr %fn) {238; CHECK-LABEL: define noalias ptr @return_unknown_noalias_call(239; CHECK-SAME: ptr readonly captures(none) [[FN:%.*]]) {240; CHECK-NEXT: [[A:%.*]] = call noalias ptr [[FN]]()241; CHECK-NEXT: ret ptr [[A]]242;243 %a = call noalias ptr %fn()244 ret ptr %a245}246