2
2
; Test that the sprintf library call simplifier works correctly.
3
3
;
4
4
; RUN: opt < %s -instcombine -S | FileCheck %s
5
- ; RUN: opt < %s -mtriple xcore-xmos-elf -instcombine -S | FileCheck %s -check-prefix=CHECK-IPRINTF
5
+ ; RUN: opt < %s -mtriple xcore-xmos-elf -instcombine -S | FileCheck %s -check-prefixes=CHECK,CHECK-IPRINTF
6
+ ; RUN: opt < %s -mtriple=i386-pc-windows-msvc -instcombine -S | FileCheck %s --check-prefixes=CHECK,WIN
6
7
7
8
target 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
@@ -23,10 +24,6 @@ define void @test_simplify1(i8* %dst) {
23
24
; CHECK-LABEL: @test_simplify1(
24
25
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false)
25
26
; CHECK-NEXT: ret void
26
- ;
27
- ; CHECK-IPRINTF-LABEL: @test_simplify1(
28
- ; CHECK-IPRINTF-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false)
29
- ; CHECK-IPRINTF-NEXT: ret void
30
27
;
31
28
%fmt = getelementptr [13 x i8 ], [13 x i8 ]* @hello_world , i32 0 , i32 0
32
29
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt )
@@ -37,10 +34,6 @@ define void @test_simplify2(i8* %dst) {
37
34
; CHECK-LABEL: @test_simplify2(
38
35
; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1
39
36
; CHECK-NEXT: ret void
40
- ;
41
- ; CHECK-IPRINTF-LABEL: @test_simplify2(
42
- ; CHECK-IPRINTF-NEXT: store i8 0, i8* [[DST:%.*]], align 1
43
- ; CHECK-IPRINTF-NEXT: ret void
44
37
;
45
38
%fmt = getelementptr [1 x i8 ], [1 x i8 ]* @null , i32 0 , i32 0
46
39
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt )
@@ -51,10 +44,6 @@ define void @test_simplify3(i8* %dst) {
51
44
; CHECK-LABEL: @test_simplify3(
52
45
; CHECK-NEXT: store i8 0, i8* [[DST:%.*]], align 1
53
46
; CHECK-NEXT: ret void
54
- ;
55
- ; CHECK-IPRINTF-LABEL: @test_simplify3(
56
- ; CHECK-IPRINTF-NEXT: store i8 0, i8* [[DST:%.*]], align 1
57
- ; CHECK-IPRINTF-NEXT: ret void
58
47
;
59
48
%fmt = getelementptr [7 x i8 ], [7 x i8 ]* @null_hello , i32 0 , i32 0
60
49
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt )
@@ -69,32 +58,18 @@ define void @test_simplify4(i8* %dst) {
69
58
; CHECK-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[DST]], i32 1
70
59
; CHECK-NEXT: store i8 0, i8* [[NUL]], align 1
71
60
; CHECK-NEXT: ret void
72
- ;
73
- ; CHECK-IPRINTF-LABEL: @test_simplify4(
74
- ; CHECK-IPRINTF-NEXT: store i8 104, i8* [[DST:%.*]], align 1
75
- ; CHECK-IPRINTF-NEXT: [[NUL:%.*]] = getelementptr i8, i8* [[DST]], i32 1
76
- ; CHECK-IPRINTF-NEXT: store i8 0, i8* [[NUL]], align 1
77
- ; CHECK-IPRINTF-NEXT: ret void
78
61
;
79
62
%fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_c , i32 0 , i32 0
80
63
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8 104 )
81
64
ret void
82
65
}
83
66
84
- ; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen( str) + 1, 1) .
67
+ ; Check sprintf(dst, "%s", str) -> strcpy(dst, "%s", str) if result is unused .
85
68
86
69
define void @test_simplify5 (i8* %dst , i8* %str ) {
87
70
; CHECK-LABEL: @test_simplify5(
88
- ; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
89
- ; CHECK-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
90
- ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
71
+ ; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[STR:%.*]])
91
72
; CHECK-NEXT: ret void
92
- ;
93
- ; CHECK-IPRINTF-LABEL: @test_simplify5(
94
- ; CHECK-IPRINTF-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
95
- ; CHECK-IPRINTF-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
96
- ; CHECK-IPRINTF-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
97
- ; CHECK-IPRINTF-NEXT: ret void
98
73
;
99
74
%fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_s , i32 0 , i32 0
100
75
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8* %str )
@@ -104,27 +79,77 @@ define void @test_simplify5(i8* %dst, i8* %str) {
104
79
; Check sprintf(dst, format, ...) -> siprintf(str, format, ...) if no floating.
105
80
106
81
define void @test_simplify6 (i8* %dst ) {
107
- ; CHECK-LABEL: @test_simplify6(
108
- ; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
109
- ; CHECK-NEXT: ret void
110
- ;
111
82
; CHECK-IPRINTF-LABEL: @test_simplify6(
112
83
; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @siprintf(i8* [[DST:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
113
84
; CHECK-IPRINTF-NEXT: ret void
85
+ ;
86
+ ; WIN-LABEL: @test_simplify6(
87
+ ; WIN-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_d, i32 0, i32 0), i32 187)
88
+ ; WIN-NEXT: ret void
114
89
;
115
90
%fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_d , i32 0 , i32 0
116
91
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i32 187 )
117
92
ret void
118
93
}
119
94
95
+ ; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen(str) + 1, 1).
96
+
97
+ define i32 @test_simplify7 (i8* %dst , i8* %str ) {
98
+ ; CHECK-IPRINTF-LABEL: @test_simplify7(
99
+ ; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]])
100
+ ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32
101
+ ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32
102
+ ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]]
103
+ ; CHECK-IPRINTF-NEXT: ret i32 [[TMP3]]
104
+ ;
105
+ ; WIN-LABEL: @test_simplify7(
106
+ ; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
107
+ ; WIN-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
108
+ ; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
109
+ ; WIN-NEXT: ret i32 [[STRLEN]]
110
+ ;
111
+ %fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_s , i32 0 , i32 0
112
+ %r = call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8* %str )
113
+ ret i32 %r
114
+ }
115
+
116
+ ; Check sprintf(dst, "%s", str) -> llvm.memcpy(dest, str, strlen(str) + 1, 1).
117
+ define i32 @test_simplify8 (i8* %dst ) {
118
+ ; CHECK-LABEL: @test_simplify8(
119
+ ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(13) [[DST:%.*]], i8* nonnull align 1 dereferenceable(13) getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0), i32 13, i1 false)
120
+ ; CHECK-NEXT: ret i32 12
121
+ ;
122
+ %fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_s , i32 0 , i32 0
123
+ %str = getelementptr [13 x i8 ], [13 x i8 ]* @hello_world , i32 0 , i32 0
124
+ %r = call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8* %str )
125
+ ret i32 %r
126
+ }
127
+
128
+ ; Check sprintf(dst, "%s", str) -> stpcpy(dest, str) - dest
129
+
130
+ define i32 @test_simplify9 (i8* %dst , i8* %str ) {
131
+ ; CHECK-IPRINTF-LABEL: @test_simplify9(
132
+ ; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]])
133
+ ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32
134
+ ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32
135
+ ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]]
136
+ ; CHECK-IPRINTF-NEXT: ret i32 [[TMP3]]
137
+ ;
138
+ ; WIN-LABEL: @test_simplify9(
139
+ ; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* nonnull dereferenceable(1) [[STR:%.*]])
140
+ ; WIN-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1
141
+ ; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false)
142
+ ; WIN-NEXT: ret i32 [[STRLEN]]
143
+ ;
144
+ %fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_s , i32 0 , i32 0
145
+ %r = call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8* %str )
146
+ ret i32 %r
147
+ }
148
+
120
149
define void @test_no_simplify1 (i8* %dst ) {
121
150
; CHECK-LABEL: @test_no_simplify1(
122
151
; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
123
152
; CHECK-NEXT: ret void
124
- ;
125
- ; CHECK-IPRINTF-LABEL: @test_no_simplify1(
126
- ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_f, i32 0, i32 0), double 1.870000e+00)
127
- ; CHECK-IPRINTF-NEXT: ret void
128
153
;
129
154
%fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_f , i32 0 , i32 0
130
155
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , double 1 .87 )
@@ -135,11 +160,24 @@ define void @test_no_simplify2(i8* %dst, i8* %fmt, double %d) {
135
160
; CHECK-LABEL: @test_no_simplify2(
136
161
; CHECK-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
137
162
; CHECK-NEXT: ret void
138
- ;
139
- ; CHECK-IPRINTF-LABEL: @test_no_simplify2(
140
- ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) [[FMT:%.*]], double [[D:%.*]])
141
- ; CHECK-IPRINTF-NEXT: ret void
142
163
;
143
164
call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , double %d )
144
165
ret void
145
166
}
167
+
168
+ define i32 @test_no_simplify3 (i8* %dst , i8* %str ) minsize {
169
+ ; CHECK-IPRINTF-LABEL: @test_no_simplify3(
170
+ ; CHECK-IPRINTF-NEXT: [[STPCPY:%.*]] = call i8* @stpcpy(i8* [[DST:%.*]], i8* [[STR:%.*]])
171
+ ; CHECK-IPRINTF-NEXT: [[TMP1:%.*]] = ptrtoint i8* [[STPCPY]] to i32
172
+ ; CHECK-IPRINTF-NEXT: [[TMP2:%.*]] = ptrtoint i8* [[DST]] to i32
173
+ ; CHECK-IPRINTF-NEXT: [[TMP3:%.*]] = sub i32 [[TMP1]], [[TMP2]]
174
+ ; CHECK-IPRINTF-NEXT: ret i32 [[TMP3]]
175
+ ;
176
+ ; WIN-LABEL: @test_no_simplify3(
177
+ ; WIN-NEXT: [[R:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @percent_s, i32 0, i32 0), i8* [[STR:%.*]])
178
+ ; WIN-NEXT: ret i32 [[R]]
179
+ ;
180
+ %fmt = getelementptr [3 x i8 ], [3 x i8 ]* @percent_s , i32 0 , i32 0
181
+ %r = call i32 (i8* , i8* , ...) @sprintf (i8* %dst , i8* %fmt , i8* %str )
182
+ ret i32 %r
183
+ }
0 commit comments