165 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare i32 @memcmp(ptr nocapture, ptr nocapture, i64)5declare ptr @memcpy(ptr nocapture, ptr nocapture, i64)6declare ptr @memmove(ptr nocapture, ptr nocapture, i64)7declare ptr @memset(ptr nocapture, i32, i64)8declare ptr @memchr(ptr nocapture, i32, i64)9declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)10declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)11declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)12 13define i32 @memcmp_const_size_set_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {14; CHECK-LABEL: @memcmp_const_size_set_deref(15; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(16) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)16; CHECK-NEXT: ret i32 [[CALL]]17;18 %call = tail call i32 @memcmp(ptr %d, ptr %s, i64 16)19 ret i32 %call20}21 22define i32 @memcmp_const_size_update_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {23; CHECK-LABEL: @memcmp_const_size_update_deref(24; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(16) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)25; CHECK-NEXT: ret i32 [[CALL]]26;27 %call = tail call i32 @memcmp(ptr dereferenceable(4) %d, ptr dereferenceable(8) %s, i64 16)28 ret i32 %call29}30 31define i32 @memcmp_const_size_update_deref2(ptr nocapture readonly %d, ptr nocapture readonly %s) {32; CHECK-LABEL: @memcmp_const_size_update_deref2(33; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(16) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)34; CHECK-NEXT: ret i32 [[CALL]]35;36 %call = tail call i32 @memcmp(ptr %d, ptr dereferenceable_or_null(8) %s, i64 16)37 ret i32 %call38}39 40define i32 @memcmp_const_size_update_deref3(ptr nocapture readonly %d, ptr nocapture readonly %s) {41; CHECK-LABEL: @memcmp_const_size_update_deref3(42; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(40) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)43; CHECK-NEXT: ret i32 [[CALL]]44;45 %call = tail call i32 @memcmp(ptr dereferenceable(40) %d, ptr %s, i64 16)46 ret i32 %call47}48 49define i32 @memcmp_const_size_update_deref4(ptr nocapture readonly %d, ptr nocapture readonly %s) {50; CHECK-LABEL: @memcmp_const_size_update_deref4(51; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(16) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)52; CHECK-NEXT: ret i32 [[CALL]]53;54 %call = tail call i32 @memcmp(ptr dereferenceable_or_null(16) %d, ptr %s, i64 16)55 ret i32 %call56}57 58define i32 @memcmp_const_size_update_deref5(ptr nocapture readonly %d, ptr nocapture readonly %s) {59; CHECK-LABEL: @memcmp_const_size_update_deref5(60; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(40) [[D:%.*]], ptr noundef nonnull dereferenceable(16) [[S:%.*]], i64 16)61; CHECK-NEXT: ret i32 [[CALL]]62;63 %call = tail call i32 @memcmp(ptr dereferenceable_or_null(40) %d, ptr %s, i64 16)64 ret i32 %call65}66 67define i32 @memcmp_const_size_update_deref6(ptr nocapture readonly %d, ptr nocapture readonly %s) null_pointer_is_valid {68; CHECK-LABEL: @memcmp_const_size_update_deref6(69; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef dereferenceable(16) dereferenceable_or_null(40) [[D:%.*]], ptr noundef dereferenceable(16) [[S:%.*]], i64 16)70; CHECK-NEXT: ret i32 [[CALL]]71;72 %call = tail call i32 @memcmp(ptr dereferenceable_or_null(40) %d, ptr %s, i64 16)73 ret i32 %call74}75 76define i32 @memcmp_const_size_update_deref7(ptr nocapture readonly %d, ptr nocapture readonly %s) null_pointer_is_valid {77; CHECK-LABEL: @memcmp_const_size_update_deref7(78; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(40) [[D:%.*]], ptr noundef dereferenceable(16) [[S:%.*]], i64 16)79; CHECK-NEXT: ret i32 [[CALL]]80;81 %call = tail call i32 @memcmp(ptr nonnull dereferenceable_or_null(40) %d, ptr %s, i64 16)82 ret i32 %call83}84 85define i32 @memcmp_const_size_no_update_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {86; CHECK-LABEL: @memcmp_const_size_no_update_deref(87; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr noundef nonnull dereferenceable(40) [[D:%.*]], ptr noundef nonnull dereferenceable(20) [[S:%.*]], i64 16)88; CHECK-NEXT: ret i32 [[CALL]]89;90 %call = tail call i32 @memcmp(ptr dereferenceable(40) %d, ptr dereferenceable(20) %s, i64 16)91 ret i32 %call92}93 94define i32 @memcmp_nonconst_size(ptr nocapture readonly %d, ptr nocapture readonly %s, i64 %n) {95; CHECK-LABEL: @memcmp_nonconst_size(96; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(ptr [[D:%.*]], ptr [[S:%.*]], i64 [[N:%.*]])97; CHECK-NEXT: ret i32 [[CALL]]98;99 %call = tail call i32 @memcmp(ptr %d, ptr %s, i64 %n)100 ret i32 %call101}102 103define ptr @memcpy_const_size_set_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {104; CHECK-LABEL: @memcpy_const_size_set_deref(105; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(64) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)106; CHECK-NEXT: ret ptr [[D]]107;108 %call = tail call ptr @memcpy(ptr %d, ptr %s, i64 64)109 ret ptr %call110}111 112define ptr @memmove_const_size_set_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {113; CHECK-LABEL: @memmove_const_size_set_deref(114; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(64) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i64 64, i1 false)115; CHECK-NEXT: ret ptr [[D]]116;117 %call = tail call ptr @memmove(ptr %d, ptr %s, i64 64)118 ret ptr %call119}120 121define ptr @memset_const_size_set_deref(ptr nocapture readonly %s, i32 %c) {122; CHECK-LABEL: @memset_const_size_set_deref(123; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8124; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(64) [[S:%.*]], i8 [[TMP1]], i64 64, i1 false)125; CHECK-NEXT: ret ptr [[S]]126;127 %call = tail call ptr @memset(ptr %s, i32 %c, i64 64)128 ret ptr %call129}130 131define ptr @memchr_const_size_set_deref(ptr nocapture readonly %s, i32 %c) {132; CHECK-LABEL: @memchr_const_size_set_deref(133; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @memchr(ptr noundef nonnull dereferenceable(1) [[S:%.*]], i32 [[C:%.*]], i64 64)134; CHECK-NEXT: ret ptr [[CALL]]135;136 %call = tail call ptr @memchr(ptr %s, i32 %c, i64 64)137 ret ptr %call138}139 140define ptr @llvm_memcpy_const_size_set_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {141; CHECK-LABEL: @llvm_memcpy_const_size_set_deref(142; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)143; CHECK-NEXT: ret ptr [[D]]144;145 call void @llvm.memcpy.p0.p0.i64(ptr align 1 %d, ptr align 1 %s, i64 16, i1 false)146 ret ptr %d147}148 149define ptr @llvm_memmove_const_size_set_deref(ptr nocapture readonly %d, ptr nocapture readonly %s) {150; CHECK-LABEL: @llvm_memmove_const_size_set_deref(151; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(16) [[S:%.*]], i64 16, i1 false)152; CHECK-NEXT: ret ptr [[D]]153;154 call void @llvm.memmove.p0.p0.i64(ptr align 1 %d, ptr align 1 %s, i64 16, i1 false)155 ret ptr %d156}157define ptr @llvm_memset_const_size_set_deref(ptr nocapture readonly %s, i8 %c) {158; CHECK-LABEL: @llvm_memset_const_size_set_deref(159; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) [[S:%.*]], i8 [[C:%.*]], i64 16, i1 false)160; CHECK-NEXT: ret ptr [[S]]161;162 call void @llvm.memset.p0.i64(ptr align 1 %s, i8 %c, i64 16, i1 false)163 ret ptr %s164}165