1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4@.str = private unnamed_addr constant [4 x i8] c"str\00", align 1
5@.str.1 = private unnamed_addr constant [3 x i8] c"%%\00", align 1
6@.str.2 = private unnamed_addr constant [3 x i8] c"%c\00", align 1
7@.str.3 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
8
9declare i32 @snprintf(i8*, i64, i8*, ...) #1
10
11define void @test_not_const_fmt(i8* %buf, i8* %fmt) #0 {
12; CHECK-LABEL: @test_not_const_fmt(
13; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 32, i8* [[FMT:%.*]])
14; CHECK-NEXT:    ret void
15;
16  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* %fmt) #2
17  ret void
18}
19
20define void @test_not_const_fmt_zero_size_return_value(i8* %buf, i8* %fmt) #0 {
21; CHECK-LABEL: @test_not_const_fmt_zero_size_return_value(
22; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 0, i8* [[FMT:%.*]])
23; CHECK-NEXT:    ret void
24;
25  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* %fmt) #2
26  ret void
27}
28
29
30define void @test_not_const_size(i8* %buf, i64 %size) #0 {
31; CHECK-LABEL: @test_not_const_size(
32; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 [[SIZE:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0))
33; CHECK-NEXT:    ret void
34;
35  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 %size, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
36  ret void
37}
38
39
40define i32 @test_return_value(i8* %buf) #0 {
41; CHECK-LABEL: @test_return_value(
42; CHECK-NEXT:    ret i32 3
43;
44  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
45  ret i32 %call
46}
47
48define void @test_percentage(i8* %buf) #0 {
49; CHECK-LABEL: @test_percentage(
50; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
51; CHECK-NEXT:    ret void
52;
53  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) #2
54  ret void
55}
56
57define i32 @test_null_buf_return_value() #0 {
58; CHECK-LABEL: @test_null_buf_return_value(
59; CHECK-NEXT:    ret i32 3
60;
61  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* null, i64 0, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
62  ret i32 %call
63}
64
65define i32 @test_percentage_return_value() #0 {
66; CHECK-LABEL: @test_percentage_return_value(
67; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* null, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
68; CHECK-NEXT:    ret i32 [[CALL]]
69;
70  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* null, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) #3
71  ret i32 %call
72}
73
74
75define void @test_correct_copy(i8* %buf) #0 {
76; CHECK-LABEL: @test_correct_copy(
77; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32*
78; CHECK-NEXT:    store i32 7500915, i32* [[TMP1]], align 1
79; CHECK-NEXT:    ret void
80;
81  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
82  ret void
83}
84
85define i32 @test_char_zero_size(i8* %buf) #0 {
86; CHECK-LABEL: @test_char_zero_size(
87; CHECK-NEXT:    ret i32 1
88;
89  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2
90  ret i32 %call
91}
92
93define i32 @test_char_wrong_size(i8* %buf) #0 {
94; CHECK-LABEL: @test_char_wrong_size(
95; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65)
96; CHECK-NEXT:    ret i32 [[CALL]]
97;
98  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2
99  ret i32 %call
100}
101
102define i32 @test_char_ok_size(i8* %buf) #0 {
103; CHECK-LABEL: @test_char_ok_size(
104; CHECK-NEXT:    store i8 65, i8* [[BUF:%.*]], align 1
105; CHECK-NEXT:    [[NUL:%.*]] = getelementptr i8, i8* [[BUF]], i64 1
106; CHECK-NEXT:    store i8 0, i8* [[NUL]], align 1
107; CHECK-NEXT:    ret i32 1
108;
109  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65) #2
110  ret i32 %call
111}
112
113define i32 @test_str_zero_size(i8* %buf) #0 {
114; CHECK-LABEL: @test_str_zero_size(
115; CHECK-NEXT:    ret i32 3
116;
117  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
118  ret i32 %call
119}
120
121define i32 @test_str_wrong_size(i8* %buf) #0 {
122; CHECK-LABEL: @test_str_wrong_size(
123; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0))
124; CHECK-NEXT:    ret i32 [[CALL]]
125;
126  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
127  ret i32 %call
128}
129
130define i32 @test_str_ok_size(i8* %buf) #0 {
131; CHECK-LABEL: @test_str_ok_size(
132; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32*
133; CHECK-NEXT:    store i32 7500915, i32* [[TMP1]], align 1
134; CHECK-NEXT:    ret i32 3
135;
136  %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2
137  ret i32 %call
138}
139