[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / snprintf.ll
blobeff9a42e814b10c6c1927eb3b966435ea8263107
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
9 declare i32 @snprintf(i8*, i64, i8*, ...) #1
11 define 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* noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 32, i8* [[FMT:%.*]])
14 ; CHECK-NEXT:    ret void
16   %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 32, i8* %fmt) #2
17   ret void
20 ; size is '0', do not add nonnull attribute
21 define void @test_not_const_fmt_zero_size_return_value(i8* %buf, i8* %fmt) #0 {
22 ; CHECK-LABEL: @test_not_const_fmt_zero_size_return_value(
23 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 0, i8* [[FMT:%.*]])
24 ; CHECK-NEXT:    ret void
26   %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* %fmt) #2
27   ret void
30 define 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
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
40 define i32 @test_return_value(i8* %buf) #0 {
41 ; CHECK-LABEL: @test_return_value(
42 ; CHECK-NEXT:    ret i32 3
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
48 define void @test_percentage(i8* %buf) #0 {
49 ; CHECK-LABEL: @test_percentage(
50 ; 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))
51 ; CHECK-NEXT:    ret void
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
57 define i32 @test_null_buf_return_value() #0 {
58 ; CHECK-LABEL: @test_null_buf_return_value(
59 ; CHECK-NEXT:    ret i32 3
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
65 define 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]]
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
75 define 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
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
85 define i32 @test_char_zero_size(i8* %buf) #0 {
86 ; CHECK-LABEL: @test_char_zero_size(
87 ; CHECK-NEXT:    ret i32 1
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
93 define 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* noundef nonnull dereferenceable(1) [[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]]
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
102 define 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
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
113 define i32 @test_str_zero_size(i8* %buf) #0 {
114 ; CHECK-LABEL: @test_str_zero_size(
115 ; CHECK-NEXT:    ret i32 3
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
121 define 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* 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))
124 ; CHECK-NEXT:    ret i32 [[CALL]]
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
130 define 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
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