1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 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 %call 20} 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 %call 29} 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 %call 38} 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 %call 47} 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 %call 56} 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 %call 65} 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 %call 74} 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 %call 83} 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 %call 92} 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 %call 101} 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 %call 110} 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 %call 119} 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 i8 124; 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 %call 129} 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 %call 138} 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 %d 147} 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 %d 156} 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 %s 164} 165