1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Test lib call simplification of __strncpy_chk calls with various values
3; for len and dstlen.
4;
5; RUN: opt < %s -instcombine -S | FileCheck %s
6
7target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
8
9@a = common global [60 x i8] zeroinitializer, align 1
10@b = common global [60 x i8] zeroinitializer, align 1
11@.str = private constant [12 x i8] c"abcdefghijk\00"
12
13; Check cases where dstlen >= len
14
15define i8* @test_simplify1() {
16; CHECK-LABEL: @test_simplify1(
17; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
18; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0)
19;
20  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
21  %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
22
23  %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
24  ret i8* %ret
25}
26
27define i8* @test_simplify2() {
28; CHECK-LABEL: @test_simplify2(
29; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false)
30; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0)
31;
32  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
33  %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
34
35  %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12)
36  ret i8* %ret
37}
38
39define i8* @test_simplify3() {
40; CHECK-LABEL: @test_simplify3(
41; CHECK-NEXT:    [[STRNCPY:%.*]] = call i8* @strncpy(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 12)
42; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0)
43;
44  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
45  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
46
47  %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60)
48  ret i8* %ret
49}
50
51; Check cases where dstlen < len
52
53define i8* @test_no_simplify1() {
54; CHECK-LABEL: @test_no_simplify1(
55; CHECK-NEXT:    [[RET:%.*]] = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 8, i32 4)
56; CHECK-NEXT:    ret i8* [[RET]]
57;
58  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
59  %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
60
61  %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4)
62  ret i8* %ret
63}
64
65define i8* @test_no_simplify2() {
66; CHECK-LABEL: @test_no_simplify2(
67; CHECK-NEXT:    [[RET:%.*]] = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8, i32 0)
68; CHECK-NEXT:    ret i8* [[RET]]
69;
70  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
71  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
72
73  %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0)
74  ret i8* %ret
75}
76
77declare i8* @__strncpy_chk(i8*, i8*, i32, i32)
78