1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4define ptr @memcpy_nonconst_n(ptr %d, ptr nocapture readonly %s, i64 %n) { 5; CHECK-LABEL: @memcpy_nonconst_n( 6; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) 7; CHECK-NEXT: [[R:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[N]] 8; CHECK-NEXT: ret ptr [[R]] 9; 10 %r = tail call ptr @mempcpy(ptr %d, ptr %s, i64 %n) 11 ret ptr %r 12} 13 14define ptr @memcpy_nonconst_n_copy_attrs(ptr %d, ptr nocapture readonly %s, i64 %n) { 15; CHECK-LABEL: @memcpy_nonconst_n_copy_attrs( 16; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 dereferenceable(16) [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) 17; CHECK-NEXT: [[R:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[N]] 18; CHECK-NEXT: ret ptr [[R]] 19; 20 %r = tail call ptr @mempcpy(ptr dereferenceable(16) %d, ptr %s, i64 %n) 21 ret ptr %r 22} 23 24define void @memcpy_nonconst_n_unused_retval(ptr %d, ptr nocapture readonly %s, i64 %n) { 25; CHECK-LABEL: @memcpy_nonconst_n_unused_retval( 26; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) 27; CHECK-NEXT: ret void 28; 29 call ptr @mempcpy(ptr %d, ptr %s, i64 %n) 30 ret void 31} 32 33define ptr @memcpy_small_const_n(ptr %d, ptr nocapture readonly %s) { 34; CHECK-LABEL: @memcpy_small_const_n( 35; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[S:%.*]], align 1 36; CHECK-NEXT: store i64 [[TMP1]], ptr [[D:%.*]], align 1 37; CHECK-NEXT: [[R:%.*]] = getelementptr inbounds nuw i8, ptr [[D]], i64 8 38; CHECK-NEXT: ret ptr [[R]] 39; 40 %r = tail call ptr @mempcpy(ptr %d, ptr %s, i64 8) 41 ret ptr %r 42} 43 44define ptr @memcpy_big_const_n(ptr %d, ptr nocapture readonly %s) { 45; CHECK-LABEL: @memcpy_big_const_n( 46; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(1024) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false) 47; CHECK-NEXT: [[R:%.*]] = getelementptr inbounds nuw i8, ptr [[D]], i64 1024 48; CHECK-NEXT: ret ptr [[R]] 49; 50 %r = tail call ptr @mempcpy(ptr %d, ptr %s, i64 1024) 51 ret ptr %r 52} 53 54; The original call may have attributes that can not propagate to memcpy. 55 56define i32 @PR48810() { 57; CHECK-LABEL: @PR48810( 58; CHECK-NEXT: store i1 true, ptr poison, align 1 59; CHECK-NEXT: ret i32 undef 60; 61 %r = call dereferenceable(1) ptr @mempcpy(ptr undef, ptr null, i64 undef) 62 ret i32 undef 63} 64 65define ptr @memcpy_no_simplify1(ptr %d, ptr nocapture readonly %s, i64 %n) { 66; CHECK-LABEL: @memcpy_no_simplify1( 67; CHECK-NEXT: [[R:%.*]] = musttail call ptr @mempcpy(ptr [[D:%.*]], ptr [[S:%.*]], i64 [[N:%.*]]) 68; CHECK-NEXT: ret ptr [[R]] 69; 70 %r = musttail call ptr @mempcpy(ptr %d, ptr %s, i64 %n) 71 ret ptr %r 72} 73 74declare ptr @mempcpy(ptr, ptr nocapture readonly, i64) 75