• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Test lib call simplification of __stpcpy_chk calls with various values
3; for src, dst, and slen.
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 slen >= strlen (src).
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 11)
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* @__stpcpy_chk(i8* %dst, i8* %src, 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 11)
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* @__stpcpy_chk(i8* %dst, i8* %src, i32 12)
36  ret i8* %ret
37}
38
39define i8* @test_simplify3() {
40; CHECK-LABEL: @test_simplify3(
41; 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)
42; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
43;
44  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
45  %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
46
47  %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
48  ret i8* %ret
49}
50
51; Check cases where there are no string constants.
52
53define i8* @test_simplify4() {
54; CHECK-LABEL: @test_simplify4(
55; CHECK-NEXT:    [[STPCPY:%.*]] = call i8* @stpcpy(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))
56; CHECK-NEXT:    ret i8* [[STPCPY]]
57;
58  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
59  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
60
61  %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 -1)
62  ret i8* %ret
63}
64
65; Check case where the string length is not constant.
66
67define i8* @test_simplify5() {
68; CHECK-LABEL: @test_simplify5(
69; CHECK-NEXT:    [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
70; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @__memcpy_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 12, i32 [[LEN]])
71; CHECK-NEXT:    ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 11)
72;
73  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
74  %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0
75
76  %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
77  %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 %len)
78  ret i8* %ret
79}
80
81; Check case where the source and destination are the same.
82
83define i8* @test_simplify6() {
84; CHECK-LABEL: @test_simplify6(
85; CHECK-NEXT:    [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0))
86; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 [[STRLEN]]
87; CHECK-NEXT:    ret i8* [[TMP1]]
88;
89  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
90
91  %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false)
92  %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %dst, i32 %len)
93  ret i8* %ret
94}
95
96; Check case where slen < strlen (src).
97
98define i8* @test_no_simplify1() {
99; CHECK-LABEL: @test_no_simplify1(
100; CHECK-NEXT:    [[RET:%.*]] = call i8* @__stpcpy_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)
101; CHECK-NEXT:    ret i8* [[RET]]
102;
103  %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0
104  %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0
105
106  %ret = call i8* @__stpcpy_chk(i8* %dst, i8* %src, i32 8)
107  ret i8* %ret
108}
109
110declare i8* @__stpcpy_chk(i8*, i8*, i32) nounwind
111declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly
112