xref: /llvm-project/llvm/test/Transforms/InstCombine/mem-deref-bytes.ll (revision 4ab40eca080965c65802710e39adbb78c4ce7bde)
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