[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / snprintf.ll
blobae22421879c3021abe39dca21358a153f0ff714c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
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 @.str.4 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
11 declare i32 @snprintf(i8*, i64, i8*, ...) #1
13 define void @test_not_const_fmt(i8* %buf, i8* %fmt) #0 {
14 ; CHECK-LABEL: @test_not_const_fmt(
15 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 32, i8* [[FMT:%.*]])
16 ; CHECK-NEXT:    ret void
18   %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* %fmt) #2
19   ret void
22 ; size is '0', do not add nonnull attribute
23 define void @test_not_const_fmt_zero_size_return_value(i8* %buf, i8* %fmt) #0 {
24 ; CHECK-LABEL: @test_not_const_fmt_zero_size_return_value(
25 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 0, i8* [[FMT:%.*]])
26 ; CHECK-NEXT:    ret void
28   %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* %fmt) #2
29   ret void
32 define void @test_not_const_size(i8* %buf, i64 %size) #0 {
33 ; CHECK-LABEL: @test_not_const_size(
34 ; 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))
35 ; CHECK-NEXT:    ret void
37   %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
38   ret void
42 define i32 @test_return_value(i8* %buf) #0 {
43 ; CHECK-LABEL: @test_return_value(
44 ; CHECK-NEXT:    ret i32 3
46   %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
47   ret i32 %call
50 define void @test_percentage(i8* %buf) #0 {
51 ; CHECK-LABEL: @test_percentage(
52 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 32, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
53 ; CHECK-NEXT:    ret void
55   %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
56   ret void
59 define i32 @test_null_buf_return_value() #0 {
60 ; CHECK-LABEL: @test_null_buf_return_value(
61 ; CHECK-NEXT:    ret i32 3
63   %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
64   ret i32 %call
67 define i32 @test_percentage_return_value() #0 {
68 ; CHECK-LABEL: @test_percentage_return_value(
69 ; 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))
70 ; CHECK-NEXT:    ret i32 [[CALL]]
72   %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
73   ret i32 %call
77 define void @test_correct_copy(i8* %buf) #0 {
78 ; CHECK-LABEL: @test_correct_copy(
79 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32*
80 ; CHECK-NEXT:    store i32 7500915, i32* [[TMP1]], align 1
81 ; CHECK-NEXT:    ret void
83   %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
84   ret void
87 define i32 @test_char_zero_size(i8* %buf) #0 {
88 ; CHECK-LABEL: @test_char_zero_size(
89 ; CHECK-NEXT:    ret i32 1
91   %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
92   ret i32 %call
95 define i32 @test_char_wrong_size(i8* %buf) #0 {
96 ; CHECK-LABEL: @test_char_wrong_size(
97 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 65)
98 ; CHECK-NEXT:    ret i32 [[CALL]]
100   %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
101   ret i32 %call
104 define i32 @test_char_ok_size(i8* %buf) #0 {
105 ; CHECK-LABEL: @test_char_ok_size(
106 ; CHECK-NEXT:    store i8 65, i8* [[BUF:%.*]], align 1
107 ; CHECK-NEXT:    [[NUL:%.*]] = getelementptr i8, i8* [[BUF]], i64 1
108 ; CHECK-NEXT:    store i8 0, i8* [[NUL]], align 1
109 ; CHECK-NEXT:    ret i32 1
111   %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
112   ret i32 %call
115 define i32 @test_str_zero_size(i8* %buf) #0 {
116 ; CHECK-LABEL: @test_str_zero_size(
117 ; CHECK-NEXT:    ret i32 3
119   %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
120   ret i32 %call
123 define i32 @test_str_wrong_size(i8* %buf) #0 {
124 ; CHECK-LABEL: @test_str_wrong_size(
125 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull dereferenceable(1) [[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))
126 ; CHECK-NEXT:    ret i32 [[CALL]]
128   %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
129   ret i32 %call
132 define i32 @test_str_ok_size(i8* %buf) #0 {
133 ; CHECK-LABEL: @test_str_ok_size(
134 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32*
135 ; CHECK-NEXT:    store i32 7500915, i32* [[TMP1]], align 1
136 ; CHECK-NEXT:    ret i32 3
138   %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
139   ret i32 %call
142 ; snprintf(buf, 32, "") -> memcpy -> store
143 define i32 @test_str_ok_size_tail(i8* %buf) {
144 ; CHECK-LABEL: @test_str_ok_size_tail(
145 ; CHECK-NEXT:    store i8 0, i8* %buf, align 1
146 ; CHECK-NEXT:    ret i32 0
148   %1 = tail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0))
149   ret i32 %1
152 define i32 @test_str_ok_size_musttail(i8* %buf, i64 %x, i8* %y, ...) {
153 ; CHECK-LABEL: @test_str_ok_size_musttail(
154 ; CHECK-NEXT:    %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...)
155 ; CHECK-NEXT:    ret i32 %1
157   %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...)
158   ret i32 %1
161 ; snprintf(buf, 32, "%s", "str") -> memcpy -> store
162 define i32 @test_str_ok_size_tail2(i8* %buf) {
163 ; CHECK-LABEL: @test_str_ok_size_tail2(
164 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i8* [[BUF:%.*]] to i32*
165 ; CHECK-NEXT:    store i32 7500915, i32* [[TMP1]], align 1
166 ; CHECK-NEXT:    ret i32 3
168   %1 = tail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, 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))
169   ret i32 %1
172 define i32 @test_str_ok_size_musttail2(i8* %buf, i64 %x, i8* %y, ...) {
173 ; CHECK-LABEL: @test_str_ok_size_musttail2(
174 ; CHECK-NEXT:    %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, 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), ...)
175 ; CHECK-NEXT:    ret i32 %1
177   %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, 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), ...)
178   ret i32 %1