brintos

brintos / llvm-project-archived public Read only

0
0
Text · 64.7 KiB · b5b14f5 Raw
1471 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 22; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s3; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s4 5@g = global ptr null		; <ptr> [#uses=1]6 7define ptr @c1(ptr %q) {8; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)9; FNATTRS-LABEL: define ptr @c110; FNATTRS-SAME: (ptr readnone returned captures(ret: address, provenance) [[Q:%.*]]) #[[ATTR0:[0-9]+]] {11; FNATTRS-NEXT:    ret ptr [[Q]]12;13; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)14; ATTRIBUTOR-LABEL: define ptr @c115; ATTRIBUTOR-SAME: (ptr nofree readnone [[Q:%.*]]) #[[ATTR0:[0-9]+]] {16; ATTRIBUTOR-NEXT:    ret ptr [[Q]]17;18  ret ptr %q19}20 21; It would also be acceptable to mark %q as readnone. Update @c3 too.22define void @c2(ptr %q) {23; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)24; FNATTRS-LABEL: define void @c225; FNATTRS-SAME: (ptr [[Q:%.*]]) #[[ATTR1:[0-9]+]] {26; FNATTRS-NEXT:    store ptr [[Q]], ptr @g, align 827; FNATTRS-NEXT:    ret void28;29; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)30; ATTRIBUTOR-LABEL: define void @c231; ATTRIBUTOR-SAME: (ptr nofree writeonly [[Q:%.*]]) #[[ATTR1:[0-9]+]] {32; ATTRIBUTOR-NEXT:    store ptr [[Q]], ptr @g, align 833; ATTRIBUTOR-NEXT:    ret void34;35  store ptr %q, ptr @g36  ret void37}38 39define void @c3(ptr %q) {40; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none, target_mem0: none, target_mem1: none)41; FNATTRS-LABEL: define void @c342; FNATTRS-SAME: (ptr [[Q:%.*]]) #[[ATTR2:[0-9]+]] {43; FNATTRS-NEXT:    call void @c2(ptr [[Q]])44; FNATTRS-NEXT:    ret void45;46; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)47; ATTRIBUTOR-LABEL: define void @c348; ATTRIBUTOR-SAME: (ptr nofree writeonly [[Q:%.*]]) #[[ATTR1]] {49; ATTRIBUTOR-NEXT:    call void @c2(ptr nofree writeonly [[Q]]) #[[ATTR21:[0-9]+]]50; ATTRIBUTOR-NEXT:    ret void51;52  call void @c2(ptr %q)53  ret void54}55 56define i1 @c4(ptr %q, i32 %bitno) {57; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)58; FNATTRS-LABEL: define noundef i1 @c459; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {60; FNATTRS-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i3261; FNATTRS-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]62; FNATTRS-NEXT:    [[BIT:%.*]] = trunc i32 [[TMP2]] to i163; FNATTRS-NEXT:    br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]64; FNATTRS:       l0:65; FNATTRS-NEXT:    ret i1 false66; FNATTRS:       l1:67; FNATTRS-NEXT:    ret i1 true68;69; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)70; ATTRIBUTOR-LABEL: define i1 @c471; ATTRIBUTOR-SAME: (ptr nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {72; ATTRIBUTOR-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i3273; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]74; ATTRIBUTOR-NEXT:    [[BIT:%.*]] = trunc i32 [[TMP2]] to i175; ATTRIBUTOR-NEXT:    br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]76; ATTRIBUTOR:       l0:77; ATTRIBUTOR-NEXT:    ret i1 false78; ATTRIBUTOR:       l1:79; ATTRIBUTOR-NEXT:    ret i1 true80;81  %tmp = ptrtoint ptr %q to i3282  %tmp2 = lshr i32 %tmp, %bitno83  %bit = trunc i32 %tmp2 to i184  br i1 %bit, label %l1, label %l085l0:86  ret i1 0 ; escaping value not caught by def-use chaining.87l1:88  ret i1 1 ; escaping value not caught by def-use chaining.89}90 91; c4b is c4 but without the escaping part92define i1 @c4b(ptr %q, i32 %bitno) {93; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)94; FNATTRS-LABEL: define noundef i1 @c4b95; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {96; FNATTRS-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i3297; FNATTRS-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]98; FNATTRS-NEXT:    [[BIT:%.*]] = trunc i32 [[TMP2]] to i199; FNATTRS-NEXT:    br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]100; FNATTRS:       l0:101; FNATTRS-NEXT:    ret i1 false102; FNATTRS:       l1:103; FNATTRS-NEXT:    ret i1 false104;105; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)106; ATTRIBUTOR-LABEL: define i1 @c4b107; ATTRIBUTOR-SAME: (ptr nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {108; ATTRIBUTOR-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32109; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]110; ATTRIBUTOR-NEXT:    [[BIT:%.*]] = trunc i32 [[TMP2]] to i1111; ATTRIBUTOR-NEXT:    br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]112; ATTRIBUTOR:       l0:113; ATTRIBUTOR-NEXT:    ret i1 false114; ATTRIBUTOR:       l1:115; ATTRIBUTOR-NEXT:    ret i1 false116;117  %tmp = ptrtoint ptr %q to i32118  %tmp2 = lshr i32 %tmp, %bitno119  %bit = trunc i32 %tmp2 to i1120  br i1 %bit, label %l1, label %l0121l0:122  ret i1 0 ; not escaping!123l1:124  ret i1 0 ; not escaping!125}126 127@lookup_table = global [2 x i1] [ i1 0, i1 1 ]128 129define i1 @c5(ptr %q, i32 %bitno) {130; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)131; FNATTRS-LABEL: define i1 @c5132; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR3:[0-9]+]] {133; FNATTRS-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32134; FNATTRS-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]135; FNATTRS-NEXT:    [[BIT:%.*]] = and i32 [[TMP2]], 1136; FNATTRS-NEXT:    [[LOOKUP:%.*]] = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 [[BIT]]137; FNATTRS-NEXT:    [[VAL:%.*]] = load i1, ptr [[LOOKUP]], align 1138; FNATTRS-NEXT:    ret i1 [[VAL]]139;140; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)141; ATTRIBUTOR-LABEL: define i1 @c5142; ATTRIBUTOR-SAME: (ptr nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2:[0-9]+]] {143; ATTRIBUTOR-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32144; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]145; ATTRIBUTOR-NEXT:    [[BIT:%.*]] = and i32 [[TMP2]], 1146; ATTRIBUTOR-NEXT:    [[LOOKUP:%.*]] = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 [[BIT]]147; ATTRIBUTOR-NEXT:    [[VAL:%.*]] = load i1, ptr [[LOOKUP]], align 1148; ATTRIBUTOR-NEXT:    ret i1 [[VAL]]149;150  %tmp = ptrtoint ptr %q to i32151  %tmp2 = lshr i32 %tmp, %bitno152  %bit = and i32 %tmp2, 1153  ; subtle escape mechanism follows154  %lookup = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 %bit155  %val = load i1, ptr %lookup156  ret i1 %val157}158 159declare void @throw_if_bit_set(ptr, i8) readonly160 161define i1 @c6(ptr %q, i8 %bit) personality ptr @__gxx_personality_v0 {162; FNATTRS: Function Attrs: nofree memory(read)163; FNATTRS-LABEL: define noundef i1 @c6164; FNATTRS-SAME: (ptr readonly captures(address) [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR5:[0-9]+]] personality ptr @__gxx_personality_v0 {165; FNATTRS-NEXT:    invoke void @throw_if_bit_set(ptr [[Q]], i8 [[BIT]])166; FNATTRS-NEXT:            to label [[RET0:%.*]] unwind label [[RET1:%.*]]167; FNATTRS:       ret0:168; FNATTRS-NEXT:    ret i1 false169; FNATTRS:       ret1:170; FNATTRS-NEXT:    [[EXN:%.*]] = landingpad { ptr, i32 }171; FNATTRS-NEXT:            cleanup172; FNATTRS-NEXT:    ret i1 true173;174; ATTRIBUTOR: Function Attrs: nosync memory(read)175; ATTRIBUTOR-LABEL: define i1 @c6176; ATTRIBUTOR-SAME: (ptr readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @__gxx_personality_v0 {177; ATTRIBUTOR-NEXT:    invoke void @throw_if_bit_set(ptr [[Q]], i8 [[BIT]]) #[[ATTR4]]178; ATTRIBUTOR-NEXT:            to label [[RET0:%.*]] unwind label [[RET1:%.*]]179; ATTRIBUTOR:       ret0:180; ATTRIBUTOR-NEXT:    ret i1 false181; ATTRIBUTOR:       ret1:182; ATTRIBUTOR-NEXT:    [[EXN:%.*]] = landingpad { ptr, i32 }183; ATTRIBUTOR-NEXT:            cleanup184; ATTRIBUTOR-NEXT:    ret i1 true185;186  invoke void @throw_if_bit_set(ptr %q, i8 %bit)187  to label %ret0 unwind label %ret1188ret0:189  ret i1 0190ret1:191  %exn = landingpad {ptr, i32}192  cleanup193  ret i1 1194}195 196declare i32 @__gxx_personality_v0(...)197 198define ptr @lookup_bit(ptr %q, i32 %bitno) readnone nounwind {199; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)200; FNATTRS-LABEL: define ptr @lookup_bit201; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {202; FNATTRS-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32203; FNATTRS-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]204; FNATTRS-NEXT:    [[BIT:%.*]] = and i32 [[TMP2]], 1205; FNATTRS-NEXT:    [[LOOKUP:%.*]] = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 [[BIT]]206; FNATTRS-NEXT:    ret ptr [[LOOKUP]]207;208; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)209; ATTRIBUTOR-LABEL: define ptr @lookup_bit210; ATTRIBUTOR-SAME: (ptr nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {211; ATTRIBUTOR-NEXT:    [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32212; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]213; ATTRIBUTOR-NEXT:    [[BIT:%.*]] = and i32 [[TMP2]], 1214; ATTRIBUTOR-NEXT:    [[LOOKUP:%.*]] = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 [[BIT]]215; ATTRIBUTOR-NEXT:    ret ptr [[LOOKUP]]216;217  %tmp = ptrtoint ptr %q to i32218  %tmp2 = lshr i32 %tmp, %bitno219  %bit = and i32 %tmp2, 1220  %lookup = getelementptr [2 x i1], ptr @lookup_table, i32 0, i32 %bit221  ret ptr %lookup222}223 224define i1 @c7(ptr %q, i32 %bitno) {225; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)226; FNATTRS-LABEL: define i1 @c7227; FNATTRS-SAME: (ptr readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR6:[0-9]+]] {228; FNATTRS-NEXT:    [[PTR:%.*]] = call ptr @lookup_bit(ptr [[Q]], i32 [[BITNO]])229; FNATTRS-NEXT:    [[VAL:%.*]] = load i1, ptr [[PTR]], align 1230; FNATTRS-NEXT:    ret i1 [[VAL]]231;232; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)233; ATTRIBUTOR-LABEL: define i1 @c7234; ATTRIBUTOR-SAME: (ptr nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {235; ATTRIBUTOR-NEXT:    [[PTR:%.*]] = call ptr @lookup_bit(ptr nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR22:[0-9]+]]236; ATTRIBUTOR-NEXT:    [[VAL:%.*]] = load i1, ptr [[PTR]], align 1237; ATTRIBUTOR-NEXT:    ret i1 [[VAL]]238;239  %ptr = call ptr @lookup_bit(ptr %q, i32 %bitno)240  %val = load i1, ptr %ptr241  ret i1 %val242}243 244 245define i32 @nc1(ptr %q, ptr %p, i1 %b) {246; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)247; FNATTRS-LABEL: define i32 @nc1248; FNATTRS-SAME: (ptr [[Q:%.*]], ptr captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7:[0-9]+]] {249; FNATTRS-NEXT:  e:250; FNATTRS-NEXT:    br label [[L:%.*]]251; FNATTRS:       l:252; FNATTRS-NEXT:    [[X:%.*]] = phi ptr [ [[P]], [[E:%.*]] ]253; FNATTRS-NEXT:    [[Y:%.*]] = phi ptr [ [[Q]], [[E]] ]254; FNATTRS-NEXT:    [[TMP2:%.*]] = select i1 [[B]], ptr [[X]], ptr [[Y]]255; FNATTRS-NEXT:    [[VAL:%.*]] = load i32, ptr [[TMP2]], align 4256; FNATTRS-NEXT:    store i32 0, ptr [[X]], align 4257; FNATTRS-NEXT:    store ptr [[Y]], ptr @g, align 8258; FNATTRS-NEXT:    ret i32 [[VAL]]259;260; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn261; ATTRIBUTOR-LABEL: define i32 @nc1262; ATTRIBUTOR-SAME: (ptr nofree [[Q:%.*]], ptr nofree captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] {263; ATTRIBUTOR-NEXT:  e:264; ATTRIBUTOR-NEXT:    br label [[L:%.*]]265; ATTRIBUTOR:       l:266; ATTRIBUTOR-NEXT:    [[X:%.*]] = phi ptr [ [[P]], [[E:%.*]] ]267; ATTRIBUTOR-NEXT:    [[Y:%.*]] = phi ptr [ [[Q]], [[E]] ]268; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = select i1 [[B]], ptr [[X]], ptr [[Y]]269; ATTRIBUTOR-NEXT:    [[VAL:%.*]] = load i32, ptr [[TMP2]], align 4270; ATTRIBUTOR-NEXT:    store i32 0, ptr [[X]], align 4271; ATTRIBUTOR-NEXT:    store ptr [[Y]], ptr @g, align 8272; ATTRIBUTOR-NEXT:    ret i32 [[VAL]]273;274e:275  br label %l276l:277  %x = phi ptr [ %p, %e ]278  %y = phi ptr [ %q, %e ]279  %tmp2 = select i1 %b, ptr %x, ptr %y280  %val = load i32, ptr %tmp2		; <i32> [#uses=1]281  store i32 0, ptr %x282  store ptr %y, ptr @g283  ret i32 %val284}285 286define i32 @nc1_addrspace(ptr %q, ptr addrspace(1) %p, i1 %b) {287; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)288; FNATTRS-LABEL: define i32 @nc1_addrspace289; FNATTRS-SAME: (ptr [[Q:%.*]], ptr addrspace(1) captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7]] {290; FNATTRS-NEXT:  e:291; FNATTRS-NEXT:    br label [[L:%.*]]292; FNATTRS:       l:293; FNATTRS-NEXT:    [[X:%.*]] = phi ptr addrspace(1) [ [[P]], [[E:%.*]] ]294; FNATTRS-NEXT:    [[Y:%.*]] = phi ptr [ [[Q]], [[E]] ]295; FNATTRS-NEXT:    [[TMP:%.*]] = addrspacecast ptr addrspace(1) [[X]] to ptr296; FNATTRS-NEXT:    [[TMP2:%.*]] = select i1 [[B]], ptr [[TMP]], ptr [[Y]]297; FNATTRS-NEXT:    [[VAL:%.*]] = load i32, ptr [[TMP2]], align 4298; FNATTRS-NEXT:    store i32 0, ptr [[TMP]], align 4299; FNATTRS-NEXT:    store ptr [[Y]], ptr @g, align 8300; FNATTRS-NEXT:    ret i32 [[VAL]]301;302; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn303; ATTRIBUTOR-LABEL: define i32 @nc1_addrspace304; ATTRIBUTOR-SAME: (ptr nofree [[Q:%.*]], ptr addrspace(1) nofree captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5]] {305; ATTRIBUTOR-NEXT:  e:306; ATTRIBUTOR-NEXT:    br label [[L:%.*]]307; ATTRIBUTOR:       l:308; ATTRIBUTOR-NEXT:    [[X:%.*]] = phi ptr addrspace(1) [ [[P]], [[E:%.*]] ]309; ATTRIBUTOR-NEXT:    [[Y:%.*]] = phi ptr [ [[Q]], [[E]] ]310; ATTRIBUTOR-NEXT:    [[TMP:%.*]] = addrspacecast ptr addrspace(1) [[X]] to ptr311; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = select i1 [[B]], ptr [[TMP]], ptr [[Y]]312; ATTRIBUTOR-NEXT:    [[VAL:%.*]] = load i32, ptr [[TMP2]], align 4313; ATTRIBUTOR-NEXT:    store i32 0, ptr [[TMP]], align 4314; ATTRIBUTOR-NEXT:    store ptr [[Y]], ptr @g, align 8315; ATTRIBUTOR-NEXT:    ret i32 [[VAL]]316;317e:318  br label %l319l:320  %x = phi ptr addrspace(1) [ %p, %e ]321  %y = phi ptr [ %q, %e ]322  %tmp = addrspacecast ptr addrspace(1) %x to ptr		; <ptr> [#uses=2]323  %tmp2 = select i1 %b, ptr %tmp, ptr %y324  %val = load i32, ptr %tmp2		; <i32> [#uses=1]325  store i32 0, ptr %tmp326  store ptr %y, ptr @g327  ret i32 %val328}329 330define void @nc2(ptr %p, ptr %q) {331; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)332; FNATTRS-LABEL: define void @nc2333; FNATTRS-SAME: (ptr captures(none) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR7]] {334; FNATTRS-NEXT:    [[TMP1:%.*]] = call i32 @nc1(ptr [[Q]], ptr [[P]], i1 false)335; FNATTRS-NEXT:    ret void336;337; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn338; ATTRIBUTOR-LABEL: define void @nc2339; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR5]] {340; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call i32 @nc1(ptr nofree [[Q]], ptr nofree captures(none) [[P]], i1 false) #[[ATTR23:[0-9]+]]341; ATTRIBUTOR-NEXT:    ret void342;343  %1 = call i32 @nc1(ptr %q, ptr %p, i1 0)		; <i32> [#uses=0]344  ret void345}346 347 348define void @nc3(ptr %p) {349; FNATTRS-LABEL: define void @nc3350; FNATTRS-SAME: (ptr readonly captures(none) [[P:%.*]]) {351; FNATTRS-NEXT:    call void [[P]]()352; FNATTRS-NEXT:    ret void353;354; ATTRIBUTOR-LABEL: define void @nc3355; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) {356; ATTRIBUTOR-NEXT:    call void [[P]]()357; ATTRIBUTOR-NEXT:    ret void358;359  call void %p()360  ret void361}362 363declare void @external_not_willreturn(ptr) readonly nounwind364define void @readonly_nounwind_not_willreturn(ptr %p) {365; FNATTRS: Function Attrs: nofree nounwind memory(read)366; FNATTRS-LABEL: define void @readonly_nounwind_not_willreturn367; FNATTRS-SAME: (ptr readonly captures(address) [[P:%.*]]) #[[ATTR9:[0-9]+]] {368; FNATTRS-NEXT:    call void @external_not_willreturn(ptr [[P]])369; FNATTRS-NEXT:    ret void370;371; ATTRIBUTOR: Function Attrs: nosync nounwind memory(read)372; ATTRIBUTOR-LABEL: define void @readonly_nounwind_not_willreturn373; ATTRIBUTOR-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR7:[0-9]+]] {374; ATTRIBUTOR-NEXT:    call void @external_not_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR4]]375; ATTRIBUTOR-NEXT:    ret void376;377  call void @external_not_willreturn(ptr %p)378  ret void379}380 381declare void @external_willreturn(ptr) readonly nounwind willreturn382define void @readonly_nounwind_willreturn(ptr %p) {383; FNATTRS: Function Attrs: mustprogress nofree nounwind willreturn memory(read)384; FNATTRS-LABEL: define void @readonly_nounwind_willreturn385; FNATTRS-SAME: (ptr readonly captures(address) [[P:%.*]]) #[[ATTR11:[0-9]+]] {386; FNATTRS-NEXT:    call void @external_willreturn(ptr [[P]])387; FNATTRS-NEXT:    ret void388;389; ATTRIBUTOR: Function Attrs: mustprogress nosync nounwind willreturn memory(read)390; ATTRIBUTOR-LABEL: define void @readonly_nounwind_willreturn391; ATTRIBUTOR-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR9:[0-9]+]] {392; ATTRIBUTOR-NEXT:    call void @external_willreturn(ptr readonly captures(none) [[P]]) #[[ATTR24:[0-9]+]]393; ATTRIBUTOR-NEXT:    ret void394;395  call void @external_willreturn(ptr %p)396  ret void397}398 399define void @callsite_readonly_nounwind_not_willreturn(ptr %f, ptr %p) {400; FNATTRS-LABEL: define void @callsite_readonly_nounwind_not_willreturn401; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr captures(address) [[P:%.*]]) {402; FNATTRS-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR8:[0-9]+]]403; FNATTRS-NEXT:    call void [[F]](ptr captures(none) [[P]])404; FNATTRS-NEXT:    ret void405;406; ATTRIBUTOR-LABEL: define void @callsite_readonly_nounwind_not_willreturn407; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[F:%.*]], ptr [[P:%.*]]) {408; ATTRIBUTOR-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR6:[0-9]+]]409; ATTRIBUTOR-NEXT:    call void [[F]](ptr captures(none) [[P]])410; ATTRIBUTOR-NEXT:    ret void411;412  call void %f(ptr %p) readonly nounwind413  call void %f(ptr nocapture %p)414  ret void415}416 417define void @callsite_readonly_nounwind_willreturn(ptr %f, ptr %p) {418; FNATTRS-LABEL: define void @callsite_readonly_nounwind_willreturn419; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr captures(address) [[P:%.*]]) {420; FNATTRS-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR10:[0-9]+]]421; FNATTRS-NEXT:    call void [[F]](ptr captures(none) [[P]])422; FNATTRS-NEXT:    ret void423;424; ATTRIBUTOR-LABEL: define void @callsite_readonly_nounwind_willreturn425; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[F:%.*]], ptr [[P:%.*]]) {426; ATTRIBUTOR-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR8:[0-9]+]]427; ATTRIBUTOR-NEXT:    call void [[F]](ptr captures(none) [[P]])428; ATTRIBUTOR-NEXT:    ret void429;430  call void %f(ptr %p) readonly nounwind willreturn431  call void %f(ptr nocapture %p)432  ret void433}434 435define void @self_readonly_nounwind_not_willreturn(ptr %p) readonly nounwind {436; FNATTRS: Function Attrs: nofree nounwind memory(read)437; FNATTRS-LABEL: define void @self_readonly_nounwind_not_willreturn438; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR9]] {439; FNATTRS-NEXT:    call void @capture(ptr [[P]])440; FNATTRS-NEXT:    ret void441;442; ATTRIBUTOR: Function Attrs: nosync nounwind memory(read)443; ATTRIBUTOR-LABEL: define void @self_readonly_nounwind_not_willreturn444; ATTRIBUTOR-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR7]] {445; ATTRIBUTOR-NEXT:    call void @capture(ptr [[P]])446; ATTRIBUTOR-NEXT:    ret void447;448  call void @capture(ptr %p)449  ret void450}451 452define void @self_readonly_nounwind_willreturn(ptr %p) readonly nounwind willreturn {453; FNATTRS: Function Attrs: mustprogress nofree nounwind willreturn memory(read)454; FNATTRS-LABEL: define void @self_readonly_nounwind_willreturn455; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR11]] {456; FNATTRS-NEXT:    call void @capture(ptr [[P]])457; FNATTRS-NEXT:    ret void458;459; ATTRIBUTOR: Function Attrs: mustprogress nosync nounwind willreturn memory(read)460; ATTRIBUTOR-LABEL: define void @self_readonly_nounwind_willreturn461; ATTRIBUTOR-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR9]] {462; ATTRIBUTOR-NEXT:    call void @capture(ptr [[P]])463; ATTRIBUTOR-NEXT:    ret void464;465  call void @capture(ptr %p)466  ret void467}468 469; It would be acceptable to add readnone to %y1_1 and %y1_2.470define void @test1_1(ptr %x1_1, ptr %y1_1, i1 %c) {471; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)472; FNATTRS-LABEL: define void @test1_1473; FNATTRS-SAME: (ptr readnone captures(none) [[X1_1:%.*]], ptr [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] {474; FNATTRS-NEXT:    [[TMP1:%.*]] = call ptr @test1_2(ptr [[X1_1]], ptr [[Y1_1]], i1 [[C]])475; FNATTRS-NEXT:    store ptr null, ptr @g, align 8476; FNATTRS-NEXT:    ret void477;478; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)479; ATTRIBUTOR-LABEL: define void @test1_1480; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X1_1:%.*]], ptr nofree readnone captures(none) [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] {481; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call ptr @test1_2(ptr nofree readnone captures(none) [[X1_1]], ptr nofree readnone [[Y1_1]], i1 [[C]]) #[[ATTR10]]482; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8483; ATTRIBUTOR-NEXT:    ret void484;485  call ptr @test1_2(ptr %x1_1, ptr %y1_1, i1 %c)486  store ptr null, ptr @g487  ret void488}489 490define ptr @test1_2(ptr %x1_2, ptr %y1_2, i1 %c) {491; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)492; FNATTRS-LABEL: define ptr @test1_2493; FNATTRS-SAME: (ptr readnone captures(none) [[X1_2:%.*]], ptr returned [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {494; FNATTRS-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]495; FNATTRS:       t:496; FNATTRS-NEXT:    call void @test1_1(ptr [[X1_2]], ptr [[Y1_2]], i1 [[C]])497; FNATTRS-NEXT:    store ptr null, ptr @g, align 8498; FNATTRS-NEXT:    br label [[F]]499; FNATTRS:       f:500; FNATTRS-NEXT:    ret ptr [[Y1_2]]501;502; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)503; ATTRIBUTOR-LABEL: define ptr @test1_2504; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X1_2:%.*]], ptr nofree readnone [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] {505; ATTRIBUTOR-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]506; ATTRIBUTOR:       t:507; ATTRIBUTOR-NEXT:    call void @test1_1(ptr nofree readnone captures(none) [[X1_2]], ptr nofree readnone captures(none) [[Y1_2]], i1 [[C]]) #[[ATTR10]]508; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8509; ATTRIBUTOR-NEXT:    br label [[F]]510; ATTRIBUTOR:       f:511; ATTRIBUTOR-NEXT:    ret ptr [[Y1_2]]512;513  br i1 %c, label %t, label %f514t:515  call void @test1_1(ptr %x1_2, ptr %y1_2, i1 %c)516  store ptr null, ptr @g517  br label %f518f:519  ret ptr %y1_2520}521 522define void @test2(ptr %x2) {523; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)524; FNATTRS-LABEL: define void @test2525; FNATTRS-SAME: (ptr readnone captures(none) [[X2:%.*]]) #[[ATTR12]] {526; FNATTRS-NEXT:    call void @test2(ptr [[X2]])527; FNATTRS-NEXT:    store ptr null, ptr @g, align 8528; FNATTRS-NEXT:    ret void529;530; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)531; ATTRIBUTOR-LABEL: define void @test2532; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X2:%.*]]) #[[ATTR10]] {533; ATTRIBUTOR-NEXT:    call void @test2(ptr nofree readnone captures(none) [[X2]]) #[[ATTR10]]534; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8535; ATTRIBUTOR-NEXT:    ret void536;537  call void @test2(ptr %x2)538  store ptr null, ptr @g539  ret void540}541 542define void @test3(ptr %x3, ptr %y3, ptr %z3) {543; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)544; FNATTRS-LABEL: define void @test3545; FNATTRS-SAME: (ptr readnone captures(none) [[X3:%.*]], ptr readnone captures(none) [[Y3:%.*]], ptr readnone captures(none) [[Z3:%.*]]) #[[ATTR12]] {546; FNATTRS-NEXT:    call void @test3(ptr [[Z3]], ptr [[Y3]], ptr [[X3]])547; FNATTRS-NEXT:    store ptr null, ptr @g, align 8548; FNATTRS-NEXT:    ret void549;550; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)551; ATTRIBUTOR-LABEL: define void @test3552; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X3:%.*]], ptr nofree readnone captures(none) [[Y3:%.*]], ptr nofree readnone captures(none) [[Z3:%.*]]) #[[ATTR10]] {553; ATTRIBUTOR-NEXT:    call void @test3(ptr nofree readnone captures(none) [[Z3]], ptr nofree readnone captures(none) [[Y3]], ptr nofree readnone captures(none) [[X3]]) #[[ATTR10]]554; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8555; ATTRIBUTOR-NEXT:    ret void556;557  call void @test3(ptr %z3, ptr %y3, ptr %x3)558  store ptr null, ptr @g559  ret void560}561 562define void @test4_1(ptr %x4_1, i1 %c) {563; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)564; FNATTRS-LABEL: define void @test4_1565; FNATTRS-SAME: (ptr [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {566; FNATTRS-NEXT:    [[TMP1:%.*]] = call ptr @test4_2(ptr [[X4_1]], ptr [[X4_1]], ptr [[X4_1]], i1 [[C]])567; FNATTRS-NEXT:    store ptr null, ptr @g, align 8568; FNATTRS-NEXT:    ret void569;570; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)571; ATTRIBUTOR-LABEL: define void @test4_1572; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR10]] {573; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call ptr @test4_2(ptr nofree readnone captures(none) [[X4_1]], ptr nofree readnone [[X4_1]], ptr nofree readnone captures(none) [[X4_1]], i1 [[C]]) #[[ATTR10]]574; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8575; ATTRIBUTOR-NEXT:    ret void576;577  call ptr @test4_2(ptr %x4_1, ptr %x4_1, ptr %x4_1, i1 %c)578  store ptr null, ptr @g579  ret void580}581 582define ptr @test4_2(ptr %x4_2, ptr %y4_2, ptr %z4_2, i1 %c) {583; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)584; FNATTRS-LABEL: define ptr @test4_2585; FNATTRS-SAME: (ptr readnone captures(none) [[X4_2:%.*]], ptr readnone returned captures(ret: address, provenance) [[Y4_2:%.*]], ptr readnone captures(none) [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {586; FNATTRS-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]587; FNATTRS:       t:588; FNATTRS-NEXT:    call void @test4_1(ptr null, i1 [[C]])589; FNATTRS-NEXT:    store ptr null, ptr @g, align 8590; FNATTRS-NEXT:    br label [[F]]591; FNATTRS:       f:592; FNATTRS-NEXT:    ret ptr [[Y4_2]]593;594; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)595; ATTRIBUTOR-LABEL: define ptr @test4_2596; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[X4_2:%.*]], ptr nofree readnone [[Y4_2:%.*]], ptr nofree readnone captures(none) [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] {597; ATTRIBUTOR-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]598; ATTRIBUTOR:       t:599; ATTRIBUTOR-NEXT:    call void @test4_1(ptr nofree readnone null, i1 [[C]]) #[[ATTR10]]600; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8601; ATTRIBUTOR-NEXT:    br label [[F]]602; ATTRIBUTOR:       f:603; ATTRIBUTOR-NEXT:    ret ptr [[Y4_2]]604;605  br i1 %c, label %t, label %f606t:607  call void @test4_1(ptr null, i1 %c)608  store ptr null, ptr @g609  br label %f610f:611  ret ptr %y4_2612}613 614declare ptr @test5_1(ptr %x5_1)615 616define void @test5_2(ptr %x5_2) {617; COMMON-LABEL: define void @test5_2618; COMMON-SAME: (ptr [[X5_2:%.*]]) {619; COMMON-NEXT:    [[TMP1:%.*]] = call ptr @test5_1(ptr [[X5_2]])620; COMMON-NEXT:    store ptr null, ptr @g, align 8621; COMMON-NEXT:    ret void622;623  call ptr @test5_1(ptr %x5_2)624  store ptr null, ptr @g625  ret void626}627 628declare void @test6_1(ptr %x6_1, ptr nocapture %y6_1, ...)629 630define void @test6_2(ptr %x6_2, ptr %y6_2, ptr %z6_2) {631; FNATTRS-LABEL: define void @test6_2632; FNATTRS-SAME: (ptr [[X6_2:%.*]], ptr captures(none) [[Y6_2:%.*]], ptr [[Z6_2:%.*]]) {633; FNATTRS-NEXT:    call void (ptr, ptr, ...) @test6_1(ptr [[X6_2]], ptr [[Y6_2]], ptr [[Z6_2]])634; FNATTRS-NEXT:    store ptr null, ptr @g, align 8635; FNATTRS-NEXT:    ret void636;637; ATTRIBUTOR-LABEL: define void @test6_2638; ATTRIBUTOR-SAME: (ptr [[X6_2:%.*]], ptr captures(none) [[Y6_2:%.*]], ptr [[Z6_2:%.*]]) {639; ATTRIBUTOR-NEXT:    call void (ptr, ptr, ...) @test6_1(ptr [[X6_2]], ptr captures(none) [[Y6_2]], ptr [[Z6_2]])640; ATTRIBUTOR-NEXT:    store ptr null, ptr @g, align 8641; ATTRIBUTOR-NEXT:    ret void642;643  call void (ptr, ptr, ...) @test6_1(ptr %x6_2, ptr %y6_2, ptr %z6_2)644  store ptr null, ptr @g645  ret void646}647 648define void @test_cmpxchg(ptr %p) {649; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)650; FNATTRS-LABEL: define void @test_cmpxchg651; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR13:[0-9]+]] {652; FNATTRS-NEXT:    [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4653; FNATTRS-NEXT:    ret void654;655; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)656; ATTRIBUTOR-LABEL: define void @test_cmpxchg657; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) #[[ATTR11:[0-9]+]] {658; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4659; ATTRIBUTOR-NEXT:    ret void660;661  cmpxchg ptr %p, i32 0, i32 1 acquire monotonic662  ret void663}664 665define void @test_cmpxchg_ptr(ptr %p, ptr %q) {666; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)667; FNATTRS-LABEL: define void @test_cmpxchg_ptr668; FNATTRS-SAME: (ptr captures(none) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR13]] {669; FNATTRS-NEXT:    [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8670; FNATTRS-NEXT:    ret void671;672; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)673; ATTRIBUTOR-LABEL: define void @test_cmpxchg_ptr674; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR11]] {675; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8676; ATTRIBUTOR-NEXT:    ret void677;678  cmpxchg ptr %p, ptr null, ptr %q acquire monotonic679  ret void680}681 682define void @test_atomicrmw(ptr %p) {683; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)684; FNATTRS-LABEL: define void @test_atomicrmw685; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR13]] {686; FNATTRS-NEXT:    [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4687; FNATTRS-NEXT:    ret void688;689; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)690; ATTRIBUTOR-LABEL: define void @test_atomicrmw691; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) #[[ATTR11]] {692; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4693; ATTRIBUTOR-NEXT:    ret void694;695  atomicrmw add ptr %p, i32 1 seq_cst696  ret void697}698 699define void @test_volatile(ptr %x) {700; FNATTRS: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite)701; FNATTRS-LABEL: define void @test_volatile702; FNATTRS-SAME: (ptr [[X:%.*]]) #[[ATTR14:[0-9]+]] {703; FNATTRS-NEXT:  entry:704; FNATTRS-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[X]], i64 1705; FNATTRS-NEXT:    store volatile i32 0, ptr [[GEP]], align 4706; FNATTRS-NEXT:    ret void707;708; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)709; ATTRIBUTOR-LABEL: define void @test_volatile710; ATTRIBUTOR-SAME: (ptr nofree [[X:%.*]]) #[[ATTR11]] {711; ATTRIBUTOR-NEXT:  entry:712; ATTRIBUTOR-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[X]], i64 1713; ATTRIBUTOR-NEXT:    store volatile i32 0, ptr [[GEP]], align 4714; ATTRIBUTOR-NEXT:    ret void715;716entry:717  %gep = getelementptr i32, ptr %x, i64 1718  store volatile i32 0, ptr %gep, align 4719  ret void720}721 722define void @nocaptureLaunder(ptr %p) {723; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write, inaccessiblemem: readwrite)724; FNATTRS-LABEL: define void @nocaptureLaunder725; FNATTRS-SAME: (ptr writeonly captures(none) [[P:%.*]]) #[[ATTR15:[0-9]+]] {726; FNATTRS-NEXT:  entry:727; FNATTRS-NEXT:    [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]])728; FNATTRS-NEXT:    store i8 42, ptr [[B]], align 1729; FNATTRS-NEXT:    ret void730;731; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)732; ATTRIBUTOR-LABEL: define void @nocaptureLaunder733; ATTRIBUTOR-SAME: (ptr nofree captures(none) [[P:%.*]]) #[[ATTR12:[0-9]+]] {734; ATTRIBUTOR-NEXT:  entry:735; ATTRIBUTOR-NEXT:    [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25:[0-9]+]]736; ATTRIBUTOR-NEXT:    store i8 42, ptr [[B]], align 1737; ATTRIBUTOR-NEXT:    ret void738;739entry:740  %b = call ptr @llvm.launder.invariant.group.p0(ptr %p)741  store i8 42, ptr %b742  ret void743}744 745@g2 = global ptr null746define void @captureLaunder(ptr %p) {747; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: readwrite, target_mem0: none, target_mem1: none)748; FNATTRS-LABEL: define void @captureLaunder749; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR16:[0-9]+]] {750; FNATTRS-NEXT:    [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]])751; FNATTRS-NEXT:    store ptr [[B]], ptr @g2, align 8752; FNATTRS-NEXT:    ret void753;754; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn755; ATTRIBUTOR-LABEL: define void @captureLaunder756; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] {757; ATTRIBUTOR-NEXT:    [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]]) #[[ATTR25]]758; ATTRIBUTOR-NEXT:    store ptr [[B]], ptr @g2, align 8759; ATTRIBUTOR-NEXT:    ret void760;761  %b = call ptr @llvm.launder.invariant.group.p0(ptr %p)762  store ptr %b, ptr @g2763  ret void764}765 766define void @nocaptureStrip(ptr %p) {767; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)768; FNATTRS-LABEL: define void @nocaptureStrip769; FNATTRS-SAME: (ptr writeonly captures(none) [[P:%.*]]) #[[ATTR17:[0-9]+]] {770; FNATTRS-NEXT:  entry:771; FNATTRS-NEXT:    [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]])772; FNATTRS-NEXT:    store i8 42, ptr [[B]], align 1773; FNATTRS-NEXT:    ret void774;775; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)776; ATTRIBUTOR-LABEL: define void @nocaptureStrip777; ATTRIBUTOR-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR13:[0-9]+]] {778; ATTRIBUTOR-NEXT:  entry:779; ATTRIBUTOR-NEXT:    [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]]780; ATTRIBUTOR-NEXT:    store i8 42, ptr [[B]], align 1781; ATTRIBUTOR-NEXT:    ret void782;783entry:784  %b = call ptr @llvm.strip.invariant.group.p0(ptr %p)785  store i8 42, ptr %b786  ret void787}788 789@g3 = global ptr null790define void @captureStrip(ptr %p) {791; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)792; FNATTRS-LABEL: define void @captureStrip793; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR1]] {794; FNATTRS-NEXT:    [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]])795; FNATTRS-NEXT:    store ptr [[B]], ptr @g3, align 8796; FNATTRS-NEXT:    ret void797;798; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)799; ATTRIBUTOR-LABEL: define void @captureStrip800; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] {801; ATTRIBUTOR-NEXT:    [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]]) #[[ATTR22]]802; ATTRIBUTOR-NEXT:    store ptr [[B]], ptr @g3, align 8803; ATTRIBUTOR-NEXT:    ret void804;805  %b = call ptr @llvm.strip.invariant.group.p0(ptr %p)806  store ptr %b, ptr @g3807  ret void808}809 810define i1 @captureICmp(ptr %x) {811; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)812; FNATTRS-LABEL: define i1 @captureICmp813; FNATTRS-SAME: (ptr readnone captures(address_is_null) [[X:%.*]]) #[[ATTR0]] {814; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null815; FNATTRS-NEXT:    ret i1 [[TMP1]]816;817; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)818; ATTRIBUTOR-LABEL: define i1 @captureICmp819; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {820; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null821; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]822;823  %1 = icmp eq ptr %x, null824  ret i1 %1825}826 827define i1 @captureICmpRev(ptr %x) {828; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)829; FNATTRS-LABEL: define i1 @captureICmpRev830; FNATTRS-SAME: (ptr readnone captures(address_is_null) [[X:%.*]]) #[[ATTR0]] {831; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp eq ptr null, [[X]]832; FNATTRS-NEXT:    ret i1 [[TMP1]]833;834; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)835; ATTRIBUTOR-LABEL: define i1 @captureICmpRev836; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {837; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp eq ptr null, [[X]]838; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]839;840  %1 = icmp eq ptr null, %x841  ret i1 %1842}843 844define i1 @captureICmpWrongPred(ptr %x) {845; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)846; FNATTRS-LABEL: define i1 @captureICmpWrongPred847; FNATTRS-SAME: (ptr readnone captures(address) [[X:%.*]]) #[[ATTR0]] {848; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp slt ptr [[X]], null849; FNATTRS-NEXT:    ret i1 [[TMP1]]850;851; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)852; ATTRIBUTOR-LABEL: define i1 @captureICmpWrongPred853; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {854; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp slt ptr [[X]], null855; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]856;857  %1 = icmp slt ptr %x, null858  ret i1 %1859}860 861define i1 @captureICmpWrongPredDereferenceableOrNull(ptr dereferenceable_or_null(1) %x) {862; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)863; FNATTRS-LABEL: define noundef i1 @captureICmpWrongPredDereferenceableOrNull864; FNATTRS-SAME: (ptr readnone captures(address) dereferenceable_or_null(1) [[X:%.*]]) #[[ATTR0]] {865; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp slt ptr [[X]], null866; FNATTRS-NEXT:    ret i1 [[TMP1]]867;868; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)869; ATTRIBUTOR-LABEL: define i1 @captureICmpWrongPredDereferenceableOrNull870; ATTRIBUTOR-SAME: (ptr nofree readnone dereferenceable_or_null(1) [[X:%.*]]) #[[ATTR0]] {871; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp slt ptr [[X]], null872; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]873;874  %1 = icmp slt ptr %x, null875  ret i1 %1876}877 878; We could infer captures(address_is_null) here, but don't bother, because879; InstCombine will optimize the GEP away.880define i1 @nocaptureInboundsGEPICmp(ptr %x) {881; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)882; FNATTRS-LABEL: define i1 @nocaptureInboundsGEPICmp883; FNATTRS-SAME: (ptr readnone captures(address) [[X:%.*]]) #[[ATTR0]] {884; FNATTRS-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[X]], i32 5885; FNATTRS-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null886; FNATTRS-NEXT:    ret i1 [[TMP2]]887;888; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)889; ATTRIBUTOR-LABEL: define i1 @nocaptureInboundsGEPICmp890; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {891; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[X]], i32 5892; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null893; ATTRIBUTOR-NEXT:    ret i1 [[TMP2]]894;895  %1 = getelementptr inbounds i32, ptr %x, i32 5896  %2 = icmp eq ptr %1, null897  ret i1 %2898}899 900define i1 @nocaptureInboundsGEPICmpRev(ptr %x) {901; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)902; FNATTRS-LABEL: define i1 @nocaptureInboundsGEPICmpRev903; FNATTRS-SAME: (ptr readnone captures(address) [[X:%.*]]) #[[ATTR0]] {904; FNATTRS-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[X]], i32 5905; FNATTRS-NEXT:    [[TMP2:%.*]] = icmp eq ptr null, [[TMP1]]906; FNATTRS-NEXT:    ret i1 [[TMP2]]907;908; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)909; ATTRIBUTOR-LABEL: define i1 @nocaptureInboundsGEPICmpRev910; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {911; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[X]], i32 5912; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq ptr null, [[TMP1]]913; ATTRIBUTOR-NEXT:    ret i1 [[TMP2]]914;915  %1 = getelementptr inbounds i32, ptr %x, i32 5916  %2 = icmp eq ptr null, %1917  ret i1 %2918}919 920define i1 @notInboundsGEPICmp(ptr %x) {921; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)922; FNATTRS-LABEL: define i1 @notInboundsGEPICmp923; FNATTRS-SAME: (ptr readnone captures(address) [[X:%.*]]) #[[ATTR0]] {924; FNATTRS-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[X]], i32 5925; FNATTRS-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null926; FNATTRS-NEXT:    ret i1 [[TMP2]]927;928; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)929; ATTRIBUTOR-LABEL: define i1 @notInboundsGEPICmp930; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR0]] {931; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[X]], i32 5932; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null933; ATTRIBUTOR-NEXT:    ret i1 [[TMP2]]934;935  %1 = getelementptr i32, ptr %x, i32 5936  %2 = icmp eq ptr %1, null937  ret i1 %2938}939 940define i1 @inboundsGEPICmpNullPointerDefined(ptr %x) null_pointer_is_valid {941; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none)942; FNATTRS-LABEL: define i1 @inboundsGEPICmpNullPointerDefined943; FNATTRS-SAME: (ptr readnone captures(address) [[X:%.*]]) #[[ATTR18:[0-9]+]] {944; FNATTRS-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[X]], i32 5945; FNATTRS-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null946; FNATTRS-NEXT:    ret i1 [[TMP2]]947;948; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none)949; ATTRIBUTOR-LABEL: define i1 @inboundsGEPICmpNullPointerDefined950; ATTRIBUTOR-SAME: (ptr nofree readnone [[X:%.*]]) #[[ATTR14:[0-9]+]] {951; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[X]], i32 5952; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null953; ATTRIBUTOR-NEXT:    ret i1 [[TMP2]]954;955  %1 = getelementptr i32, ptr %x, i32 5956  %2 = icmp eq ptr %1, null957  ret i1 %2958}959 960define i1 @nocaptureDereferenceableOrNullICmp(ptr dereferenceable_or_null(4) %x) {961; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)962; FNATTRS-LABEL: define noundef i1 @nocaptureDereferenceableOrNullICmp963; FNATTRS-SAME: (ptr readnone captures(address_is_null) dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR0]] {964; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null965; FNATTRS-NEXT:    ret i1 [[TMP1]]966;967; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)968; ATTRIBUTOR-LABEL: define i1 @nocaptureDereferenceableOrNullICmp969; ATTRIBUTOR-SAME: (ptr nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR0]] {970; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null971; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]972;973  %1 = icmp eq ptr %x, null974  ret i1 %1975}976 977define i1 @captureDereferenceableOrNullICmp(ptr dereferenceable_or_null(4) %x) null_pointer_is_valid {978; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none)979; FNATTRS-LABEL: define noundef i1 @captureDereferenceableOrNullICmp980; FNATTRS-SAME: (ptr readnone captures(address_is_null) dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR18]] {981; FNATTRS-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null982; FNATTRS-NEXT:    ret i1 [[TMP1]]983;984; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none)985; ATTRIBUTOR-LABEL: define i1 @captureDereferenceableOrNullICmp986; ATTRIBUTOR-SAME: (ptr nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR14]] {987; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[X]], null988; ATTRIBUTOR-NEXT:    ret i1 [[TMP1]]989;990  %1 = icmp eq ptr %x, null991  ret i1 %1992}993 994declare void @capture(ptr)995 996define void @nocapture_fptr(ptr %f, ptr %p) {997; FNATTRS-LABEL: define void @nocapture_fptr998; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr [[P:%.*]]) {999; FNATTRS-NEXT:    [[RES:%.*]] = call ptr [[F]](ptr [[P]])1000; FNATTRS-NEXT:    call void @capture(ptr [[RES]])1001; FNATTRS-NEXT:    ret void1002;1003; ATTRIBUTOR-LABEL: define void @nocapture_fptr1004; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[F:%.*]], ptr [[P:%.*]]) {1005; ATTRIBUTOR-NEXT:    [[RES:%.*]] = call ptr [[F]](ptr [[P]])1006; ATTRIBUTOR-NEXT:    call void @capture(ptr [[RES]])1007; ATTRIBUTOR-NEXT:    ret void1008;1009  %res = call ptr %f(ptr %p)1010  call void @capture(ptr %res)1011  ret void1012}1013 1014define void @recurse_fptr(ptr %f, ptr %p) {1015; FNATTRS-LABEL: define void @recurse_fptr1016; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr [[P:%.*]]) {1017; FNATTRS-NEXT:    [[RES:%.*]] = call ptr [[F]](ptr [[P]])1018; FNATTRS-NEXT:    store i8 0, ptr [[RES]], align 11019; FNATTRS-NEXT:    ret void1020;1021; ATTRIBUTOR-LABEL: define void @recurse_fptr1022; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[F:%.*]], ptr [[P:%.*]]) {1023; ATTRIBUTOR-NEXT:    [[RES:%.*]] = call ptr [[F]](ptr [[P]])1024; ATTRIBUTOR-NEXT:    store i8 0, ptr [[RES]], align 11025; ATTRIBUTOR-NEXT:    ret void1026;1027  %res = call ptr %f(ptr %p)1028  store i8 0, ptr %res1029  ret void1030}1031 1032define void @readnone_indirec(ptr %f, ptr %p) {1033; FNATTRS: Function Attrs: nofree nosync memory(none)1034; FNATTRS-LABEL: define void @readnone_indirec1035; FNATTRS-SAME: (ptr readonly captures(none) [[F:%.*]], ptr readnone captures(address) [[P:%.*]]) #[[ATTR19:[0-9]+]] {1036; FNATTRS-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR25:[0-9]+]]1037; FNATTRS-NEXT:    ret void1038;1039; ATTRIBUTOR: Function Attrs: nosync memory(none)1040; ATTRIBUTOR-LABEL: define void @readnone_indirec1041; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[F:%.*]], ptr readnone [[P:%.*]]) #[[ATTR15:[0-9]+]] {1042; ATTRIBUTOR-NEXT:    call void [[F]](ptr [[P]]) #[[ATTR26:[0-9]+]]1043; ATTRIBUTOR-NEXT:    ret void1044;1045  call void %f(ptr %p) readnone1046  ret void1047}1048 1049define ptr @captures_ret_only(ptr %p) {1050; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1051; FNATTRS-LABEL: define ptr @captures_ret_only1052; FNATTRS-SAME: (ptr readnone captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0]] {1053; FNATTRS-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 81054; FNATTRS-NEXT:    ret ptr [[GEP]]1055;1056; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1057; ATTRIBUTOR-LABEL: define ptr @captures_ret_only1058; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {1059; ATTRIBUTOR-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 81060; ATTRIBUTOR-NEXT:    ret ptr [[GEP]]1061;1062  %gep = getelementptr i8, ptr %p, i64 81063  ret ptr %gep1064}1065 1066; Even though the ptrtoint is only used in the return value, this should *not*1067; be considered a read-only capture.1068define i64 @captures_not_ret_only(ptr %p) {1069; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1070; FNATTRS-LABEL: define i64 @captures_not_ret_only1071; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {1072; FNATTRS-NEXT:    [[INT:%.*]] = ptrtoint ptr [[P]] to i641073; FNATTRS-NEXT:    ret i64 [[INT]]1074;1075; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1076; ATTRIBUTOR-LABEL: define i64 @captures_not_ret_only1077; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {1078; ATTRIBUTOR-NEXT:    [[INT:%.*]] = ptrtoint ptr [[P]] to i641079; ATTRIBUTOR-NEXT:    ret i64 [[INT]]1080;1081  %int = ptrtoint ptr %p to i641082  ret i64 %int1083}1084 1085@gi = global i64 01086 1087;; Unlike ptrtoint, ptrtoaddr only captures the address1088define i64 @captures_ptrtoaddr_stored(ptr %p) {1089; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)1090; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_stored1091; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR1]] {1092; FNATTRS-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641093; FNATTRS-NEXT:    store i64 [[INT]], ptr @gi, align 81094; FNATTRS-NEXT:    ret i64 01095;1096; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)1097; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_stored1098; ATTRIBUTOR-SAME: (ptr nofree writeonly [[P:%.*]]) #[[ATTR1]] {1099; ATTRIBUTOR-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641100; ATTRIBUTOR-NEXT:    store i64 [[INT]], ptr @gi, align 81101; ATTRIBUTOR-NEXT:    ret i64 01102;1103  %int = ptrtoaddr ptr %p to i641104  store i64 %int, ptr @gi, align 81105  ret i64 01106}1107 1108;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(ret: address) here.1109define i64 @captures_ptrtoaddr_ret(ptr %p) {1110; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1111; FNATTRS-LABEL: define i64 @captures_ptrtoaddr_ret1112; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {1113; FNATTRS-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641114; FNATTRS-NEXT:    ret i64 [[INT]]1115;1116; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1117; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ret1118; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {1119; ATTRIBUTOR-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641120; ATTRIBUTOR-NEXT:    ret i64 [[INT]]1121;1122  %int = ptrtoaddr ptr %p to i641123  ret i64 %int1124}1125 1126;; Note: ptrtoaddr is a location-independent capture, so we don't get captures(none) here.1127define i64 @captures_ptrtoaddr_ignored(ptr %p) {1128; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1129; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_ignored1130; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR0]] {1131; FNATTRS-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641132; FNATTRS-NEXT:    ret i64 01133;1134; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1135; ATTRIBUTOR-LABEL: define i64 @captures_ptrtoaddr_ignored1136; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {1137; ATTRIBUTOR-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i641138; ATTRIBUTOR-NEXT:    ret i64 01139;1140  %int = ptrtoaddr ptr %p to i641141  ret i64 01142}1143 1144define void @captures_read_provenance(ptr %p) {1145; FNATTRS-LABEL: define void @captures_read_provenance1146; FNATTRS-SAME: (ptr captures(address, read_provenance) [[P:%.*]]) {1147; FNATTRS-NEXT:    call void @capture(ptr captures(address, read_provenance) [[P]])1148; FNATTRS-NEXT:    ret void1149;1150; ATTRIBUTOR-LABEL: define void @captures_read_provenance1151; ATTRIBUTOR-SAME: (ptr [[P:%.*]]) {1152; ATTRIBUTOR-NEXT:    call void @capture(ptr captures(address, read_provenance) [[P]])1153; ATTRIBUTOR-NEXT:    ret void1154;1155  call void @capture(ptr captures(address, read_provenance) %p)1156  ret void1157}1158 1159define void @captures_unused_ret(ptr %p) {1160; FNATTRS-LABEL: define void @captures_unused_ret1161; FNATTRS-SAME: (ptr captures(address_is_null) [[P:%.*]]) {1162; FNATTRS-NEXT:    [[TMP1:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])1163; FNATTRS-NEXT:    ret void1164;1165; ATTRIBUTOR-LABEL: define void @captures_unused_ret1166; ATTRIBUTOR-SAME: (ptr [[P:%.*]]) {1167; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])1168; ATTRIBUTOR-NEXT:    ret void1169;1170  call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) %p)1171  ret void1172}1173 1174define ptr @captures_used_ret(ptr %p) {1175; FNATTRS-LABEL: define ptr @captures_used_ret1176; FNATTRS-SAME: (ptr captures(address_is_null, ret: address, provenance) [[P:%.*]]) {1177; FNATTRS-NEXT:    [[RET:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])1178; FNATTRS-NEXT:    ret ptr [[RET]]1179;1180; ATTRIBUTOR-LABEL: define ptr @captures_used_ret1181; ATTRIBUTOR-SAME: (ptr [[P:%.*]]) {1182; ATTRIBUTOR-NEXT:    [[RET:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])1183; ATTRIBUTOR-NEXT:    ret ptr [[RET]]1184;1185  %ret = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) %p)1186  ret ptr %ret1187}1188 1189; Make sure this is does not produce captures(ret: ...). We need to take the1190; return capture components into account when handling argument SCCs.1191define ptr @scc_capture_via_ret(i1 %c, ptr %p) {1192; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)1193; FNATTRS-LABEL: define ptr @scc_capture_via_ret1194; FNATTRS-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) #[[ATTR12]] {1195; FNATTRS-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]1196; FNATTRS:       if:1197; FNATTRS-NEXT:    [[C_NOT:%.*]] = xor i1 [[C]], true1198; FNATTRS-NEXT:    [[RET:%.*]] = call ptr @scc_capture_via_ret(i1 [[C_NOT]], ptr [[P]])1199; FNATTRS-NEXT:    store ptr [[RET]], ptr @g, align 81200; FNATTRS-NEXT:    ret ptr [[RET]]1201; FNATTRS:       else:1202; FNATTRS-NEXT:    ret ptr [[P]]1203;1204; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)1205; ATTRIBUTOR-LABEL: define ptr @scc_capture_via_ret1206; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) #[[ATTR10]] {1207; ATTRIBUTOR-NEXT:    br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]1208; ATTRIBUTOR:       if:1209; ATTRIBUTOR-NEXT:    [[C_NOT:%.*]] = xor i1 [[C]], true1210; ATTRIBUTOR-NEXT:    [[RET:%.*]] = call ptr @scc_capture_via_ret(i1 [[C_NOT]], ptr nofree [[P]]) #[[ATTR10]]1211; ATTRIBUTOR-NEXT:    store ptr [[RET]], ptr @g, align 81212; ATTRIBUTOR-NEXT:    ret ptr [[RET]]1213; ATTRIBUTOR:       else:1214; ATTRIBUTOR-NEXT:    ret ptr [[P]]1215;1216  br i1 %c, label %if, label %else1217if:1218  %c.not = xor i1 %c, true1219  %ret = call ptr @scc_capture_via_ret(i1 %c.not, ptr %p)1220  store ptr %ret, ptr @g1221  ret ptr %ret1222else:1223  ret ptr %p1224}1225 1226define i1 @improve_existing_captures(ptr captures(address) %p) {1227; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1228; FNATTRS-LABEL: define i1 @improve_existing_captures1229; FNATTRS-SAME: (ptr readnone captures(address_is_null) [[P:%.*]]) #[[ATTR0]] {1230; FNATTRS-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], null1231; FNATTRS-NEXT:    ret i1 [[CMP]]1232;1233; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1234; ATTRIBUTOR-LABEL: define i1 @improve_existing_captures1235; ATTRIBUTOR-SAME: (ptr nofree readnone captures(address) [[P:%.*]]) #[[ATTR0]] {1236; ATTRIBUTOR-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], null1237; ATTRIBUTOR-NEXT:    ret i1 [[CMP]]1238;1239  %cmp = icmp eq ptr %p, null1240  ret i1 %cmp1241}1242 1243define void @dont_increase_existing_captures(ptr captures(address) %p) {1244; COMMON-LABEL: define void @dont_increase_existing_captures1245; COMMON-SAME: (ptr captures(address) [[P:%.*]]) {1246; COMMON-NEXT:    call void @capture(ptr [[P]])1247; COMMON-NEXT:    ret void1248;1249  call void @capture(ptr %p)1250  ret void1251}1252 1253define void @dont_increase_existing_captures_trivial_scc(ptr captures(address) %p) {1254; COMMON-LABEL: define void @dont_increase_existing_captures_trivial_scc1255; COMMON-SAME: (ptr captures(address) [[P:%.*]]) {1256; COMMON-NEXT:    call void @capture(ptr captures(address, read_provenance) [[P]])1257; COMMON-NEXT:    call void @dont_increase_existing_captures_trivial_scc(ptr [[P]])1258; COMMON-NEXT:    ret void1259;1260  call void @capture(ptr captures(address, read_provenance) %p)1261  call void @dont_increase_existing_captures_trivial_scc(ptr %p)1262  ret void1263}1264 1265define void @dont_increase_existing_captures_scc1(ptr captures(address) %p) {1266; COMMON-LABEL: define void @dont_increase_existing_captures_scc11267; COMMON-SAME: (ptr captures(address) [[P:%.*]]) {1268; COMMON-NEXT:    call void @dont_increase_existing_captures_scc2(ptr [[P]])1269; COMMON-NEXT:    ret void1270;1271  call void @dont_increase_existing_captures_scc2(ptr %p)1272  ret void1273}1274 1275define void @dont_increase_existing_captures_scc2(ptr %p) {1276; FNATTRS-LABEL: define void @dont_increase_existing_captures_scc21277; FNATTRS-SAME: (ptr captures(address, read_provenance) [[P:%.*]]) {1278; FNATTRS-NEXT:    call void @capture(ptr captures(address, read_provenance) [[P]])1279; FNATTRS-NEXT:    call void @dont_increase_existing_captures_scc1(ptr [[P]])1280; FNATTRS-NEXT:    ret void1281;1282; ATTRIBUTOR-LABEL: define void @dont_increase_existing_captures_scc21283; ATTRIBUTOR-SAME: (ptr [[P:%.*]]) {1284; ATTRIBUTOR-NEXT:    call void @capture(ptr captures(address, read_provenance) [[P]])1285; ATTRIBUTOR-NEXT:    call void @dont_increase_existing_captures_scc1(ptr [[P]])1286; ATTRIBUTOR-NEXT:    ret void1287;1288  call void @capture(ptr captures(address, read_provenance) %p)1289  call void @dont_increase_existing_captures_scc1(ptr %p)1290  ret void1291}1292 1293define void @addr_only_scc(ptr %p) {1294; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem0: none, target_mem1: none)1295; FNATTRS-LABEL: define void @addr_only_scc1296; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20:[0-9]+]] {1297; FNATTRS-NEXT:    [[V:%.*]] = load i8, ptr [[P]], align 11298; FNATTRS-NEXT:    store i8 [[V]], ptr @g, align 11299; FNATTRS-NEXT:    call void @addr_only_scc2(ptr [[P]])1300; FNATTRS-NEXT:    ret void1301;1302; ATTRIBUTOR: Function Attrs: nofree nosync nounwind1303; ATTRIBUTOR-LABEL: define void @addr_only_scc1304; ATTRIBUTOR-SAME: (ptr nofree nonnull [[P:%.*]]) #[[ATTR16:[0-9]+]] {1305; ATTRIBUTOR-NEXT:    [[V:%.*]] = load i8, ptr [[P]], align 11306; ATTRIBUTOR-NEXT:    store i8 [[V]], ptr @g, align 11307; ATTRIBUTOR-NEXT:    call void @addr_only_scc2(ptr nofree nonnull [[P]]) #[[ATTR16]]1308; ATTRIBUTOR-NEXT:    ret void1309;1310  %v = load i8, ptr %p1311  store i8 %v, ptr @g1312  call void @addr_only_scc2(ptr %p)1313  ret void1314}1315 1316define void @addr_only_scc2(ptr %p) {1317; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem0: none, target_mem1: none)1318; FNATTRS-LABEL: define void @addr_only_scc21319; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20]] {1320; FNATTRS-NEXT:    [[CMP:%.*]] = icmp ne ptr [[P]], null1321; FNATTRS-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]1322; FNATTRS:       if:1323; FNATTRS-NEXT:    call void @addr_only_scc(ptr [[P]])1324; FNATTRS-NEXT:    br label [[EXIT]]1325; FNATTRS:       exit:1326; FNATTRS-NEXT:    ret void1327;1328; ATTRIBUTOR: Function Attrs: nofree nosync nounwind1329; ATTRIBUTOR-LABEL: define void @addr_only_scc21330; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]]) #[[ATTR16]] {1331; ATTRIBUTOR-NEXT:    [[CMP:%.*]] = icmp ne ptr [[P]], null1332; ATTRIBUTOR-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]1333; ATTRIBUTOR:       if:1334; ATTRIBUTOR-NEXT:    call void @addr_only_scc(ptr nofree [[P]]) #[[ATTR16]]1335; ATTRIBUTOR-NEXT:    br label [[EXIT]]1336; ATTRIBUTOR:       exit:1337; ATTRIBUTOR-NEXT:    ret void1338;1339  %cmp = icmp ne ptr %p, null1340  br i1 %cmp, label %if, label %exit1341 1342if:1343  call void @addr_only_scc(ptr %p)1344  br label %exit1345 1346exit:1347  ret void1348}1349 1350define void @assume_align(ptr %p) {1351; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1352; FNATTRS-LABEL: define void @assume_align1353; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21:[0-9]+]] {1354; FNATTRS-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]1355; FNATTRS-NEXT:    ret void1356;1357; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1358; ATTRIBUTOR-LABEL: define void @assume_align1359; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[P:%.*]]) #[[ATTR17:[0-9]+]] {1360; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) #[[ATTR27:[0-9]+]] [ "align"(ptr [[P]], i64 8) ]1361; ATTRIBUTOR-NEXT:    ret void1362;1363  call void @llvm.assume(i1 true) ["align"(ptr %p, i64 8)]1364  ret void1365}1366 1367define void @assume_dereferenceable(ptr %p) {1368; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1369; FNATTRS-LABEL: define void @assume_dereferenceable1370; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] {1371; FNATTRS-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8) ]1372; FNATTRS-NEXT:    ret void1373;1374; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1375; ATTRIBUTOR-LABEL: define void @assume_dereferenceable1376; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] {1377; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) #[[ATTR27]] [ "dereferenceable"(ptr [[P]], i64 8) ]1378; ATTRIBUTOR-NEXT:    ret void1379;1380  call void @llvm.assume(i1 true) ["dereferenceable"(ptr %p, i64 8)]1381  ret void1382}1383 1384define void @assume_nonnull(ptr %p) {1385; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1386; FNATTRS-LABEL: define void @assume_nonnull1387; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR21]] {1388; FNATTRS-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ]1389; FNATTRS-NEXT:    ret void1390;1391; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)1392; ATTRIBUTOR-LABEL: define void @assume_nonnull1393; ATTRIBUTOR-SAME: (ptr nofree nonnull readnone captures(none) [[P:%.*]]) #[[ATTR17]] {1394; ATTRIBUTOR-NEXT:    call void @llvm.assume(i1 true) #[[ATTR27]] [ "nonnull"(ptr [[P]]) ]1395; ATTRIBUTOR-NEXT:    ret void1396;1397  call void @llvm.assume(i1 true) ["nonnull"(ptr %p)]1398  ret void1399}1400 1401define void @captures_metadata_address_is_null(ptr %x, ptr %y) {1402; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1403; FNATTRS-LABEL: define void @captures_metadata_address_is_null1404; FNATTRS-SAME: (ptr captures(address_is_null) [[X:%.*]], ptr writeonly captures(none) initializes((0, 8)) [[Y:%.*]]) #[[ATTR17]] {1405; FNATTRS-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META0:![0-9]+]]1406; FNATTRS-NEXT:    ret void1407;1408; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1409; ATTRIBUTOR-LABEL: define void @captures_metadata_address_is_null1410; ATTRIBUTOR-SAME: (ptr nofree writeonly [[X:%.*]], ptr nofree nonnull writeonly captures(none) [[Y:%.*]]) #[[ATTR13]] {1411; ATTRIBUTOR-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META0:![0-9]+]]1412; ATTRIBUTOR-NEXT:    ret void1413;1414  store ptr %x, ptr %y, !captures !{!"address_is_null"}1415  ret void1416}1417 1418define void @captures_metadata_address(ptr %x, ptr %y) {1419; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1420; FNATTRS-LABEL: define void @captures_metadata_address1421; FNATTRS-SAME: (ptr captures(address) [[X:%.*]], ptr writeonly captures(none) initializes((0, 8)) [[Y:%.*]]) #[[ATTR17]] {1422; FNATTRS-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META1:![0-9]+]]1423; FNATTRS-NEXT:    ret void1424;1425; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1426; ATTRIBUTOR-LABEL: define void @captures_metadata_address1427; ATTRIBUTOR-SAME: (ptr nofree writeonly [[X:%.*]], ptr nofree nonnull writeonly captures(none) [[Y:%.*]]) #[[ATTR13]] {1428; ATTRIBUTOR-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META1:![0-9]+]]1429; ATTRIBUTOR-NEXT:    ret void1430;1431  store ptr %x, ptr %y, !captures !{!"address"}1432  ret void1433}1434 1435define void @captures_metadata_address_read_provenance(ptr %x, ptr %y) {1436; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1437; FNATTRS-LABEL: define void @captures_metadata_address_read_provenance1438; FNATTRS-SAME: (ptr captures(address, read_provenance) [[X:%.*]], ptr writeonly captures(none) initializes((0, 8)) [[Y:%.*]]) #[[ATTR17]] {1439; FNATTRS-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META2:![0-9]+]]1440; FNATTRS-NEXT:    ret void1441;1442; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1443; ATTRIBUTOR-LABEL: define void @captures_metadata_address_read_provenance1444; ATTRIBUTOR-SAME: (ptr nofree writeonly [[X:%.*]], ptr nofree nonnull writeonly captures(none) [[Y:%.*]]) #[[ATTR13]] {1445; ATTRIBUTOR-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META2:![0-9]+]]1446; ATTRIBUTOR-NEXT:    ret void1447;1448  store ptr %x, ptr %y, !captures !{!"address", !"read_provenance"}1449  ret void1450}1451 1452define void @captures_metadata_provenance(ptr %x, ptr %y) {1453; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1454; FNATTRS-LABEL: define void @captures_metadata_provenance1455; FNATTRS-SAME: (ptr captures(provenance) [[X:%.*]], ptr writeonly captures(none) initializes((0, 8)) [[Y:%.*]]) #[[ATTR17]] {1456; FNATTRS-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META3:![0-9]+]]1457; FNATTRS-NEXT:    ret void1458;1459; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)1460; ATTRIBUTOR-LABEL: define void @captures_metadata_provenance1461; ATTRIBUTOR-SAME: (ptr nofree writeonly [[X:%.*]], ptr nofree nonnull writeonly captures(none) [[Y:%.*]]) #[[ATTR13]] {1462; ATTRIBUTOR-NEXT:    store ptr [[X]], ptr [[Y]], align 8, !captures [[META3:![0-9]+]]1463; ATTRIBUTOR-NEXT:    ret void1464;1465  store ptr %x, ptr %y, !captures !{!"provenance"}1466  ret void1467}1468 1469declare ptr @llvm.launder.invariant.group.p0(ptr)1470declare ptr @llvm.strip.invariant.group.p0(ptr)1471