269 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4@hello = private constant [11 x i8] c"helloworld\00", align 15@NoNulTerminator = private constant [10 x i8] c"helloworld", align 16@StopCharAfterNulTerminator = private constant [12 x i8] c"helloworld\00x", align 17@StringWithEOF = constant [14 x i8] c"helloworld\FFab\00", align 18 9declare ptr @memccpy(ptr, ptr, i32, i64)10 11define ptr @memccpy_to_memcpy(ptr %dst) {12; CHECK-LABEL: @memccpy_to_memcpy(13; CHECK-NEXT: store i64 8245940763182785896, ptr [[DST:%.*]], align 114; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 815; CHECK-NEXT: ret ptr [[CALL]]16;17 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 12) ; 114 is 'r'18 ret ptr %call19}20 21define ptr @memccpy_to_memcpy2(ptr %dst) {22; CHECK-LABEL: @memccpy_to_memcpy2(23; CHECK-NEXT: store i64 8245940763182785896, ptr [[DST:%.*]], align 124; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 825; CHECK-NEXT: ret ptr [[CALL]]26;27 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 8); ; 114 is 'r'28 ret ptr %call29}30 31define void @memccpy_to_memcpy3(ptr %dst) {32; CHECK-LABEL: @memccpy_to_memcpy3(33; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(5) @hello, i64 5, i1 false)34; CHECK-NEXT: ret void35;36 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 111, i64 10) ; 111 is 'o'37 ret void38}39 40define void @memccpy_to_memcpy3_tail(ptr %dst) {41; CHECK-LABEL: @memccpy_to_memcpy3_tail(42; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(5) @hello, i64 5, i1 false)43; CHECK-NEXT: ret void44;45 %call = tail call ptr @memccpy(ptr %dst, ptr @hello, i32 111, i64 10) ; 111 is 'o'46 ret void47}48 49define ptr @memccpy_to_memcpy3_musttail(ptr %dst, ptr %x, i32 %y, i64 %z) {50; CHECK-LABEL: @memccpy_to_memcpy3_musttail(51; CHECK-NEXT: [[CALL:%.*]] = musttail call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 111, i64 10)52; CHECK-NEXT: ret ptr [[CALL]]53;54 %call = musttail call ptr @memccpy(ptr %dst, ptr @hello, i32 111, i64 10) ; 111 is 'o'55 ret ptr %call56}57 58 59define void @memccpy_to_memcpy4(ptr %dst) {60; CHECK-LABEL: @memccpy_to_memcpy4(61; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(11) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(11) @hello, i64 11, i1 false)62; CHECK-NEXT: ret void63;64 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 0, i64 12)65 ret void66}67 68define ptr @memccpy_to_memcpy5(ptr %dst) {69; CHECK-LABEL: @memccpy_to_memcpy5(70; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(7) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(7) @hello, i64 7, i1 false)71; CHECK-NEXT: ret ptr null72;73 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 7)74 ret ptr %call75}76 77define ptr @memccpy_to_memcpy5_tail(ptr %dst) {78; CHECK-LABEL: @memccpy_to_memcpy5_tail(79; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(7) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(7) @hello, i64 7, i1 false)80; CHECK-NEXT: ret ptr null81;82 %call = tail call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 7)83 ret ptr %call84}85 86define ptr @memccpy_to_memcpy5_musttail(ptr %dst, ptr %x, i32 %y, i64 %z) {87; CHECK-LABEL: @memccpy_to_memcpy5_musttail(88; CHECK-NEXT: [[CALL:%.*]] = musttail call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 114, i64 7)89; CHECK-NEXT: ret ptr [[CALL]]90;91 %call = musttail call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 7)92 ret ptr %call93}94 95define ptr @memccpy_to_memcpy6(ptr %dst) {96; CHECK-LABEL: @memccpy_to_memcpy6(97; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(6) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i64 6, i1 false)98; CHECK-NEXT: ret ptr null99;100 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 6);101 ret ptr %call102}103 104define ptr @memccpy_to_memcpy7(ptr %dst) {105; CHECK-LABEL: @memccpy_to_memcpy7(106; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(5) @hello, i64 5, i1 false)107; CHECK-NEXT: ret ptr null108;109 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 115, i64 5) ; 115 is 's'110 ret ptr %call111}112 113define ptr @memccpy_to_memcpy8(ptr %dst) {114; CHECK-LABEL: @memccpy_to_memcpy8(115; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(11) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(11) @hello, i64 11, i1 false)116; CHECK-NEXT: ret ptr null117;118 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 115, i64 11) ; 115 is 's'119 ret ptr %call120}121 122define ptr @memccpy_to_memcpy9(ptr %dst, i64 %n) {123; CHECK-LABEL: @memccpy_to_memcpy9(124; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(12) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(12) @StopCharAfterNulTerminator, i64 12, i1 false)125; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 12126; CHECK-NEXT: ret ptr [[CALL]]127;128 %call = call ptr @memccpy(ptr %dst, ptr @StopCharAfterNulTerminator, i32 120, i64 15) ; 120 is 'x'129 ret ptr %call130}131 132define ptr @memccpy_to_memcpy10(ptr %dst, i64 %n) {133; CHECK-LABEL: @memccpy_to_memcpy10(134; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(11) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(11) @StringWithEOF, i64 11, i1 false)135; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 11136; CHECK-NEXT: ret ptr [[CALL]]137;138 %call = call ptr @memccpy(ptr %dst, ptr @StringWithEOF, i32 255, i64 15)139 ret ptr %call140}141 142define ptr @memccpy_to_memcpy11(ptr %dst, i64 %n) {143; CHECK-LABEL: @memccpy_to_memcpy11(144; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(11) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(11) @StringWithEOF, i64 11, i1 false)145; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 11146; CHECK-NEXT: ret ptr [[CALL]]147;148 %call = call ptr @memccpy(ptr %dst, ptr @StringWithEOF, i32 -1, i64 15)149 ret ptr %call150}151 152define ptr @memccpy_to_memcpy12(ptr %dst, i64 %n) {153; CHECK-LABEL: @memccpy_to_memcpy12(154; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(11) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(11) @StringWithEOF, i64 11, i1 false)155; CHECK-NEXT: [[CALL:%.*]] = getelementptr inbounds nuw i8, ptr [[DST]], i64 11156; CHECK-NEXT: ret ptr [[CALL]]157;158 %call = call ptr @memccpy(ptr %dst, ptr @StringWithEOF, i32 1023, i64 15)159 ret ptr %call160}161 162define ptr @memccpy_to_null(ptr %dst, ptr %src, i32 %c) {163; CHECK-LABEL: @memccpy_to_null(164; CHECK-NEXT: ret ptr null165;166 %call = call ptr @memccpy(ptr %dst, ptr %src, i32 %c, i64 0)167 ret ptr %call168}169 170define void @memccpy_dst_src_same_retval_unused(ptr %dst, i32 %c, i64 %n) {171; CHECK-LABEL: @memccpy_dst_src_same_retval_unused(172; CHECK-NEXT: ret void173;174 %call = call ptr @memccpy(ptr %dst, ptr %dst, i32 %c, i64 %n)175 ret void176}177 178; Negative tests179define ptr @unknown_src(ptr %dst, ptr %src) {180; CHECK-LABEL: @unknown_src(181; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 114, i64 12)182; CHECK-NEXT: ret ptr [[CALL]]183;184 %call = call ptr @memccpy(ptr %dst, ptr %src, i32 114, i64 12)185 ret ptr %call186}187 188define ptr @unknown_stop_char(ptr %dst, i32 %c) {189; CHECK-LABEL: @unknown_stop_char(190; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 [[C:%.*]], i64 12)191; CHECK-NEXT: ret ptr [[CALL]]192;193 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 %c, i64 12)194 ret ptr %call195}196 197define ptr @unknown_size_n(ptr %dst, i64 %n) {198; CHECK-LABEL: @unknown_size_n(199; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 114, i64 [[N:%.*]])200; CHECK-NEXT: ret ptr [[CALL]]201;202 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 %n)203 ret ptr %call204}205 206define ptr @no_nul_terminator(ptr %dst, i64 %n) {207; CHECK-LABEL: @no_nul_terminator(208; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @StopCharAfterNulTerminator, i32 120, i64 [[N:%.*]])209; CHECK-NEXT: ret ptr [[CALL]]210;211 %call = call ptr @memccpy(ptr %dst, ptr @StopCharAfterNulTerminator, i32 120, i64 %n) ; 120 is 'x'212 ret ptr %call213}214 215define ptr @possibly_valid_data_after_array(ptr %dst, i64 %n) {216; CHECK-LABEL: @possibly_valid_data_after_array(217; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @NoNulTerminator, i32 115, i64 [[N:%.*]])218; CHECK-NEXT: ret ptr [[CALL]]219;220 %call = call ptr @memccpy(ptr %dst, ptr @NoNulTerminator, i32 115, i64 %n) ; 115 is 's'221 ret ptr %call222}223 224define ptr @possibly_valid_data_after_array2(ptr %dst, i64 %n) {225; CHECK-LABEL: @possibly_valid_data_after_array2(226; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 115, i64 [[N:%.*]])227; CHECK-NEXT: ret ptr [[CALL]]228;229 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 115, i64 %n) ; 115 is 's'230 ret ptr %call231}232 233define ptr @possibly_valid_data_after_array3(ptr %dst) {234; CHECK-LABEL: @possibly_valid_data_after_array3(235; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 115, i64 12)236; CHECK-NEXT: ret ptr [[CALL]]237;238 %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 115, i64 12) ; 115 is 's'239 ret ptr %call240}241 242define ptr @memccpy_dst_src_same_retval_used(ptr %dst, i32 %c, i64 %n) {243; CHECK-LABEL: @memccpy_dst_src_same_retval_used(244; CHECK-NEXT: [[CALL:%.*]] = call ptr @memccpy(ptr [[DST:%.*]], ptr [[DST]], i32 [[C:%.*]], i64 [[N:%.*]])245; CHECK-NEXT: ret ptr [[CALL]]246;247 %call = call ptr @memccpy(ptr %dst, ptr %dst, i32 %c, i64 %n)248 ret ptr %call249}250 251define ptr @memccpy_to_memcpy_musttail(ptr %dst, ptr %x, i32 %y, i64 %z) {252; CHECK-LABEL: @memccpy_to_memcpy_musttail(253; CHECK-NEXT: [[CALL:%.*]] = musttail call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 114, i64 12)254; CHECK-NEXT: ret ptr [[CALL]]255;256 %call = musttail call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 12) ; 114 is 'r'257 ret ptr %call258}259 260define ptr @memccpy_to_memcpy2_musttail(ptr %dst, ptr %x, i32 %y, i64 %z) {261; CHECK-LABEL: @memccpy_to_memcpy2_musttail(262; CHECK-NEXT: [[CALL:%.*]] = musttail call ptr @memccpy(ptr [[DST:%.*]], ptr nonnull @hello, i32 114, i64 8)263; CHECK-NEXT: ret ptr [[CALL]]264;265 %call = musttail call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 8) ; 114 is 'r'266 ret ptr %call267}268 269