brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.2 KiB · 936b8a0 Raw
764 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,CGSCC4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"5 6@G = external dso_local global i32, align 47 8declare noalias ptr @malloc(i64) inaccessiblememonly9 10;.11; CHECK: @G = external dso_local global i32, align 412;.13define dso_local ptr @internal_only(i32 %arg) {14; CHECK: Function Attrs: memory(inaccessiblemem: readwrite)15; CHECK-LABEL: define {{[^@]+}}@internal_only16; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {17; CHECK-NEXT:  entry:18; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i6419; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]])20; CHECK-NEXT:    ret ptr [[CALL]]21;22entry:23  %conv = sext i32 %arg to i6424  %call = call ptr @malloc(i64 %conv)25  ret ptr %call26}27 28define dso_local ptr @internal_only_rec(i32 %arg) {29; CHECK: Function Attrs: memory(inaccessiblemem: readwrite)30; CHECK-LABEL: define {{[^@]+}}@internal_only_rec31; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {32; CHECK-NEXT:  entry:33; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 234; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 135; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]36; CHECK:       if.then:37; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 238; CHECK-NEXT:    [[CALL:%.*]] = call ptr @internal_only_rec(i32 [[DIV]])39; CHECK-NEXT:    br label [[RETURN:%.*]]40; CHECK:       if.end:41; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i6442; CHECK-NEXT:    [[CALL1:%.*]] = call noalias ptr @malloc(i64 [[CONV]])43; CHECK-NEXT:    br label [[RETURN]]44; CHECK:       return:45; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[CALL]], [[IF_THEN]] ], [ [[CALL1]], [[IF_END]] ]46; CHECK-NEXT:    ret ptr [[RETVAL_0]]47;48entry:49  %rem = srem i32 %arg, 250  %cmp = icmp eq i32 %rem, 151  br i1 %cmp, label %if.then, label %if.end52 53if.then:                                          ; preds = %entry54  %div = sdiv i32 %arg, 255  %call = call ptr @internal_only_rec(i32 %div)56  br label %return57 58if.end:                                           ; preds = %entry59  %conv = sext i32 %arg to i6460  %call1 = call ptr @malloc(i64 %conv)61  br label %return62 63return:                                           ; preds = %if.end, %if.then64  %retval.0 = phi ptr [ %call, %if.then ], [ %call1, %if.end ]65  ret ptr %retval.066}67 68define dso_local ptr @internal_only_rec_static_helper(i32 %arg) {69; CHECK: Function Attrs: memory(inaccessiblemem: readwrite)70; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper71; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {72; CHECK-NEXT:  entry:73; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_only_rec_static(i32 [[ARG]])74; CHECK-NEXT:    ret ptr [[CALL]]75;76entry:77  %call = call ptr @internal_only_rec_static(i32 %arg)78  ret ptr %call79}80 81define internal ptr @internal_only_rec_static(i32 %arg) {82; CHECK: Function Attrs: memory(inaccessiblemem: readwrite)83; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static84; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {85; CHECK-NEXT:  entry:86; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 287; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 188; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]89; CHECK:       if.then:90; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 291; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_only_rec(i32 [[DIV]])92; CHECK-NEXT:    br label [[RETURN:%.*]]93; CHECK:       if.end:94; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i6495; CHECK-NEXT:    [[CALL1:%.*]] = call noalias ptr @malloc(i64 [[CONV]])96; CHECK-NEXT:    br label [[RETURN]]97; CHECK:       return:98; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[CALL]], [[IF_THEN]] ], [ [[CALL1]], [[IF_END]] ]99; CHECK-NEXT:    ret ptr [[RETVAL_0]]100;101entry:102  %rem = srem i32 %arg, 2103  %cmp = icmp eq i32 %rem, 1104  br i1 %cmp, label %if.then, label %if.end105 106if.then:                                          ; preds = %entry107  %div = sdiv i32 %arg, 2108  %call = call ptr @internal_only_rec(i32 %div)109  br label %return110 111if.end:                                           ; preds = %entry112  %conv = sext i32 %arg to i64113  %call1 = call ptr @malloc(i64 %conv)114  br label %return115 116return:                                           ; preds = %if.end, %if.then117  %retval.0 = phi ptr [ %call, %if.then ], [ %call1, %if.end ]118  ret ptr %retval.0119}120 121define dso_local ptr @internal_only_rec_static_helper_malloc_noescape(i32 %arg) {122; FIXME: This is actually inaccessiblememonly because the malloced memory does not escape123; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape124; CHECK-SAME: (i32 [[ARG:%.*]]) {125; CHECK-NEXT:  entry:126; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_only_rec_static_malloc_noescape(i32 [[ARG]])127; CHECK-NEXT:    ret ptr [[CALL]]128;129entry:130  %call = call ptr @internal_only_rec_static_malloc_noescape(i32 %arg)131  ret ptr %call132}133 134define internal ptr @internal_only_rec_static_malloc_noescape(i32 %arg) {135; FIXME: This is actually inaccessiblememonly because the malloced memory does not escape136; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_malloc_noescape137; CHECK-SAME: (i32 [[ARG:%.*]]) {138; CHECK-NEXT:  entry:139; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[ARG]], 2140; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 1141; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]142; CHECK:       if.then:143; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[ARG]], 2144; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_only_rec(i32 [[DIV]])145; CHECK-NEXT:    br label [[RETURN:%.*]]146; CHECK:       if.end:147; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64148; CHECK-NEXT:    [[CALL1:%.*]] = call noalias ptr @malloc(i64 [[CONV]])149; CHECK-NEXT:    br label [[RETURN]]150; CHECK:       return:151; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[CALL]], [[IF_THEN]] ], [ null, [[IF_END]] ]152; CHECK-NEXT:    ret ptr [[RETVAL_0]]153;154entry:155  %rem = srem i32 %arg, 2156  %cmp = icmp eq i32 %rem, 1157  br i1 %cmp, label %if.then, label %if.end158 159if.then:                                          ; preds = %entry160  %div = sdiv i32 %arg, 2161  %call = call ptr @internal_only_rec(i32 %div)162  br label %return163 164if.end:                                           ; preds = %entry165  %conv = sext i32 %arg to i64166  %call1 = call ptr @malloc(i64 %conv)167  store i8 0, ptr %call1168  br label %return169 170return:                                           ; preds = %if.end, %if.then171  %retval.0 = phi ptr [ %call, %if.then ], [ null, %if.end ]172  ret ptr %retval.0173}174 175define dso_local ptr @internal_argmem_only_read(ptr %arg) {176; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)177; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_read178; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] {179; CHECK-NEXT:  entry:180; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[ARG]], align 4181; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP]] to i64182; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]])183; CHECK-NEXT:    ret ptr [[CALL]]184;185entry:186  %tmp = load i32, ptr %arg, align 4187  %conv = sext i32 %tmp to i64188  %call = call ptr @malloc(i64 %conv)189  ret ptr %call190}191 192define dso_local ptr @internal_argmem_only_write(ptr %arg) {193; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)194; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_write195; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {196; CHECK-NEXT:  entry:197; CHECK-NEXT:    store i32 10, ptr [[ARG]], align 4198; CHECK-NEXT:    [[CALL:%.*]] = call noalias noundef dereferenceable_or_null(10) ptr @malloc(i64 noundef 10)199; CHECK-NEXT:    ret ptr [[CALL]]200;201entry:202  store i32 10, ptr %arg, align 4203  %call = call dereferenceable_or_null(10) ptr @malloc(i64 10)204  ret ptr %call205}206 207define dso_local ptr @internal_argmem_only_rec(ptr %arg) {208; TUNIT: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)209; TUNIT-LABEL: define {{[^@]+}}@internal_argmem_only_rec210; TUNIT-SAME: (ptr nofree captures(none) [[ARG:%.*]]) #[[ATTR1]] {211; TUNIT-NEXT:  entry:212; TUNIT-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_argmem_only_rec_1(ptr nofree noundef align 4 captures(none) [[ARG]])213; TUNIT-NEXT:    ret ptr [[CALL]]214;215; CGSCC: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)216; CGSCC-LABEL: define {{[^@]+}}@internal_argmem_only_rec217; CGSCC-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {218; CGSCC-NEXT:  entry:219; CGSCC-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_argmem_only_rec_1(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ARG]])220; CGSCC-NEXT:    ret ptr [[CALL]]221;222entry:223  %call = call ptr @internal_argmem_only_rec_1(ptr %arg)224  ret ptr %call225}226 227define internal ptr @internal_argmem_only_rec_1(ptr %arg) {228; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)229; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1230; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {231; CHECK-NEXT:  entry:232; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[ARG]], align 4233; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP]], 0234; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]235; CHECK:       if.then:236; CHECK-NEXT:    br label [[RETURN:%.*]]237; CHECK:       if.end:238; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARG]], align 4239; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP1]], 1240; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]241; CHECK:       if.then2:242; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 -1243; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_argmem_only_rec_2(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ADD_PTR]])244; CHECK-NEXT:    br label [[RETURN]]245; CHECK:       if.end3:246; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARG]], align 4247; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP2]] to i64248; CHECK-NEXT:    [[CALL4:%.*]] = call noalias ptr @malloc(i64 [[CONV]])249; CHECK-NEXT:    br label [[RETURN]]250; CHECK:       return:251; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ null, [[IF_THEN]] ], [ [[CALL]], [[IF_THEN2]] ], [ [[CALL4]], [[IF_END3]] ]252; CHECK-NEXT:    ret ptr [[RETVAL_0]]253;254entry:255  %tmp = load i32, ptr %arg, align 4256  %cmp = icmp eq i32 %tmp, 0257  br i1 %cmp, label %if.then, label %if.end258 259if.then:                                          ; preds = %entry260  br label %return261 262if.end:                                           ; preds = %entry263  %tmp1 = load i32, ptr %arg, align 4264  %cmp1 = icmp eq i32 %tmp1, 1265  br i1 %cmp1, label %if.then2, label %if.end3266 267if.then2:                                         ; preds = %if.end268  %add.ptr = getelementptr inbounds i32, ptr %arg, i64 -1269  %call = call ptr @internal_argmem_only_rec_2(ptr nonnull %add.ptr)270  br label %return271 272if.end3:                                          ; preds = %if.end273  %tmp2 = load i32, ptr %arg, align 4274  %conv = sext i32 %tmp2 to i64275  %call4 = call ptr @malloc(i64 %conv)276  br label %return277 278return:                                           ; preds = %if.end3, %if.then2, %if.then279  %retval.0 = phi ptr [ null, %if.then ], [ %call, %if.then2 ], [ %call4, %if.end3 ]280  ret ptr %retval.0281}282 283define internal ptr @internal_argmem_only_rec_2(ptr %arg) {284; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)285; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_2286; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR1]] {287; CHECK-NEXT:  entry:288; CHECK-NEXT:    store i32 0, ptr [[ARG]], align 4289; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i64 -1290; CHECK-NEXT:    [[CALL:%.*]] = call noalias ptr @internal_argmem_only_rec_1(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[ADD_PTR]])291; CHECK-NEXT:    ret ptr [[CALL]]292;293entry:294  store i32 0, ptr %arg, align 4295  %add.ptr = getelementptr inbounds i32, ptr %arg, i64 -1296  %call = call ptr @internal_argmem_only_rec_1(ptr nonnull %add.ptr)297  ret ptr %call298}299 300declare ptr @unknown_ptr() readnone301declare ptr @argmem_only(ptr %arg) argmemonly302declare ptr @inaccesible_argmem_only_decl(ptr %arg) inaccessiblemem_or_argmemonly303 304define void @callerA1(ptr %arg) {305; CHECK: Function Attrs: memory(argmem: readwrite)306; CHECK-LABEL: define {{[^@]+}}@callerA1307; CHECK-SAME: (ptr [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {308; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @argmem_only(ptr [[ARG]])309; CHECK-NEXT:    ret void310;311  call ptr @argmem_only(ptr %arg)312  ret void313}314define void @callerA2(ptr %arg) {315; CHECK: Function Attrs: memory(argmem: readwrite, inaccessiblemem: readwrite)316; CHECK-LABEL: define {{[^@]+}}@callerA2317; CHECK-SAME: (ptr [[ARG:%.*]]) #[[ATTR1]] {318; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @inaccesible_argmem_only_decl(ptr [[ARG]])319; CHECK-NEXT:    ret void320;321  call ptr @inaccesible_argmem_only_decl(ptr %arg)322  ret void323}324define void @callerB1() {325; CHECK: Function Attrs: memory(none)326; CHECK-LABEL: define {{[^@]+}}@callerB1327; CHECK-SAME: () #[[ATTR2:[0-9]+]] {328; CHECK-NEXT:    [[STACK:%.*]] = alloca i8, align 1329; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @argmem_only(ptr noundef nonnull dereferenceable(1) [[STACK]])330; CHECK-NEXT:    ret void331;332  %stack = alloca i8333  call ptr @argmem_only(ptr %stack)334  ret void335}336define void @callerB2() {337; CHECK: Function Attrs: memory(inaccessiblemem: readwrite)338; CHECK-LABEL: define {{[^@]+}}@callerB2339; CHECK-SAME: () #[[ATTR0]] {340; CHECK-NEXT:    [[STACK:%.*]] = alloca i8, align 1341; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @inaccesible_argmem_only_decl(ptr noundef nonnull dereferenceable(1) [[STACK]])342; CHECK-NEXT:    ret void343;344  %stack = alloca i8345  call ptr @inaccesible_argmem_only_decl(ptr %stack)346  ret void347}348define void @callerC1() {349; CHECK-LABEL: define {{[^@]+}}@callerC1() {350; CHECK-NEXT:    [[UNKNOWN:%.*]] = call ptr @unknown_ptr()351; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @argmem_only(ptr [[UNKNOWN]])352; CHECK-NEXT:    ret void353;354  %unknown = call ptr @unknown_ptr()355  call ptr @argmem_only(ptr %unknown)356  ret void357}358define void @callerC2() {359; CHECK-LABEL: define {{[^@]+}}@callerC2() {360; CHECK-NEXT:    [[UNKNOWN:%.*]] = call ptr @unknown_ptr()361; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @inaccesible_argmem_only_decl(ptr [[UNKNOWN]])362; CHECK-NEXT:    ret void363;364  %unknown = call ptr @unknown_ptr()365  call ptr @inaccesible_argmem_only_decl(ptr %unknown)366  ret void367}368define void @callerD1() {369; CHECK-LABEL: define {{[^@]+}}@callerD1() {370; CHECK-NEXT:    [[UNKNOWN:%.*]] = call ptr @argmem_only(ptr noundef null)371; CHECK-NEXT:    store i8 0, ptr [[UNKNOWN]], align 1372; CHECK-NEXT:    ret void373;374  %unknown = call ptr @argmem_only(ptr null)375  store i8 0, ptr %unknown376  ret void377}378define void @callerD2() {379; CHECK-LABEL: define {{[^@]+}}@callerD2() {380; CHECK-NEXT:    [[UNKNOWN:%.*]] = call ptr @inaccesible_argmem_only_decl(ptr noundef null)381; CHECK-NEXT:    store i8 0, ptr [[UNKNOWN]], align 1382; CHECK-NEXT:    ret void383;384  %unknown = call ptr @inaccesible_argmem_only_decl(ptr null)385  store i8 0, ptr %unknown386  ret void387}388 389define void @write_global() {390; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)391; CHECK-LABEL: define {{[^@]+}}@write_global392; CHECK-SAME: () #[[ATTR4:[0-9]+]] {393; CHECK-NEXT:    store i32 0, ptr @G, align 4394; CHECK-NEXT:    ret void395;396  store i32 0, ptr @G, align 4397  ret void398}399define void @write_global_via_arg(ptr %GPtr) {400; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)401; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg402; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[GPTR:%.*]]) #[[ATTR5:[0-9]+]] {403; CHECK-NEXT:    store i32 0, ptr [[GPTR]], align 4404; CHECK-NEXT:    ret void405;406  store i32 0, ptr %GPtr, align 4407  ret void408}409define internal void @write_global_via_arg_internal(ptr %GPtr) {410; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none)411; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg_internal412; CHECK-SAME: () #[[ATTR6:[0-9]+]] {413; CHECK-NEXT:    store i32 0, ptr @G, align 4414; CHECK-NEXT:    ret void415;416  store i32 0, ptr %GPtr, align 4417  ret void418}419 420define void @writeonly_global() {421; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)422; TUNIT-LABEL: define {{[^@]+}}@writeonly_global423; TUNIT-SAME: () #[[ATTR4]] {424; TUNIT-NEXT:    call void @write_global() #[[ATTR10:[0-9]+]]425; TUNIT-NEXT:    ret void426;427; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)428; CGSCC-LABEL: define {{[^@]+}}@writeonly_global429; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {430; CGSCC-NEXT:    call void @write_global() #[[ATTR11:[0-9]+]]431; CGSCC-NEXT:    ret void432;433  call void @write_global()434  ret void435}436define void @writeonly_global_via_arg() {437; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)438; TUNIT-LABEL: define {{[^@]+}}@writeonly_global_via_arg439; TUNIT-SAME: () #[[ATTR4]] {440; TUNIT-NEXT:    call void @write_global_via_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) @G) #[[ATTR10]]441; TUNIT-NEXT:    ret void442;443; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)444; CGSCC-LABEL: define {{[^@]+}}@writeonly_global_via_arg445; CGSCC-SAME: () #[[ATTR7]] {446; CGSCC-NEXT:    call void @write_global_via_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) @G) #[[ATTR11]]447; CGSCC-NEXT:    ret void448;449  call void @write_global_via_arg(ptr @G)450  ret void451}452 453define void @writeonly_global_via_arg_internal() {454;455; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)456; TUNIT-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal457; TUNIT-SAME: () #[[ATTR4]] {458; TUNIT-NEXT:    call void @write_global_via_arg_internal() #[[ATTR10]]459; TUNIT-NEXT:    ret void460;461; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)462; CGSCC-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal463; CGSCC-SAME: () #[[ATTR7]] {464; CGSCC-NEXT:    call void @write_global_via_arg_internal() #[[ATTR11]]465; CGSCC-NEXT:    ret void466;467  call void @write_global_via_arg_internal(ptr @G)468  ret void469}470 471define i8 @recursive_not_readnone(ptr %ptr, i1 %c) {472; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write)473; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone474; TUNIT-SAME: (ptr nofree writeonly captures(none) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR7:[0-9]+]] {475; TUNIT-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1476; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]477; TUNIT:       t:478; TUNIT-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11:[0-9]+]]479; TUNIT-NEXT:    ret i8 1480; TUNIT:       f:481; TUNIT-NEXT:    store i8 1, ptr [[PTR]], align 1482; TUNIT-NEXT:    ret i8 0483;484; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write)485; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone486; CGSCC-SAME: (ptr nofree writeonly captures(none) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR8:[0-9]+]] {487; CGSCC-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1488; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]489; CGSCC:       t:490; CGSCC-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12:[0-9]+]]491; CGSCC-NEXT:    ret i8 1492; CGSCC:       f:493; CGSCC-NEXT:    store i8 1, ptr [[PTR]], align 1494; CGSCC-NEXT:    ret i8 0495;496  %alloc = alloca i8497  br i1 %c, label %t, label %f498t:499  call i8 @recursive_not_readnone(ptr %alloc, i1 false)500  %r = load i8, ptr %alloc501  ret i8 %r502f:503  store i8 1, ptr %ptr504  ret i8 0505}506 507define internal i8 @recursive_not_readnone_internal(ptr %ptr, i1 %c) {508; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write)509; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone_internal510; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR7]] {511; TUNIT-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1512; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]513; TUNIT:       t:514; TUNIT-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]]515; TUNIT-NEXT:    ret i8 1516; TUNIT:       f:517; TUNIT-NEXT:    store i8 1, ptr [[PTR]], align 1518; TUNIT-NEXT:    ret i8 0519;520; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write)521; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone_internal522; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR8]] {523; CGSCC-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1524; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]525; CGSCC:       t:526; CGSCC-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12]]527; CGSCC-NEXT:    ret i8 1528; CGSCC:       f:529; CGSCC-NEXT:    store i8 1, ptr [[PTR]], align 1530; CGSCC-NEXT:    ret i8 0531;532  %alloc = alloca i8533  br i1 %c, label %t, label %f534t:535  call i8 @recursive_not_readnone_internal(ptr %alloc, i1 false)536  %r = load i8, ptr %alloc537  ret i8 %r538f:539  store i8 1, ptr %ptr540  ret i8 0541}542 543define i8 @readnone_caller(i1 %c) {544; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)545; TUNIT-LABEL: define {{[^@]+}}@readnone_caller546; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] {547; TUNIT-NEXT:    [[A:%.*]] = alloca i8, align 1548; TUNIT-NEXT:    [[R:%.*]] = call i8 @recursive_not_readnone_internal(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[A]], i1 noundef [[C]]) #[[ATTR11]]549; TUNIT-NEXT:    ret i8 [[R]]550;551; CGSCC: Function Attrs: nofree nosync nounwind memory(none)552; CGSCC-LABEL: define {{[^@]+}}@readnone_caller553; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR9:[0-9]+]] {554; CGSCC-NEXT:    [[A:%.*]] = alloca i8, align 1555; CGSCC-NEXT:    [[R:%.*]] = call i8 @recursive_not_readnone_internal(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[A]], i1 noundef [[C]]) #[[ATTR13:[0-9]+]]556; CGSCC-NEXT:    ret i8 [[R]]557;558  %a = alloca i8559  %r = call i8 @recursive_not_readnone_internal(ptr %a, i1 %c)560  ret i8 %r561}562 563define internal i8 @recursive_readnone_internal2(ptr %ptr, i1 %c) {564; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write)565; TUNIT-LABEL: define {{[^@]+}}@recursive_readnone_internal2566; TUNIT-SAME: (ptr noalias nofree writeonly captures(none) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR7]] {567; TUNIT-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1568; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]569; TUNIT:       t:570; TUNIT-NEXT:    [[TMP1:%.*]] = call i8 @recursive_readnone_internal2(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]]571; TUNIT-NEXT:    ret i8 1572; TUNIT:       f:573; TUNIT-NEXT:    store i8 1, ptr [[PTR]], align 1574; TUNIT-NEXT:    ret i8 0575;576; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write)577; CGSCC-LABEL: define {{[^@]+}}@recursive_readnone_internal2578; CGSCC-SAME: (ptr noalias nofree writeonly captures(none) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR8]] {579; CGSCC-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1580; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]581; CGSCC:       t:582; CGSCC-NEXT:    [[TMP1:%.*]] = call i8 @recursive_readnone_internal2(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12]]583; CGSCC-NEXT:    ret i8 1584; CGSCC:       f:585; CGSCC-NEXT:    store i8 1, ptr [[PTR]], align 1586; CGSCC-NEXT:    ret i8 0587;588  %alloc = alloca i8589  br i1 %c, label %t, label %f590t:591  call i8 @recursive_readnone_internal2(ptr %alloc, i1 false)592  %r = load i8, ptr %alloc593  ret i8 %r594f:595  store i8 1, ptr %ptr596  ret i8 0597}598 599define i8 @readnone_caller2(i1 %c) {600; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)601; TUNIT-LABEL: define {{[^@]+}}@readnone_caller2602; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR8]] {603; TUNIT-NEXT:    [[R:%.*]] = call i8 @recursive_readnone_internal2(ptr undef, i1 noundef [[C]]) #[[ATTR11]]604; TUNIT-NEXT:    ret i8 [[R]]605;606; CGSCC: Function Attrs: nofree nosync nounwind memory(none)607; CGSCC-LABEL: define {{[^@]+}}@readnone_caller2608; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR9]] {609; CGSCC-NEXT:    [[R:%.*]] = call i8 @recursive_readnone_internal2(ptr nofree undef, i1 noundef [[C]]) #[[ATTR13]]610; CGSCC-NEXT:    ret i8 [[R]]611;612  %r = call i8 @recursive_readnone_internal2(ptr undef, i1 %c)613  ret i8 %r614}615 616define internal i8 @recursive_not_readnone_internal3(ptr %ptr, i1 %c) {617; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: write)618; TUNIT-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3619; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR7]] {620; TUNIT-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1621; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]622; TUNIT:       t:623; TUNIT-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal3(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]]624; TUNIT-NEXT:    ret i8 1625; TUNIT:       f:626; TUNIT-NEXT:    store i8 1, ptr [[PTR]], align 1627; TUNIT-NEXT:    ret i8 0628;629; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: write)630; CGSCC-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3631; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[PTR:%.*]], i1 noundef [[C:%.*]]) #[[ATTR8]] {632; CGSCC-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1633; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]634; CGSCC:       t:635; CGSCC-NEXT:    [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal3(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12]]636; CGSCC-NEXT:    ret i8 1637; CGSCC:       f:638; CGSCC-NEXT:    store i8 1, ptr [[PTR]], align 1639; CGSCC-NEXT:    ret i8 0640;641  %alloc = alloca i8642  br i1 %c, label %t, label %f643t:644  call i8 @recursive_not_readnone_internal3(ptr %alloc, i1 false)645  %r = load i8, ptr %alloc646  ret i8 %r647f:648  store i8 1, ptr %ptr649  ret i8 0650}651 652define i8 @readnone_caller3(i1 %c) {653; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)654; TUNIT-LABEL: define {{[^@]+}}@readnone_caller3655; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR8]] {656; TUNIT-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1657; TUNIT-NEXT:    [[R:%.*]] = call i8 @recursive_not_readnone_internal3(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef [[C]]) #[[ATTR11]]658; TUNIT-NEXT:    ret i8 [[R]]659;660; CGSCC: Function Attrs: nofree nosync nounwind memory(none)661; CGSCC-LABEL: define {{[^@]+}}@readnone_caller3662; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR9]] {663; CGSCC-NEXT:    [[ALLOC:%.*]] = alloca i8, align 1664; CGSCC-NEXT:    [[R:%.*]] = call i8 @recursive_not_readnone_internal3(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ALLOC]], i1 noundef [[C]]) #[[ATTR13]]665; CGSCC-NEXT:    ret i8 [[R]]666;667  %alloc = alloca i8668  %r = call i8 @recursive_not_readnone_internal3(ptr %alloc, i1 %c)669  ret i8 %r670}671 672define internal void @argmemonly_before_ipconstprop(ptr %p) argmemonly {673; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none)674; CHECK-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop675; CHECK-SAME: () #[[ATTR6]] {676; CHECK-NEXT:    store i32 0, ptr @G, align 4677; CHECK-NEXT:    ret void678;679  store i32 0, ptr %p680  ret void681}682 683define void @argmemonly_caller() {684; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)685; TUNIT-LABEL: define {{[^@]+}}@argmemonly_caller686; TUNIT-SAME: () #[[ATTR4]] {687; TUNIT-NEXT:    call void @argmemonly_before_ipconstprop() #[[ATTR10]]688; TUNIT-NEXT:    ret void689;690; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write)691; CGSCC-LABEL: define {{[^@]+}}@argmemonly_caller692; CGSCC-SAME: () #[[ATTR7]] {693; CGSCC-NEXT:    call void @argmemonly_before_ipconstprop() #[[ATTR11]]694; CGSCC-NEXT:    ret void695;696  call void @argmemonly_before_ipconstprop(ptr @G)697  ret void698}699 700declare ptr @no_mem_unknown_ptr(ptr %arg) memory(none)701 702define void @argmem_and_unknown(i1 %c, ptr %arg) memory(argmem: readwrite) {703; TUNIT: Function Attrs: nosync memory(argmem: write)704; TUNIT-LABEL: define {{[^@]+}}@argmem_and_unknown705; TUNIT-SAME: (i1 noundef [[C:%.*]], ptr writeonly [[ARG:%.*]]) #[[ATTR9:[0-9]+]] {706; TUNIT-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]707; TUNIT:       t:708; TUNIT-NEXT:    [[P:%.*]] = call ptr @no_mem_unknown_ptr(ptr noalias readnone [[ARG]]) #[[ATTR12:[0-9]+]]709; TUNIT-NEXT:    store i32 0, ptr [[P]], align 4710; TUNIT-NEXT:    br label [[F]]711; TUNIT:       f:712; TUNIT-NEXT:    ret void713;714; CGSCC: Function Attrs: nosync memory(argmem: write)715; CGSCC-LABEL: define {{[^@]+}}@argmem_and_unknown716; CGSCC-SAME: (i1 noundef [[C:%.*]], ptr writeonly [[ARG:%.*]]) #[[ATTR10:[0-9]+]] {717; CGSCC-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]718; CGSCC:       t:719; CGSCC-NEXT:    [[P:%.*]] = call ptr @no_mem_unknown_ptr(ptr noalias readnone [[ARG]]) #[[ATTR14:[0-9]+]]720; CGSCC-NEXT:    store i32 0, ptr [[P]], align 4721; CGSCC-NEXT:    br label [[F]]722; CGSCC:       f:723; CGSCC-NEXT:    ret void724;725  br i1 %c, label %t, label %f726t:727  %p = call ptr @no_mem_unknown_ptr(ptr %arg)728  store i32 0, ptr %p729  br label %f730f:731  ret void732}733;.734; TUNIT: attributes #[[ATTR0]] = { memory(inaccessiblemem: readwrite) }735; TUNIT: attributes #[[ATTR1]] = { memory(argmem: readwrite, inaccessiblemem: readwrite) }736; TUNIT: attributes #[[ATTR2]] = { memory(none) }737; TUNIT: attributes #[[ATTR3]] = { memory(argmem: readwrite) }738; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }739; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }740; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none) }741; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind memory(argmem: write) }742; TUNIT: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind memory(none) }743; TUNIT: attributes #[[ATTR9]] = { nosync memory(argmem: write) }744; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn memory(write) }745; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind memory(write) }746; TUNIT: attributes #[[ATTR12]] = { nosync }747;.748; CGSCC: attributes #[[ATTR0]] = { memory(inaccessiblemem: readwrite) }749; CGSCC: attributes #[[ATTR1]] = { memory(argmem: readwrite, inaccessiblemem: readwrite) }750; CGSCC: attributes #[[ATTR2]] = { memory(none) }751; CGSCC: attributes #[[ATTR3]] = { memory(argmem: readwrite) }752; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }753; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }754; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none) }755; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree nosync nounwind willreturn memory(write) }756; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind memory(argmem: write) }757; CGSCC: attributes #[[ATTR9]] = { nofree nosync nounwind memory(none) }758; CGSCC: attributes #[[ATTR10]] = { nosync memory(argmem: write) }759; CGSCC: attributes #[[ATTR11]] = { nofree nounwind willreturn memory(write) }760; CGSCC: attributes #[[ATTR12]] = { nofree nosync nounwind memory(write) }761; CGSCC: attributes #[[ATTR13]] = { nofree nounwind memory(write) }762; CGSCC: attributes #[[ATTR14]] = { nosync }763;.764