@@ -200,3 +200,101 @@ bb0(%0 : @owned $Optional<Klass>):
200200 return %2 : $Builtin.RawPointer
201201}
202202
203+ // -----------------------------------------------------------------------------
204+ // SILCombiner::optimizeAlignment
205+ //
206+ // Optimize Builtin.assumeAlignment -> pointer_to_address
207+ // -----------------------------------------------------------------------------
208+
209+ // Case #1. Literal zero = natural alignment
210+ // %1 = integer_literal $Builtin.Int64, 0
211+ // %2 = builtin "assumeAlignment"
212+ // (%0 : $Builtin.RawPointer, %1 : $Builtin.Int64) : $Builtin.RawPointer
213+ // %3 = pointer_to_address %2 : $Builtin.RawPointer to [align=1] $*Int
214+ //
215+ // Erases the `pointer_to_address` `[align=]` attribute:
216+ //
217+ // CHECK-LABEL: sil @$s8builtins20testNaturalAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
218+ // CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
219+ // CHECK-NOT: integer_literal
220+ // CHECK-NOT: builtin "assumeAlignment"
221+ // CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to $*T
222+ // CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
223+ // CHECK-LABEL: } // end sil function '$s8builtins20testNaturalAlignmentyxBp_xmtlF'
224+ sil @$s8builtins20testNaturalAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
225+ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
226+ debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
227+ debug_value %2 : $@thick T.Type, let, name "_1", argno 2
228+ %5 = integer_literal $Builtin.Word, 0
229+ %6 = builtin "assumeAlignment"(%1 : $Builtin.RawPointer, %5 : $Builtin.Word) : $Builtin.RawPointer
230+ debug_value %6 : $Builtin.RawPointer, let, name "alignedPointer"
231+ %8 = pointer_to_address %6 : $Builtin.RawPointer to [align=1] $*T
232+ copy_addr %8 to [initialization] %0 : $*T
233+ %10 = tuple ()
234+ return %10 : $()
235+ }
236+
237+ //
238+ // Case #2. Literal nonzero = forced alignment.
239+ //
240+ // %1 = integer_literal $Builtin.Int64, 16
241+ // %2 = builtin "assumeAlignment"
242+ // (%0 : $Builtin.RawPointer, %1 : $Builtin.Int64) : $Builtin.RawPointer
243+ // %3 = pointer_to_address %2 : $Builtin.RawPointer to [align=1] $*Int
244+ //
245+ // Promotes the `pointer_to_address` `[align=]` attribute to a higher value.
246+ //
247+ // CHECK-LABEL: sil @$s8builtins18testFixedAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
248+ // CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
249+ // CHECK-NOT: integer_literal
250+ // CHECK-NOT: builtin "assumeAlignment"
251+ // CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to [align=8] $*T
252+ // CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
253+ // CHECK-LABEL: } // end sil function '$s8builtins18testFixedAlignmentyxBp_xmtlF'
254+ sil @$s8builtins18testFixedAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
255+ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
256+ debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
257+ debug_value %2 : $@thick T.Type, let, name "_1", argno 2
258+ %5 = integer_literal $Builtin.Word, 8
259+ %6 = builtin "assumeAlignment"(%1 : $Builtin.RawPointer, %5 : $Builtin.Word) : $Builtin.RawPointer
260+ debug_value %6 : $Builtin.RawPointer, let, name "alignedPointer"
261+ %8 = pointer_to_address %6 : $Builtin.RawPointer to [align=1] $*T
262+ copy_addr %8 to [initialization] %0 : $*T
263+ %10 = tuple ()
264+ return %10 : $()
265+ }
266+
267+ // Case #3. Folded dynamic alignment
268+ //
269+ // %1 = builtin "alignof"<T>(%0 : $@thin T.Type) : $Builtin.Word
270+ // %2 = builtin "assumeAlignment"
271+ // (%0 : $Builtin.RawPointer, %1 : $Builtin.Int64) : $Builtin.RawPointer
272+ // %3 = pointer_to_address %2 : $Builtin.RawPointer to [align=1] $*T
273+ //
274+ // Erases the `pointer_to_address` `[align=]` attribute.
275+ //
276+ // CHECK-LABEL: sil @$s8builtins20testDynamicAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
277+ // CHECK: bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
278+ // CHECK-NOT: metatype
279+ // CHECK-NOT: builtin "alignOf"
280+ // CHECK-NOT: builtin "assumeAlignment"
281+ // CHECK: [[PTR:%.*]] = pointer_to_address %1 : $Builtin.RawPointer to $*T
282+ // CHECK: copy_addr [[PTR]] to [initialization] %0 : $*T
283+ // CHECK-LABEL: } // end sil function '$s8builtins20testDynamicAlignmentyxBp_xmtlF'
284+ sil @$s8builtins20testDynamicAlignmentyxBp_xmtlF : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> @out T {
285+ bb0(%0 : $*T, %1 : $Builtin.RawPointer, %2 : $@thick T.Type):
286+ debug_value %1 : $Builtin.RawPointer, let, name "rawPointer", argno 1
287+ debug_value %2 : $@thick T.Type, let, name "_1", argno 2
288+ %5 = metatype $@thick T.Type
289+ %6 = builtin "alignof"<T>(%5 : $@thick T.Type) : $Builtin.Word
290+ %7 = builtin "sextOrBitCast_Word_Int64"(%6 : $Builtin.Word) : $Builtin.Int64
291+ %8 = struct $Int (%7 : $Builtin.Int64)
292+ debug_value %8 : $Int, let, name "align"
293+ %10 = builtin "truncOrBitCast_Int64_Word"(%7 : $Builtin.Int64) : $Builtin.Word
294+ %11 = builtin "assumeAlignment"(%1 : $Builtin.RawPointer, %10 : $Builtin.Word) : $Builtin.RawPointer
295+ debug_value %11 : $Builtin.RawPointer, let, name "alignedPointer"
296+ %13 = pointer_to_address %11 : $Builtin.RawPointer to [align=1] $*T
297+ copy_addr %13 to [initialization] %0 : $*T
298+ %15 = tuple ()
299+ return %15 : $()
300+ }
0 commit comments