brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.3 KiB · 193d0fd Raw
666 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 42; RUN: opt -passes=function-attrs -S < %s | FileCheck %s3 4define void @basic(ptr %p) {5; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)6; CHECK-LABEL: define void @basic(7; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8)) [[P:%.*]]) #[[ATTR0:[0-9]+]] {8; CHECK-NEXT:    store i64 123, ptr [[P]], align 49; CHECK-NEXT:    ret void10;11  store i64 123, ptr %p12  ret void13}14 15define void @stores_on_both_paths(ptr %p, i1 %i) {16; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)17; CHECK-LABEL: define void @stores_on_both_paths(18; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8)) [[P:%.*]], i1 [[I:%.*]]) #[[ATTR0]] {19; CHECK-NEXT:  entry:20; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]21; CHECK:       bb1:22; CHECK-NEXT:    store i64 123, ptr [[P]], align 423; CHECK-NEXT:    br label [[END:%.*]]24; CHECK:       bb2:25; CHECK-NEXT:    store i64 321, ptr [[P]], align 426; CHECK-NEXT:    br label [[END]]27; CHECK:       end:28; CHECK-NEXT:    ret void29;30entry:31  br i1 %i, label %bb1, label %bb232bb1:33  store i64 123, ptr %p34  br label %end35bb2:36  store i64 321, ptr %p37  br label %end38end:39  ret void40}41 42define void @store_pointer_to_pointer(ptr %p, ptr %p2) {43; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)44; CHECK-LABEL: define void @store_pointer_to_pointer(45; CHECK-SAME: ptr [[P:%.*]], ptr writeonly captures(none) initializes((0, 8)) [[P2:%.*]]) #[[ATTR0]] {46; CHECK-NEXT:    store ptr [[P]], ptr [[P2]], align 847; CHECK-NEXT:    ret void48;49  store ptr %p, ptr %p250  ret void51}52 53; TODO: this is still initializes54define void @store_pointer_to_itself(ptr %p) {55; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)56; CHECK-LABEL: define void @store_pointer_to_itself(57; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {58; CHECK-NEXT:    store ptr [[P]], ptr [[P]], align 859; CHECK-NEXT:    ret void60;61  store ptr %p, ptr %p62  ret void63}64 65define void @load_before_store(ptr %p) {66; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)67; CHECK-LABEL: define void @load_before_store(68; CHECK-SAME: ptr captures(none) [[P:%.*]]) #[[ATTR1:[0-9]+]] {69; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 470; CHECK-NEXT:    store i32 123, ptr [[P]], align 471; CHECK-NEXT:    ret void72;73  %a = load i32, ptr %p74  store i32 123, ptr %p75  ret void76}77 78define void @partial_load_before_store(ptr %p) {79; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)80; CHECK-LABEL: define void @partial_load_before_store(81; CHECK-SAME: ptr captures(none) initializes((4, 8)) [[P:%.*]]) #[[ATTR1]] {82; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 483; CHECK-NEXT:    store i64 123, ptr [[P]], align 484; CHECK-NEXT:    ret void85;86  %a = load i32, ptr %p87  store i64 123, ptr %p88  ret void89}90 91declare void @use(ptr)92 93define void @call_clobber(ptr %p) {94; CHECK-LABEL: define void @call_clobber(95; CHECK-SAME: ptr [[P:%.*]]) {96; CHECK-NEXT:    call void @use(ptr [[P]])97; CHECK-NEXT:    store i64 123, ptr [[P]], align 498; CHECK-NEXT:    ret void99;100  call void @use(ptr %p)101  store i64 123, ptr %p102  ret void103}104 105define void @call_clobber_after_store(ptr %p) {106; CHECK-LABEL: define void @call_clobber_after_store(107; CHECK-SAME: ptr initializes((0, 8)) [[P:%.*]]) {108; CHECK-NEXT:    store i64 123, ptr [[P]], align 4109; CHECK-NEXT:    call void @use(ptr [[P]])110; CHECK-NEXT:    ret void111;112  store i64 123, ptr %p113  call void @use(ptr %p)114  ret void115}116 117define void @store_offset(ptr %p) {118; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)119; CHECK-LABEL: define void @store_offset(120; CHECK-SAME: ptr writeonly captures(none) initializes((8, 12)) [[P:%.*]]) #[[ATTR0]] {121; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 8122; CHECK-NEXT:    store i32 123, ptr [[G]], align 4123; CHECK-NEXT:    ret void124;125  %g = getelementptr i8, ptr %p, i64 8126  store i32 123, ptr %g127  ret void128}129 130define void @store_volatile(ptr %p) {131; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite)132; CHECK-LABEL: define void @store_volatile(133; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR2:[0-9]+]] {134; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 8135; CHECK-NEXT:    store volatile i32 123, ptr [[G]], align 4136; CHECK-NEXT:    ret void137;138  %g = getelementptr i8, ptr %p, i64 8139  store volatile i32 123, ptr %g140  ret void141}142 143define void @merge_store_ranges(ptr %p) {144; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)145; CHECK-LABEL: define void @merge_store_ranges(146; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8)) [[P:%.*]]) #[[ATTR0]] {147; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 4148; CHECK-NEXT:    store i32 123, ptr [[G]], align 4149; CHECK-NEXT:    store i32 123, ptr [[P]], align 4150; CHECK-NEXT:    ret void151;152  %g = getelementptr i8, ptr %p, i64 4153  store i32 123, ptr %g154  store i32 123, ptr %p155  ret void156}157 158define void @partially_overlapping_stores_branches(ptr %p, i1 %i) {159; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)160; CHECK-LABEL: define void @partially_overlapping_stores_branches(161; CHECK-SAME: ptr captures(none) initializes((4, 8)) [[P:%.*]], i1 [[I:%.*]]) #[[ATTR1]] {162; CHECK-NEXT:  entry:163; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P]], align 4164; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 4165; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]166; CHECK:       bb1:167; CHECK-NEXT:    store i64 123, ptr [[G]], align 4168; CHECK-NEXT:    br label [[END:%.*]]169; CHECK:       bb2:170; CHECK-NEXT:    store i64 321, ptr [[P]], align 4171; CHECK-NEXT:    br label [[END]]172; CHECK:       end:173; CHECK-NEXT:    ret void174;175entry:176  %a = load i32, ptr %p177  %g = getelementptr i8, ptr %p, i64 4178  br i1 %i, label %bb1, label %bb2179bb1:180  store i64 123, ptr %g181  br label %end182bb2:183  store i64 321, ptr %p184  br label %end185end:186  ret void187}188 189define void @non_overlapping_stores_branches(ptr %p, i1 %i) {190; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)191; CHECK-LABEL: define void @non_overlapping_stores_branches(192; CHECK-SAME: ptr writeonly captures(none) [[P:%.*]], i1 [[I:%.*]]) #[[ATTR0]] {193; CHECK-NEXT:  entry:194; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 8195; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]196; CHECK:       bb1:197; CHECK-NEXT:    store i64 123, ptr [[G]], align 4198; CHECK-NEXT:    br label [[END:%.*]]199; CHECK:       bb2:200; CHECK-NEXT:    store i64 321, ptr [[P]], align 4201; CHECK-NEXT:    br label [[END]]202; CHECK:       end:203; CHECK-NEXT:    ret void204;205entry:206  %g = getelementptr i8, ptr %p, i64 8207  br i1 %i, label %bb1, label %bb2208bb1:209  store i64 123, ptr %g210  br label %end211bb2:212  store i64 321, ptr %p213  br label %end214end:215  ret void216}217 218define void @dominating_store(ptr %p, i1 %i) {219; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)220; CHECK-LABEL: define void @dominating_store(221; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8)) [[P:%.*]], i1 [[I:%.*]]) #[[ATTR0]] {222; CHECK-NEXT:  entry:223; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]224; CHECK:       bb1:225; CHECK-NEXT:    br label [[END:%.*]]226; CHECK:       bb2:227; CHECK-NEXT:    br label [[END]]228; CHECK:       end:229; CHECK-NEXT:    store i64 321, ptr [[P]], align 4230; CHECK-NEXT:    ret void231;232entry:233  br i1 %i, label %bb1, label %bb2234bb1:235  br label %end236bb2:237  br label %end238end:239  store i64 321, ptr %p240  ret void241}242 243define void @call_clobber_on_one_branch(ptr %p, i1 %i) {244; CHECK-LABEL: define void @call_clobber_on_one_branch(245; CHECK-SAME: ptr [[P:%.*]], i1 [[I:%.*]]) {246; CHECK-NEXT:  entry:247; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]248; CHECK:       bb1:249; CHECK-NEXT:    br label [[END:%.*]]250; CHECK:       bb2:251; CHECK-NEXT:    call void @use(ptr [[P]])252; CHECK-NEXT:    br label [[END]]253; CHECK:       end:254; CHECK-NEXT:    store i64 321, ptr [[P]], align 4255; CHECK-NEXT:    ret void256;257entry:258  br i1 %i, label %bb1, label %bb2259bb1:260  br label %end261bb2:262  call void @use(ptr %p)263  br label %end264end:265  store i64 321, ptr %p266  ret void267}268 269define void @merge_existing_initializes(ptr initializes((33, 36)) %p) {270; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)271; CHECK-LABEL: define void @merge_existing_initializes(272; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8), (33, 36)) [[P:%.*]]) #[[ATTR0]] {273; CHECK-NEXT:    store i64 123, ptr [[P]], align 4274; CHECK-NEXT:    ret void275;276  store i64 123, ptr %p277  ret void278}279 280define void @negative_offset(ptr %p) {281; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)282; CHECK-LABEL: define void @negative_offset(283; CHECK-SAME: ptr writeonly captures(none) initializes((-5, 3)) [[P:%.*]]) #[[ATTR0]] {284; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 -5285; CHECK-NEXT:    store i64 123, ptr [[G]], align 4286; CHECK-NEXT:    ret void287;288  %g = getelementptr i8, ptr %p, i64 -5289  store i64 123, ptr %g290  ret void291}292 293define void @non_const_gep(ptr %p, i64 %i) {294; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)295; CHECK-LABEL: define void @non_const_gep(296; CHECK-SAME: ptr writeonly captures(none) initializes((0, 8)) [[P:%.*]], i64 [[I:%.*]]) #[[ATTR0]] {297; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]]298; CHECK-NEXT:    store i64 123, ptr [[G]], align 4299; CHECK-NEXT:    store i64 123, ptr [[P]], align 4300; CHECK-NEXT:    ret void301;302  %g = getelementptr i8, ptr %p, i64 %i303  store i64 123, ptr %g304  store i64 123, ptr %p305  ret void306}307 308define void @call_clobber_in_entry_block(ptr %p, i1 %i) {309; CHECK-LABEL: define void @call_clobber_in_entry_block(310; CHECK-SAME: ptr [[P:%.*]], i1 [[I:%.*]]) {311; CHECK-NEXT:  entry:312; CHECK-NEXT:    call void @use(ptr [[P]])313; CHECK-NEXT:    br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]]314; CHECK:       bb1:315; CHECK-NEXT:    store i64 123, ptr [[P]], align 4316; CHECK-NEXT:    br label [[END:%.*]]317; CHECK:       bb2:318; CHECK-NEXT:    store i64 321, ptr [[P]], align 4319; CHECK-NEXT:    br label [[END]]320; CHECK:       end:321; CHECK-NEXT:    ret void322;323entry:324  call void @use(ptr %p)325  br i1 %i, label %bb1, label %bb2326bb1:327  store i64 123, ptr %p328  br label %end329bb2:330  store i64 321, ptr %p331  br label %end332end:333  ret void334}335 336declare void @g1(ptr initializes((0, 4)) %p)337declare void @g2(ptr initializes((8, 12)) %p)338declare void @g3(ptr initializes((0, 4)) writeonly nocapture %p)339 340define void @call_initializes(ptr %p) {341; CHECK-LABEL: define void @call_initializes(342; CHECK-SAME: ptr initializes((0, 4)) [[P:%.*]]) {343; CHECK-NEXT:    call void @g1(ptr [[P]])344; CHECK-NEXT:    ret void345;346  call void @g1(ptr %p)347  ret void348}349 350define void @call_initializes_clobber(ptr %p) {351; CHECK-LABEL: define void @call_initializes_clobber(352; CHECK-SAME: ptr initializes((0, 4)) [[P:%.*]]) {353; CHECK-NEXT:    call void @g1(ptr [[P]])354; CHECK-NEXT:    call void @g2(ptr [[P]])355; CHECK-NEXT:    ret void356;357  call void @g1(ptr %p)358  call void @g2(ptr %p)359  ret void360}361 362define void @call_initializes_no_clobber_writeonly_nocapture(ptr %p) {363; CHECK-LABEL: define void @call_initializes_no_clobber_writeonly_nocapture(364; CHECK-SAME: ptr initializes((0, 4), (8, 12)) [[P:%.*]]) {365; CHECK-NEXT:    call void @g3(ptr [[P]])366; CHECK-NEXT:    call void @g2(ptr [[P]])367; CHECK-NEXT:    ret void368;369  call void @g3(ptr %p)370  call void @g2(ptr %p)371  ret void372}373 374define void @call_initializes_escape_bundle(ptr %p) {375; CHECK-LABEL: define void @call_initializes_escape_bundle(376; CHECK-SAME: ptr [[P:%.*]]) {377; CHECK-NEXT:    call void @g1(ptr [[P]]) [ "unknown"(ptr [[P]]) ]378; CHECK-NEXT:    ret void379;380  call void @g1(ptr %p) ["unknown"(ptr %p)]381  ret void382}383 384define void @access_bundle() {385; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)386; CHECK-LABEL: define void @access_bundle(387; CHECK-SAME: ) #[[ATTR3:[0-9]+]] {388; CHECK-NEXT:    [[SINK:%.*]] = alloca i64, align 8389; CHECK-NEXT:    store i64 123, ptr [[SINK]], align 4390; CHECK-NEXT:    ret void391;392  %sink = alloca i64, align 8393  store i64 123, ptr %sink394  ret void395}396 397define void @call_operand_bundle(ptr %p) {398; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn399; CHECK-LABEL: define void @call_operand_bundle(400; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] {401; CHECK-NEXT:    call void @access_bundle() [ "unknown"(ptr [[P]]) ]402; CHECK-NEXT:    ret void403;404  call void @access_bundle() ["unknown"(ptr %p)]405  ret void406}407 408declare void @llvm.memset(ptr, i8, i64 ,i1)409 410define void @memset(ptr %p) {411; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)412; CHECK-LABEL: define void @memset(413; CHECK-SAME: ptr writeonly captures(none) initializes((0, 9)) [[P:%.*]]) #[[ATTR0]] {414; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 9, i1 false)415; CHECK-NEXT:    ret void416;417  call void @llvm.memset(ptr %p, i8 2, i64 9, i1 false)418  ret void419}420 421define void @memset_offset(ptr %p) {422; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)423; CHECK-LABEL: define void @memset_offset(424; CHECK-SAME: ptr writeonly captures(none) initializes((3, 12)) [[P:%.*]]) #[[ATTR0]] {425; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 3426; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[G]], i8 2, i64 9, i1 false)427; CHECK-NEXT:    ret void428;429  %g = getelementptr i8, ptr %p, i64 3430  call void @llvm.memset(ptr %g, i8 2, i64 9, i1 false)431  ret void432}433 434define void @memset_neg(ptr %p) {435; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)436; CHECK-LABEL: define void @memset_neg(437; CHECK-SAME: ptr writeonly captures(none) [[P:%.*]]) #[[ATTR0]] {438; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 -1, i1 false)439; CHECK-NEXT:    ret void440;441  call void @llvm.memset(ptr %p, i8 2, i64 -1, i1 false)442  ret void443}444 445define void @memset_volatile(ptr %p) {446; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write, inaccessiblemem: readwrite)447; CHECK-LABEL: define void @memset_volatile(448; CHECK-SAME: ptr writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] {449; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 9, i1 true)450; CHECK-NEXT:    ret void451;452  call void @llvm.memset(ptr %p, i8 2, i64 9, i1 true)453  ret void454}455 456define void @memset_non_constant(ptr %p, i64 %i) {457; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)458; CHECK-LABEL: define void @memset_non_constant(459; CHECK-SAME: ptr writeonly captures(none) [[P:%.*]], i64 [[I:%.*]]) #[[ATTR0]] {460; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 [[I]], i1 false)461; CHECK-NEXT:    ret void462;463  call void @llvm.memset(ptr %p, i8 2, i64 %i, i1 false)464  ret void465}466 467declare void @llvm.memcpy(ptr, ptr, i64 ,i1)468 469define void @memcpy(ptr %p, ptr %p2) {470; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)471; CHECK-LABEL: define void @memcpy(472; CHECK-SAME: ptr writeonly captures(none) initializes((0, 9)) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR1]] {473; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 false)474; CHECK-NEXT:    ret void475;476  call void @llvm.memcpy(ptr %p, ptr %p2, i64 9, i1 false)477  ret void478}479 480define void @memcpy_volatile(ptr %p, ptr %p2) {481; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)482; CHECK-LABEL: define void @memcpy_volatile(483; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6:[0-9]+]] {484; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true)485; CHECK-NEXT:    ret void486;487  call void @llvm.memcpy(ptr %p, ptr %p2, i64 9, i1 true)488  ret void489}490 491define void @memcpy_offset(ptr %p, ptr %p2) {492; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)493; CHECK-LABEL: define void @memcpy_offset(494; CHECK-SAME: ptr writeonly captures(none) initializes((3, 12)) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR1]] {495; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 3496; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[G]], ptr [[P2]], i64 9, i1 false)497; CHECK-NEXT:    ret void498;499  %g = getelementptr i8, ptr %p, i64 3500  call void @llvm.memcpy(ptr %g, ptr %p2, i64 9, i1 false)501  ret void502}503 504define void @memcpy_src(ptr %p, ptr %p2) {505; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)506; CHECK-LABEL: define void @memcpy_src(507; CHECK-SAME: ptr captures(none) initializes((96, 128)) [[P:%.*]], ptr captures(none) initializes((0, 96)) [[P2:%.*]]) #[[ATTR1]] {508; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[P2]], ptr [[P]], i64 96, i1 false)509; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 64510; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[G]], ptr [[P2]], i64 64, i1 false)511; CHECK-NEXT:    ret void512;513  call void @llvm.memcpy(ptr %p2, ptr %p, i64 96, i1 false)514  %g = getelementptr i8, ptr %p, i64 64515  call void @llvm.memcpy(ptr %g, ptr %p2, i64 64, i1 false)516  ret void517}518 519define void @memcpy_non_constant(ptr %p, ptr %p2, i64 %i) {520; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)521; CHECK-LABEL: define void @memcpy_non_constant(522; CHECK-SAME: ptr writeonly captures(none) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]], i64 [[I:%.*]]) #[[ATTR1]] {523; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 [[I]], i1 false)524; CHECK-NEXT:    ret void525;526  call void @llvm.memcpy(ptr %p, ptr %p2, i64 %i, i1 false)527  ret void528}529 530declare void @llvm.memmove(ptr, ptr, i64 ,i1)531 532define void @memmove(ptr %p, ptr %p2) {533; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)534; CHECK-LABEL: define void @memmove(535; CHECK-SAME: ptr writeonly captures(none) initializes((0, 9)) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR1]] {536; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 false)537; CHECK-NEXT:    ret void538;539  call void @llvm.memmove(ptr %p, ptr %p2, i64 9, i1 false)540  ret void541}542 543define void @memmove_volatile(ptr %p, ptr %p2) {544; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)545; CHECK-LABEL: define void @memmove_volatile(546; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6]] {547; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true)548; CHECK-NEXT:    ret void549;550  call void @llvm.memmove(ptr %p, ptr %p2, i64 9, i1 true)551  ret void552}553 554define void @memmove_offset(ptr %p, ptr %p2) {555; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)556; CHECK-LABEL: define void @memmove_offset(557; CHECK-SAME: ptr writeonly captures(none) initializes((3, 12)) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR1]] {558; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 3559; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[G]], ptr [[P2]], i64 9, i1 false)560; CHECK-NEXT:    ret void561;562  %g = getelementptr i8, ptr %p, i64 3563  call void @llvm.memmove(ptr %g, ptr %p2, i64 9, i1 false)564  ret void565}566 567define void @memmove_src(ptr %p, ptr %p2) {568; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)569; CHECK-LABEL: define void @memmove_src(570; CHECK-SAME: ptr captures(none) initializes((96, 128)) [[P:%.*]], ptr captures(none) initializes((0, 96)) [[P2:%.*]]) #[[ATTR1]] {571; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[P2]], ptr [[P]], i64 96, i1 false)572; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[P]], i64 64573; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[G]], ptr [[P2]], i64 64, i1 false)574; CHECK-NEXT:    ret void575;576  call void @llvm.memmove(ptr %p2, ptr %p, i64 96, i1 false)577  %g = getelementptr i8, ptr %p, i64 64578  call void @llvm.memmove(ptr %g, ptr %p2, i64 64, i1 false)579  ret void580}581 582define void @memmove_non_constant(ptr %p, ptr %p2, i64 %i) {583; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)584; CHECK-LABEL: define void @memmove_non_constant(585; CHECK-SAME: ptr writeonly captures(none) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]], i64 [[I:%.*]]) #[[ATTR1]] {586; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 [[I]], i1 false)587; CHECK-NEXT:    ret void588;589  call void @llvm.memmove(ptr %p, ptr %p2, i64 %i, i1 false)590  ret void591}592 593define void @callee_byval(ptr byval(i32) %p) {594; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)595; CHECK-LABEL: define void @callee_byval(596; CHECK-SAME: ptr writeonly byval(i32) captures(none) initializes((0, 4)) [[P:%.*]]) #[[ATTR0]] {597; CHECK-NEXT:    store i32 0, ptr [[P]], align 4598; CHECK-NEXT:    ret void599;600  store i32 0, ptr %p601  ret void602}603 604define void @caller_byval(ptr %p) {605; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)606; CHECK-LABEL: define void @caller_byval(607; CHECK-SAME: ptr readonly captures(none) [[P:%.*]]) #[[ATTR0]] {608; CHECK-NEXT:    call void @callee_byval(ptr byval(i32) [[P]])609; CHECK-NEXT:    ret void610;611  call void @callee_byval(ptr byval(i32) %p)612  ret void613}614 615define void @memset_offset_0_size_0(ptr %dst, ptr %src) {616; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)617; CHECK-LABEL: define void @memset_offset_0_size_0(618; CHECK-SAME: ptr writeonly captures(none) [[DST:%.*]], ptr readonly captures(none) [[SRC:%.*]]) #[[ATTR1]] {619; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 0, i1 false)620; CHECK-NEXT:    ret void621;622  call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 0, i1 false)623  ret void624}625 626define void @memset_offset_1_size_0(ptr %dst, ptr %src) {627; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)628; CHECK-LABEL: define void @memset_offset_1_size_0(629; CHECK-SAME: ptr writeonly captures(none) [[DST:%.*]], ptr readonly captures(none) [[SRC:%.*]]) #[[ATTR1]] {630; CHECK-NEXT:    [[DST_1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1631; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[DST_1]], ptr [[SRC]], i64 0, i1 false)632; CHECK-NEXT:    ret void633;634  %dst.1 = getelementptr inbounds i8, ptr %dst, i64 1635  call void @llvm.memmove.p0.p0.i64(ptr %dst.1, ptr %src, i64 0, i1 false)636  ret void637}638 639; We should bail if the range overflows a singed 64-bit int.640define void @range_overflows_signed_64_bit_int(ptr %arg) {641; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)642; CHECK-LABEL: define void @range_overflows_signed_64_bit_int(643; CHECK-SAME: ptr writeonly captures(none) [[ARG:%.*]]) #[[ATTR0]] {644; CHECK-NEXT:    [[GETELEMENTPTR:%.*]] = getelementptr i8, ptr [[ARG]], i64 9223372036854775804645; CHECK-NEXT:    store i32 0, ptr [[GETELEMENTPTR]], align 4646; CHECK-NEXT:    ret void647;648  %getelementptr = getelementptr i8, ptr %arg, i64 9223372036854775804649  store i32 0, ptr %getelementptr650  ret void651}652 653; We should bail if the memset range overflows a signed 64-bit int.654define void @memset_large_offset_nonzero_size(ptr %dst) {655; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)656; CHECK-LABEL: define void @memset_large_offset_nonzero_size(657; CHECK-SAME: ptr writeonly captures(none) [[DST:%.*]]) #[[ATTR0]] {658; CHECK-NEXT:    [[OFFSET:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 9223372036854775805659; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[OFFSET]], i8 0, i64 3, i1 false)660; CHECK-NEXT:    ret void661;662  %offset = getelementptr inbounds i8, ptr %dst, i64 9223372036854775805663  call void @llvm.memset.p0.i64(ptr %offset, i8 0, i64 3, i1 false)664  ret void665}666