@@ -900,6 +900,104 @@ define void @readnone_indirec(ptr %f, ptr %p) {
900900 ret void
901901}
902902
903+ define ptr @captures_ret_only (ptr %p ) {
904+ ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
905+ ; FNATTRS-LABEL: define ptr @captures_ret_only
906+ ; FNATTRS-SAME: (ptr readnone [[P:%.*]]) #[[ATTR0]] {
907+ ; FNATTRS-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8
908+ ; FNATTRS-NEXT: ret ptr [[GEP]]
909+ ;
910+ ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
911+ ; ATTRIBUTOR-LABEL: define ptr @captures_ret_only
912+ ; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
913+ ; ATTRIBUTOR-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8
914+ ; ATTRIBUTOR-NEXT: ret ptr [[GEP]]
915+ ;
916+ %gep = getelementptr i8 , ptr %p , i64 8
917+ ret ptr %gep
918+ }
919+
920+ define i64 @captures_not_ret_only (ptr %p ) {
921+ ; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
922+ ; FNATTRS-LABEL: define i64 @captures_not_ret_only
923+ ; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR0]] {
924+ ; FNATTRS-NEXT: [[INT:%.*]] = ptrtoint ptr [[P]] to i64
925+ ; FNATTRS-NEXT: ret i64 [[INT]]
926+ ;
927+ ; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
928+ ; ATTRIBUTOR-LABEL: define i64 @captures_not_ret_only
929+ ; ATTRIBUTOR-SAME: (ptr nofree readnone [[P:%.*]]) #[[ATTR0]] {
930+ ; ATTRIBUTOR-NEXT: [[INT:%.*]] = ptrtoint ptr [[P]] to i64
931+ ; ATTRIBUTOR-NEXT: ret i64 [[INT]]
932+ ;
933+ %int = ptrtoint ptr %p to i64
934+ ret i64 %int
935+ }
936+
937+ define void @captures_read_provenance (ptr %p ) {
938+ ; COMMON-LABEL: define void @captures_read_provenance
939+ ; COMMON-SAME: (ptr [[P:%.*]]) {
940+ ; COMMON-NEXT: call void @capture(ptr captures(address, read_provenance) [[P]])
941+ ; COMMON-NEXT: ret void
942+ ;
943+ call void @capture (ptr captures(address, read_provenance) %p )
944+ ret void
945+ }
946+
947+ define void @captures_unused_ret (ptr %p ) {
948+ ; COMMON-LABEL: define void @captures_unused_ret
949+ ; COMMON-SAME: (ptr [[P:%.*]]) {
950+ ; COMMON-NEXT: [[TMP1:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])
951+ ; COMMON-NEXT: ret void
952+ ;
953+ call ptr @capture (ptr captures(address_is_null, ret: address, read_provenance) %p )
954+ ret void
955+ }
956+
957+ define ptr @captures_used_ret (ptr %p ) {
958+ ; COMMON-LABEL: define ptr @captures_used_ret
959+ ; COMMON-SAME: (ptr [[P:%.*]]) {
960+ ; COMMON-NEXT: [[RET:%.*]] = call ptr @capture(ptr captures(address_is_null, ret: address, read_provenance) [[P]])
961+ ; COMMON-NEXT: ret ptr [[RET]]
962+ ;
963+ %ret = call ptr @capture (ptr captures(address_is_null, ret: address, read_provenance) %p )
964+ ret ptr %ret
965+ }
966+
967+ define ptr @scc_capture_via_ret (i1 %c , ptr %p ) {
968+ ; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
969+ ; FNATTRS-LABEL: define ptr @scc_capture_via_ret
970+ ; FNATTRS-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) #[[ATTR10]] {
971+ ; FNATTRS-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
972+ ; FNATTRS: if:
973+ ; FNATTRS-NEXT: [[C_NOT:%.*]] = xor i1 [[C]], true
974+ ; FNATTRS-NEXT: [[RET:%.*]] = call ptr @scc_capture_via_ret(i1 [[C_NOT]], ptr [[P]])
975+ ; FNATTRS-NEXT: store ptr [[RET]], ptr @g, align 8
976+ ; FNATTRS-NEXT: ret ptr [[RET]]
977+ ; FNATTRS: else:
978+ ; FNATTRS-NEXT: ret ptr [[P]]
979+ ;
980+ ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(write)
981+ ; ATTRIBUTOR-LABEL: define ptr @scc_capture_via_ret
982+ ; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) #[[ATTR8]] {
983+ ; ATTRIBUTOR-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
984+ ; ATTRIBUTOR: if:
985+ ; ATTRIBUTOR-NEXT: [[C_NOT:%.*]] = xor i1 [[C]], true
986+ ; ATTRIBUTOR-NEXT: [[RET:%.*]] = call ptr @scc_capture_via_ret(i1 [[C_NOT]], ptr nofree [[P]]) #[[ATTR8]]
987+ ; ATTRIBUTOR-NEXT: store ptr [[RET]], ptr @g, align 8
988+ ; ATTRIBUTOR-NEXT: ret ptr [[RET]]
989+ ; ATTRIBUTOR: else:
990+ ; ATTRIBUTOR-NEXT: ret ptr [[P]]
991+ ;
992+ br i1 %c , label %if , label %else
993+ if:
994+ %c.not = xor i1 %c , true
995+ %ret = call ptr @scc_capture_via_ret (i1 %c.not , ptr %p )
996+ store ptr %ret , ptr @g
997+ ret ptr %ret
998+ else:
999+ ret ptr %p
1000+ }
9031001
9041002declare ptr @llvm.launder.invariant.group.p0 (ptr )
9051003declare ptr @llvm.strip.invariant.group.p0 (ptr )
0 commit comments