@@ -87,7 +87,6 @@ define void @write_src_between_call_and_memcpy() {
87
87
ret void
88
88
}
89
89
90
- ; TODO: This is a miscompile.
91
90
define void @throw_between_call_and_mempy (i8* dereferenceable (16 ) %dest.i8 ) {
92
91
; CHECK-LABEL: @throw_between_call_and_mempy(
93
92
; CHECK-NEXT: [[SRC:%.*]] = alloca [16 x i8], align 1
@@ -106,6 +105,64 @@ define void @throw_between_call_and_mempy(i8* dereferenceable(16) %dest.i8) {
106
105
ret void
107
106
}
108
107
108
+ define void @dest_is_gep_nounwind_call () {
109
+ ; CHECK-LABEL: @dest_is_gep_nounwind_call(
110
+ ; CHECK-NEXT: [[DEST:%.*]] = alloca [16 x i8], align 1
111
+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [8 x i8], align 1
112
+ ; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [8 x i8]* [[SRC]] to i8*
113
+ ; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
114
+ ; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]]) [[ATTR3:#.*]]
115
+ ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 8, i1 false)
116
+ ; CHECK-NEXT: ret void
117
+ ;
118
+ %dest = alloca [16 x i8 ]
119
+ %src = alloca [8 x i8 ]
120
+ %src.i8 = bitcast [8 x i8 ]* %src to i8*
121
+ %dest.i8 = getelementptr [16 x i8 ], [16 x i8 ]* %dest , i64 0 , i64 8
122
+ call void @accept_ptr (i8* %src.i8 ) nounwind
123
+ call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %dest.i8 , i8* %src.i8 , i64 8 , i1 false )
124
+ ret void
125
+ }
126
+
127
+ define void @dest_is_gep_may_throw_call () {
128
+ ; CHECK-LABEL: @dest_is_gep_may_throw_call(
129
+ ; CHECK-NEXT: [[DEST:%.*]] = alloca [16 x i8], align 1
130
+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [8 x i8], align 1
131
+ ; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [8 x i8]* [[SRC]] to i8*
132
+ ; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
133
+ ; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]])
134
+ ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 8, i1 false)
135
+ ; CHECK-NEXT: ret void
136
+ ;
137
+ %dest = alloca [16 x i8 ]
138
+ %src = alloca [8 x i8 ]
139
+ %src.i8 = bitcast [8 x i8 ]* %src to i8*
140
+ %dest.i8 = getelementptr [16 x i8 ], [16 x i8 ]* %dest , i64 0 , i64 8
141
+ call void @accept_ptr (i8* %src.i8 )
142
+ call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %dest.i8 , i8* %src.i8 , i64 8 , i1 false )
143
+ ret void
144
+ }
145
+
146
+ define void @dest_is_gep_requires_movement () {
147
+ ; CHECK-LABEL: @dest_is_gep_requires_movement(
148
+ ; CHECK-NEXT: [[DEST:%.*]] = alloca [16 x i8], align 1
149
+ ; CHECK-NEXT: [[SRC:%.*]] = alloca [8 x i8], align 1
150
+ ; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [8 x i8]* [[SRC]] to i8*
151
+ ; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]]) [[ATTR3]]
152
+ ; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
153
+ ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 8, i1 false)
154
+ ; CHECK-NEXT: ret void
155
+ ;
156
+ %dest = alloca [16 x i8 ]
157
+ %src = alloca [8 x i8 ]
158
+ %src.i8 = bitcast [8 x i8 ]* %src to i8*
159
+ call void @accept_ptr (i8* %src.i8 ) nounwind
160
+ %dest.i8 = getelementptr [16 x i8 ], [16 x i8 ]* %dest , i64 0 , i64 8
161
+ call void @llvm.memcpy.p0i8.p0i8.i64 (i8* %dest.i8 , i8* %src.i8 , i64 8 , i1 false )
162
+ ret void
163
+ }
164
+
109
165
declare void @may_throw ()
166
+ declare void @accept_ptr (i8* )
110
167
declare void @llvm.memcpy.p0i8.p0i8.i64 (i8* , i8* , i64 , i1 )
111
168
declare void @llvm.memset.p0i8.i64 (i8* , i8 , i64 , i1 )
0 commit comments