Implement Debug helpers via Cell#159302
Conversation
|
|
|
Details; ModuleID = 'repro.95a4099cea1845-cgu.0'
source_filename = "repro.95a4099cea1845-cgu.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "arm64-apple-macosx11.0.0"
@alloc_fe2ddbdc622a788f5416063d1e8d8ad4 = private unnamed_addr constant [3 x i8] c" { ", align 1
@alloc_94b00be069aafad82a2c6df764237b82 = private unnamed_addr constant [2 x i8] c", ", align 1
@alloc_556e4180596b5b612bb6ed6c0cbb55e1 = private unnamed_addr constant [2 x i8] c": ", align 1
@alloc_3690db001d3db01550bdb6f3f450de28 = private unnamed_addr constant [3 x i8] c" {\0A", align 1
@alloc_f7ac0c356c6ac6fcd03badb685e09ca2 = private unnamed_addr constant [2 x i8] c",\0A", align 1
@alloc_bf0ef947d182249ea2203578272460c5 = private unnamed_addr constant [5 x i8] c"Point", align 1
@alloc_37f62a15fae368a2423b3a16c75adcc9 = private unnamed_addr constant [1 x i8] c"x", align 1
@alloc_cd51bc84b49b21a3fdb2800731f25c21 = private unnamed_addr constant [1 x i8] c"y", align 1
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>
; Function Attrs: uwtable
define align 8 ptr @_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr align 4 %value_fmt) unnamed_addr #0 {
start:
%_8 = alloca [32 x i8], align 8
%op = alloca [32 x i8], align 8
%_4 = alloca [1 x i8], align 1
%0 = getelementptr inbounds i8, ptr %self, i64 8
%1 = load i8, ptr %0, align 8
%self1 = trunc nuw i8 %1 to i1
store ptr %self, ptr %op, align 8
%2 = getelementptr inbounds i8, ptr %op, i64 8
store ptr %name.0, ptr %2, align 8
%3 = getelementptr inbounds i8, ptr %2, i64 8
store i64 %name.1, ptr %3, align 8
%4 = getelementptr inbounds i8, ptr %op, i64 24
store ptr %value_fmt, ptr %4, align 8
%_7 = zext i1 %self1 to i64
%5 = trunc nuw i64 %_7 to i1
br i1 %5, label %bb3, label %bb4
bb3: ; preds = %start
store i8 1, ptr %_4, align 1
br label %bb1
bb4: ; preds = %start
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_8, ptr align 8 %op, i64 32, i1 false)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>::{closure#0}
%6 = call zeroext i1 @_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmt0E0B1h_(ptr align 8 %_8) #4
%7 = zext i1 %6 to i8
store i8 %7, ptr %_4, align 1
br label %bb1
bb1: ; preds = %bb3, %bb4
%8 = getelementptr inbounds i8, ptr %self, i64 8
%9 = load i8, ptr %_4, align 1
%10 = trunc nuw i8 %9 to i1
%11 = zext i1 %10 to i8
store i8 %11, ptr %8, align 8
%12 = getelementptr inbounds i8, ptr %self, i64 9
store i8 1, ptr %12, align 1
ret ptr %self
bb2: ; No predecessors!
unreachable
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>
; Function Attrs: uwtable
define align 8 ptr @_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr align 4 %value_fmt) unnamed_addr #0 {
start:
%_8 = alloca [32 x i8], align 8
%op = alloca [32 x i8], align 8
%_4 = alloca [1 x i8], align 1
%0 = getelementptr inbounds i8, ptr %self, i64 8
%1 = load i8, ptr %0, align 8
%self1 = trunc nuw i8 %1 to i1
store ptr %self, ptr %op, align 8
%2 = getelementptr inbounds i8, ptr %op, i64 8
store ptr %name.0, ptr %2, align 8
%3 = getelementptr inbounds i8, ptr %2, i64 8
store i64 %name.1, ptr %3, align 8
%4 = getelementptr inbounds i8, ptr %op, i64 24
store ptr %value_fmt, ptr %4, align 8
%_7 = zext i1 %self1 to i64
%5 = trunc nuw i64 %_7 to i1
br i1 %5, label %bb3, label %bb4
bb3: ; preds = %start
store i8 1, ptr %_4, align 1
br label %bb1
bb4: ; preds = %start
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_8, ptr align 8 %op, i64 32, i1 false)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>::{closure#0}
%6 = call zeroext i1 @_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmts_0E0B1h_(ptr align 8 %_8) #4
%7 = zext i1 %6 to i8
store i8 %7, ptr %_4, align 1
br label %bb1
bb1: ; preds = %bb3, %bb4
%8 = getelementptr inbounds i8, ptr %self, i64 8
%9 = load i8, ptr %_4, align 1
%10 = trunc nuw i8 %9 to i1
%11 = zext i1 %10 to i8
store i8 %11, ptr %8, align 8
%12 = getelementptr inbounds i8, ptr %self, i64 9
store i8 1, ptr %12, align 1
ret ptr %self
bb2: ; No predecessors!
unreachable
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>::{closure#0}
; Function Attrs: inlinehint uwtable
define zeroext i1 @_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmt0E0B1h_(ptr align 8 %_1) unnamed_addr #1 personality ptr @rust_eh_personality {
start:
%0 = alloca [16 x i8], align 8
%_50 = alloca [1 x i8], align 1
%prefix = alloca [16 x i8], align 8
%writer = alloca [24 x i8], align 8
%state = alloca [1 x i8], align 1
%slot = alloca [24 x i8], align 8
%_0 = alloca [1 x i8], align 1
store i8 1, ptr %_50, align 1
%self = load ptr, ptr %_1, align 8
%_51 = load ptr, ptr %self, align 8
%1 = getelementptr inbounds i8, ptr %_51, i64 16
%_53 = load i32, ptr %1, align 8
%_52 = and i32 %_53, 8388608
%2 = icmp eq i32 %_52, 0
br i1 %2, label %bb11, label %bb1
bb11: ; preds = %start
%_40 = load ptr, ptr %_1, align 8
%3 = getelementptr inbounds i8, ptr %_40, i64 9
%4 = load i8, ptr %3, align 1
%_24 = trunc nuw i8 %4 to i1
br i1 %_24, label %bb12, label %bb13
bb1: ; preds = %start
%_34 = load ptr, ptr %_1, align 8
%5 = getelementptr inbounds i8, ptr %_34, i64 9
%6 = load i8, ptr %5, align 1
%_3 = trunc nuw i8 %6 to i1
br i1 %_3, label %bb5, label %bb2
bb13: ; preds = %bb11
store ptr @alloc_fe2ddbdc622a788f5416063d1e8d8ad4, ptr %prefix, align 8, !captures !4
%7 = getelementptr inbounds i8, ptr %prefix, i64 8
store i64 3, ptr %7, align 8
br label %bb14
bb12: ; preds = %bb11
store ptr @alloc_94b00be069aafad82a2c6df764237b82, ptr %prefix, align 8, !captures !4
%8 = getelementptr inbounds i8, ptr %prefix, i64 8
store i64 2, ptr %8, align 8
br label %bb14
bb14: ; preds = %bb12, %bb13
%_41 = load ptr, ptr %_1, align 8
%_42 = load ptr, ptr %_41, align 8
%9 = load ptr, ptr %prefix, align 8
%10 = getelementptr inbounds i8, ptr %prefix, i64 8
%11 = load i64, ptr %10, align 8
; invoke <core::fmt::Formatter>::write_str
%self1 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_42, ptr %9, i64 %11)
to label %bb15 unwind label %cleanup
bb24: ; preds = %cleanup
%12 = load i8, ptr %_50, align 1
%13 = trunc nuw i8 %12 to i1
br i1 %13, label %bb23, label %bb22
cleanup: ; preds = %bb32, %bb30, %bb28, %bb6, %bb5, %bb2, %bb38, %bb36, %bb34, %bb14
%14 = landingpad { ptr, i32 }
cleanup
%15 = extractvalue { ptr, i32 } %14, 0
%16 = extractvalue { ptr, i32 } %14, 1
store ptr %15, ptr %0, align 8
%17 = getelementptr inbounds i8, ptr %0, i64 8
store i32 %16, ptr %17, align 8
br label %bb24
bb15: ; preds = %bb14
%_66 = zext i1 %self1 to i64
%18 = trunc nuw i64 %_66 to i1
br i1 %18, label %bb33, label %bb34
bb33: ; preds = %bb15
store i8 1, ptr %_0, align 1
br label %bb20
bb34: ; preds = %bb15
%_43 = load ptr, ptr %_1, align 8
%_44 = load ptr, ptr %_43, align 8
%19 = getelementptr inbounds i8, ptr %_1, i64 8
%_45.0 = load ptr, ptr %19, align 8
%20 = getelementptr inbounds i8, ptr %19, i64 8
%_45.1 = load i64, ptr %20, align 8
; invoke <core::fmt::Formatter>::write_str
%self2 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_44, ptr %_45.0, i64 %_45.1)
to label %bb16 unwind label %cleanup
bb16: ; preds = %bb34
%_69 = zext i1 %self2 to i64
%21 = trunc nuw i64 %_69 to i1
br i1 %21, label %bb35, label %bb36
bb35: ; preds = %bb16
store i8 1, ptr %_0, align 1
br label %bb20
bb36: ; preds = %bb16
%_46 = load ptr, ptr %_1, align 8
%_47 = load ptr, ptr %_46, align 8
; invoke <core::fmt::Formatter>::write_str
%self3 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_47, ptr @alloc_556e4180596b5b612bb6ed6c0cbb55e1, i64 2)
to label %bb17 unwind label %cleanup
bb17: ; preds = %bb36
%_72 = zext i1 %self3 to i64
%22 = trunc nuw i64 %_72 to i1
br i1 %22, label %bb37, label %bb38
bb37: ; preds = %bb17
store i8 1, ptr %_0, align 1
br label %bb20
bb38: ; preds = %bb17
store i8 0, ptr %_50, align 1
%23 = getelementptr inbounds i8, ptr %_1, i64 24
%_31 = load ptr, ptr %23, align 8
%_48 = load ptr, ptr %_1, align 8
%_49 = load ptr, ptr %_48, align 8
; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#0}
%24 = invoke zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptr align 4 %_31, ptr align 8 %_49)
to label %bb18 unwind label %cleanup
bb18: ; preds = %bb38
%25 = zext i1 %24 to i8
store i8 %25, ptr %_0, align 1
br label %bb19
bb19: ; preds = %bb10, %bb18
br label %bb21
bb20: ; preds = %bb33, %bb35, %bb37
br label %bb40
bb40: ; preds = %bb39, %bb25, %bb20
br label %bb21
bb2: ; preds = %bb1
%_35 = load ptr, ptr %_1, align 8
%_36 = load ptr, ptr %_35, align 8
; invoke <core::fmt::Formatter>::write_str
%self4 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_36, ptr @alloc_3690db001d3db01550bdb6f3f450de28, i64 3)
to label %bb3 unwind label %cleanup
bb5: ; preds = %bb26, %bb1
store ptr null, ptr %slot, align 8
store i8 1, ptr %state, align 1
%_37 = load ptr, ptr %_1, align 8
%_38 = load ptr, ptr %_37, align 8
; invoke <core::fmt::builders::PadAdapter>::wrap
invoke void @_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptr sret([24 x i8]) align 8 %writer, ptr align 8 %_38, ptr align 8 %slot, ptr %state)
to label %bb6 unwind label %cleanup
bb3: ; preds = %bb2
%_54 = zext i1 %self4 to i64
%26 = trunc nuw i64 %_54 to i1
br i1 %26, label %bb25, label %bb26
bb25: ; preds = %bb3
store i8 1, ptr %_0, align 1
br label %bb40
bb26: ; preds = %bb3
br label %bb5
bb6: ; preds = %bb5
%27 = getelementptr inbounds i8, ptr %_1, i64 8
%_39.0 = load ptr, ptr %27, align 8
%28 = getelementptr inbounds i8, ptr %27, i64 8
%_39.1 = load i64, ptr %28, align 8
; invoke <core::fmt::Formatter>::write_str
%self5 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr %_39.0, i64 %_39.1)
to label %bb7 unwind label %cleanup
bb7: ; preds = %bb6
%_57 = zext i1 %self5 to i64
%29 = trunc nuw i64 %_57 to i1
br i1 %29, label %bb27, label %bb28
bb27: ; preds = %bb7
store i8 1, ptr %_0, align 1
br label %bb39
bb28: ; preds = %bb7
; invoke <core::fmt::Formatter>::write_str
%self6 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr @alloc_556e4180596b5b612bb6ed6c0cbb55e1, i64 2)
to label %bb8 unwind label %cleanup
bb8: ; preds = %bb28
%_60 = zext i1 %self6 to i64
%30 = trunc nuw i64 %_60 to i1
br i1 %30, label %bb29, label %bb30
bb29: ; preds = %bb8
store i8 1, ptr %_0, align 1
br label %bb39
bb30: ; preds = %bb8
store i8 0, ptr %_50, align 1
%31 = getelementptr inbounds i8, ptr %_1, i64 24
%_18 = load ptr, ptr %31, align 8
; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#0}
%self7 = invoke zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptr align 4 %_18, ptr align 8 %writer)
to label %bb9 unwind label %cleanup
bb9: ; preds = %bb30
%_63 = zext i1 %self7 to i64
%32 = trunc nuw i64 %_63 to i1
br i1 %32, label %bb31, label %bb32
bb31: ; preds = %bb9
store i8 1, ptr %_0, align 1
br label %bb21
bb32: ; preds = %bb9
; invoke <core::fmt::Formatter>::write_str
%33 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr @alloc_f7ac0c356c6ac6fcd03badb685e09ca2, i64 2)
to label %bb10 unwind label %cleanup
bb10: ; preds = %bb32
%34 = zext i1 %33 to i8
store i8 %34, ptr %_0, align 1
br label %bb19
bb21: ; preds = %bb40, %bb31, %bb19
%35 = load i8, ptr %_0, align 1
%36 = trunc nuw i8 %35 to i1
ret i1 %36
bb39: ; preds = %bb27, %bb29
br label %bb40
bb4: ; No predecessors!
unreachable
bb22: ; preds = %bb23, %bb24
%37 = load ptr, ptr %0, align 8
%38 = getelementptr inbounds i8, ptr %0, i64 8
%39 = load i32, ptr %38, align 8
%40 = insertvalue { ptr, i32 } poison, ptr %37, 0
%41 = insertvalue { ptr, i32 } %40, i32 %39, 1
resume { ptr, i32 } %41
bb23: ; preds = %bb24
br label %bb22
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>::{closure#0}
; Function Attrs: inlinehint uwtable
define zeroext i1 @_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmts_0E0B1h_(ptr align 8 %_1) unnamed_addr #1 personality ptr @rust_eh_personality {
start:
%0 = alloca [16 x i8], align 8
%_50 = alloca [1 x i8], align 1
%prefix = alloca [16 x i8], align 8
%writer = alloca [24 x i8], align 8
%state = alloca [1 x i8], align 1
%slot = alloca [24 x i8], align 8
%_0 = alloca [1 x i8], align 1
store i8 1, ptr %_50, align 1
%self = load ptr, ptr %_1, align 8
%_51 = load ptr, ptr %self, align 8
%1 = getelementptr inbounds i8, ptr %_51, i64 16
%_53 = load i32, ptr %1, align 8
%_52 = and i32 %_53, 8388608
%2 = icmp eq i32 %_52, 0
br i1 %2, label %bb11, label %bb1
bb11: ; preds = %start
%_40 = load ptr, ptr %_1, align 8
%3 = getelementptr inbounds i8, ptr %_40, i64 9
%4 = load i8, ptr %3, align 1
%_24 = trunc nuw i8 %4 to i1
br i1 %_24, label %bb12, label %bb13
bb1: ; preds = %start
%_34 = load ptr, ptr %_1, align 8
%5 = getelementptr inbounds i8, ptr %_34, i64 9
%6 = load i8, ptr %5, align 1
%_3 = trunc nuw i8 %6 to i1
br i1 %_3, label %bb5, label %bb2
bb13: ; preds = %bb11
store ptr @alloc_fe2ddbdc622a788f5416063d1e8d8ad4, ptr %prefix, align 8, !captures !4
%7 = getelementptr inbounds i8, ptr %prefix, i64 8
store i64 3, ptr %7, align 8
br label %bb14
bb12: ; preds = %bb11
store ptr @alloc_94b00be069aafad82a2c6df764237b82, ptr %prefix, align 8, !captures !4
%8 = getelementptr inbounds i8, ptr %prefix, i64 8
store i64 2, ptr %8, align 8
br label %bb14
bb14: ; preds = %bb12, %bb13
%_41 = load ptr, ptr %_1, align 8
%_42 = load ptr, ptr %_41, align 8
%9 = load ptr, ptr %prefix, align 8
%10 = getelementptr inbounds i8, ptr %prefix, i64 8
%11 = load i64, ptr %10, align 8
; invoke <core::fmt::Formatter>::write_str
%self1 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_42, ptr %9, i64 %11)
to label %bb15 unwind label %cleanup
bb24: ; preds = %cleanup
%12 = load i8, ptr %_50, align 1
%13 = trunc nuw i8 %12 to i1
br i1 %13, label %bb23, label %bb22
cleanup: ; preds = %bb32, %bb30, %bb28, %bb6, %bb5, %bb2, %bb38, %bb36, %bb34, %bb14
%14 = landingpad { ptr, i32 }
cleanup
%15 = extractvalue { ptr, i32 } %14, 0
%16 = extractvalue { ptr, i32 } %14, 1
store ptr %15, ptr %0, align 8
%17 = getelementptr inbounds i8, ptr %0, i64 8
store i32 %16, ptr %17, align 8
br label %bb24
bb15: ; preds = %bb14
%_66 = zext i1 %self1 to i64
%18 = trunc nuw i64 %_66 to i1
br i1 %18, label %bb33, label %bb34
bb33: ; preds = %bb15
store i8 1, ptr %_0, align 1
br label %bb20
bb34: ; preds = %bb15
%_43 = load ptr, ptr %_1, align 8
%_44 = load ptr, ptr %_43, align 8
%19 = getelementptr inbounds i8, ptr %_1, i64 8
%_45.0 = load ptr, ptr %19, align 8
%20 = getelementptr inbounds i8, ptr %19, i64 8
%_45.1 = load i64, ptr %20, align 8
; invoke <core::fmt::Formatter>::write_str
%self2 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_44, ptr %_45.0, i64 %_45.1)
to label %bb16 unwind label %cleanup
bb16: ; preds = %bb34
%_69 = zext i1 %self2 to i64
%21 = trunc nuw i64 %_69 to i1
br i1 %21, label %bb35, label %bb36
bb35: ; preds = %bb16
store i8 1, ptr %_0, align 1
br label %bb20
bb36: ; preds = %bb16
%_46 = load ptr, ptr %_1, align 8
%_47 = load ptr, ptr %_46, align 8
; invoke <core::fmt::Formatter>::write_str
%self3 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_47, ptr @alloc_556e4180596b5b612bb6ed6c0cbb55e1, i64 2)
to label %bb17 unwind label %cleanup
bb17: ; preds = %bb36
%_72 = zext i1 %self3 to i64
%22 = trunc nuw i64 %_72 to i1
br i1 %22, label %bb37, label %bb38
bb37: ; preds = %bb17
store i8 1, ptr %_0, align 1
br label %bb20
bb38: ; preds = %bb17
store i8 0, ptr %_50, align 1
%23 = getelementptr inbounds i8, ptr %_1, i64 24
%_31 = load ptr, ptr %23, align 8
%_48 = load ptr, ptr %_1, align 8
%_49 = load ptr, ptr %_48, align 8
; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#1}
%24 = invoke zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptr align 4 %_31, ptr align 8 %_49)
to label %bb18 unwind label %cleanup
bb18: ; preds = %bb38
%25 = zext i1 %24 to i8
store i8 %25, ptr %_0, align 1
br label %bb19
bb19: ; preds = %bb10, %bb18
br label %bb21
bb20: ; preds = %bb33, %bb35, %bb37
br label %bb40
bb40: ; preds = %bb39, %bb25, %bb20
br label %bb21
bb2: ; preds = %bb1
%_35 = load ptr, ptr %_1, align 8
%_36 = load ptr, ptr %_35, align 8
; invoke <core::fmt::Formatter>::write_str
%self4 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %_36, ptr @alloc_3690db001d3db01550bdb6f3f450de28, i64 3)
to label %bb3 unwind label %cleanup
bb5: ; preds = %bb26, %bb1
store ptr null, ptr %slot, align 8
store i8 1, ptr %state, align 1
%_37 = load ptr, ptr %_1, align 8
%_38 = load ptr, ptr %_37, align 8
; invoke <core::fmt::builders::PadAdapter>::wrap
invoke void @_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptr sret([24 x i8]) align 8 %writer, ptr align 8 %_38, ptr align 8 %slot, ptr %state)
to label %bb6 unwind label %cleanup
bb3: ; preds = %bb2
%_54 = zext i1 %self4 to i64
%26 = trunc nuw i64 %_54 to i1
br i1 %26, label %bb25, label %bb26
bb25: ; preds = %bb3
store i8 1, ptr %_0, align 1
br label %bb40
bb26: ; preds = %bb3
br label %bb5
bb6: ; preds = %bb5
%27 = getelementptr inbounds i8, ptr %_1, i64 8
%_39.0 = load ptr, ptr %27, align 8
%28 = getelementptr inbounds i8, ptr %27, i64 8
%_39.1 = load i64, ptr %28, align 8
; invoke <core::fmt::Formatter>::write_str
%self5 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr %_39.0, i64 %_39.1)
to label %bb7 unwind label %cleanup
bb7: ; preds = %bb6
%_57 = zext i1 %self5 to i64
%29 = trunc nuw i64 %_57 to i1
br i1 %29, label %bb27, label %bb28
bb27: ; preds = %bb7
store i8 1, ptr %_0, align 1
br label %bb39
bb28: ; preds = %bb7
; invoke <core::fmt::Formatter>::write_str
%self6 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr @alloc_556e4180596b5b612bb6ed6c0cbb55e1, i64 2)
to label %bb8 unwind label %cleanup
bb8: ; preds = %bb28
%_60 = zext i1 %self6 to i64
%30 = trunc nuw i64 %_60 to i1
br i1 %30, label %bb29, label %bb30
bb29: ; preds = %bb8
store i8 1, ptr %_0, align 1
br label %bb39
bb30: ; preds = %bb8
store i8 0, ptr %_50, align 1
%31 = getelementptr inbounds i8, ptr %_1, i64 24
%_18 = load ptr, ptr %31, align 8
; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#1}
%self7 = invoke zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptr align 4 %_18, ptr align 8 %writer)
to label %bb9 unwind label %cleanup
bb9: ; preds = %bb30
%_63 = zext i1 %self7 to i64
%32 = trunc nuw i64 %_63 to i1
br i1 %32, label %bb31, label %bb32
bb31: ; preds = %bb9
store i8 1, ptr %_0, align 1
br label %bb21
bb32: ; preds = %bb9
; invoke <core::fmt::Formatter>::write_str
%33 = invoke zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8 %writer, ptr @alloc_f7ac0c356c6ac6fcd03badb685e09ca2, i64 2)
to label %bb10 unwind label %cleanup
bb10: ; preds = %bb32
%34 = zext i1 %33 to i8
store i8 %34, ptr %_0, align 1
br label %bb19
bb21: ; preds = %bb40, %bb31, %bb19
%35 = load i8, ptr %_0, align 1
%36 = trunc nuw i8 %35 to i1
ret i1 %36
bb39: ; preds = %bb27, %bb29
br label %bb40
bb4: ; No predecessors!
unreachable
bb22: ; preds = %bb23, %bb24
%37 = load ptr, ptr %0, align 8
%38 = getelementptr inbounds i8, ptr %0, i64 8
%39 = load i32, ptr %38, align 8
%40 = insertvalue { ptr, i32 } poison, ptr %37, 0
%41 = insertvalue { ptr, i32 } %40, i32 %39, 1
resume { ptr, i32 } %41
bb23: ; preds = %bb24
br label %bb22
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#0}
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptr align 4 %_1, ptr align 8 %f) unnamed_addr #1 {
start:
; call <u32 as core::fmt::Debug>::fmt
%_0 = call zeroext i1 @_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptr align 4 %_1, ptr align 8 %f) #4
ret i1 %_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#1}
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptr align 4 %_1, ptr align 8 %f) unnamed_addr #1 {
start:
%_3 = getelementptr inbounds i8, ptr %_1, i64 4
; call <u32 as core::fmt::Debug>::fmt
%_0 = call zeroext i1 @_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptr align 4 %_3, ptr align 8 %f) #4
ret i1 %_0
}
; <repro::Point as core::fmt::Debug>::fmt
; Function Attrs: uwtable
define zeroext i1 @_RNvXCs36UsywoTqr_5reproNtB2_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt(ptr align 4 %self, ptr align 8 %f) unnamed_addr #0 {
start:
%_6 = alloca [16 x i8], align 8
; call <core::fmt::Formatter>::debug_struct
call void @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter12debug_struct(ptr sret([16 x i8]) align 8 %_6, ptr align 8 %f, ptr @alloc_bf0ef947d182249ea2203578272460c5, i64 5)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>
%_4 = call align 8 ptr @_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptr align 8 %_6, ptr @alloc_37f62a15fae368a2423b3a16c75adcc9, i64 1, ptr align 4 %self)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>
%_3 = call align 8 ptr @_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptr align 8 %_4, ptr @alloc_cd51bc84b49b21a3fdb2800731f25c21, i64 1, ptr align 4 %self)
; call <core::fmt::builders::DebugStruct>::finish
%_0 = call zeroext i1 @_RNvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB5_11DebugStruct6finish(ptr align 8 %_3)
ret i1 %_0
}
; <u32 as core::fmt::Debug>::fmt
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptr align 4 %self, ptr align 8 %f) unnamed_addr #1 {
start:
%_0 = alloca [1 x i8], align 1
%0 = getelementptr inbounds i8, ptr %f, i64 16
%_4 = load i32, ptr %0, align 8
%_3 = and i32 %_4, 33554432
%1 = icmp eq i32 %_3, 0
br i1 %1, label %bb2, label %bb1
bb2: ; preds = %start
%2 = getelementptr inbounds i8, ptr %f, i64 16
%_6 = load i32, ptr %2, align 8
%_5 = and i32 %_6, 67108864
%3 = icmp eq i32 %_5, 0
br i1 %3, label %bb4, label %bb3
bb1: ; preds = %start
; call <u32 as core::fmt::LowerHex>::fmt
%4 = call zeroext i1 @_RNvXsu_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8LowerHex3fmt(ptr align 4 %self, ptr align 8 %f)
%5 = zext i1 %4 to i8
store i8 %5, ptr %_0, align 1
br label %bb6
bb4: ; preds = %bb2
; call <u32 as core::fmt::Display>::fmt
%6 = call zeroext i1 @_RNvXs8_NtNtNtCs2xrpM2fV95l_4core3fmt3num3impmNtB9_7Display3fmt(ptr align 4 %self, ptr align 8 %f)
%7 = zext i1 %6 to i8
store i8 %7, ptr %_0, align 1
br label %bb5
bb3: ; preds = %bb2
; call <u32 as core::fmt::UpperHex>::fmt
%8 = call zeroext i1 @_RNvXsw_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8UpperHex3fmt(ptr align 4 %self, ptr align 8 %f)
%9 = zext i1 %8 to i8
store i8 %9, ptr %_0, align 1
br label %bb5
bb5: ; preds = %bb3, %bb4
br label %bb6
bb6: ; preds = %bb1, %bb5
%10 = load i8, ptr %_0, align 1
%11 = trunc nuw i8 %10 to i1
ret i1 %11
}
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #2
; Function Attrs: nounwind uwtable
declare i32 @rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #3
; <core::fmt::Formatter>::write_str
; Function Attrs: uwtable
declare zeroext i1 @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptr align 8, ptr, i64) unnamed_addr #0
; <core::fmt::builders::PadAdapter>::wrap
; Function Attrs: uwtable
declare void @_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptr sret([24 x i8]) align 8, ptr align 8, ptr align 8, ptr) unnamed_addr #0
; <core::fmt::Formatter>::debug_struct
; Function Attrs: uwtable
declare void @_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter12debug_struct(ptr sret([16 x i8]) align 8, ptr align 8, ptr, i64) unnamed_addr #0
; <core::fmt::builders::DebugStruct>::finish
; Function Attrs: uwtable
declare zeroext i1 @_RNvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB5_11DebugStruct6finish(ptr align 8) unnamed_addr #0
; <u32 as core::fmt::Display>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXs8_NtNtNtCs2xrpM2fV95l_4core3fmt3num3impmNtB9_7Display3fmt(ptr align 4, ptr align 8) unnamed_addr #0
; <u32 as core::fmt::UpperHex>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXsw_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8UpperHex3fmt(ptr align 4, ptr align 8) unnamed_addr #0
; <u32 as core::fmt::LowerHex>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXsu_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8LowerHex3fmt(ptr align 4, ptr align 8) unnamed_addr #0
attributes #0 = { uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #1 = { inlinehint uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { nounwind uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #4 = { inlinehint }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"uwtable", i32 2}
!2 = !{i32 7, !"frame-pointer", i32 1}
!3 = !{!"rustc version 1.99.0-nightly (77cf889bc 2026-07-12)"}
!4 = !{!"address", !"read_provenance"}
Details; ModuleID = 'repro.ada4be50ab0d3186-cgu.0'
source_filename = "repro.ada4be50ab0d3186-cgu.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "arm64-apple-macosx11.0.0"
@vtable.0 = private unnamed_addr constant <{ [24 x i8], ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr @_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmt0EB1w_3fmtB10_ }>, align 8
@vtable.1 = private unnamed_addr constant <{ [24 x i8], ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr @_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmts_0EB1w_3fmtB10_ }>, align 8
@alloc_bf0ef947d182249ea2203578272460c5 = private unnamed_addr constant [5 x i8] c"Point", align 1
@alloc_37f62a15fae368a2423b3a16c75adcc9 = private unnamed_addr constant [1 x i8] c"x", align 1
@alloc_cd51bc84b49b21a3fdb2800731f25c21 = private unnamed_addr constant [1 x i8] c"y", align 1
@alloc_67658ef8123446d70a96e7dbc7651d58 = private unnamed_addr constant [40 x i8] c"formatting closure called more than once", align 1
@alloc_703b1d677d4c28a67f1910a45c16864b = private unnamed_addr constant [33 x i8] c"library/core/src/fmt/builders.rs\00", align 1
@alloc_7fd203ad775cd664e43a5c0ae4634671 = private unnamed_addr constant <{ ptr, [16 x i8] }> <{ ptr @alloc_703b1d677d4c28a67f1910a45c16864b, [16 x i8] c" \00\00\00\00\00\00\00H\00\00\00\15\00\00\00" }>, align 8
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>
; Function Attrs: uwtable
define align 8 ptr @_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr align 4 %value_fmt) unnamed_addr #0 personality ptr @rust_eh_personality {
start:
%0 = alloca [16 x i8], align 8
%_6 = alloca [8 x i8], align 8
store ptr %value_fmt, ptr %_6, align 8
; invoke <core::fmt::builders::DebugStruct>::field
%_0 = invoke align 8 ptr @_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr %_6, ptr align 8 @vtable.0)
to label %bb1 unwind label %cleanup
bb3: ; preds = %cleanup
%1 = load ptr, ptr %0, align 8
%2 = getelementptr inbounds i8, ptr %0, i64 8
%3 = load i32, ptr %2, align 8
%4 = insertvalue { ptr, i32 } poison, ptr %1, 0
%5 = insertvalue { ptr, i32 } %4, i32 %3, 1
resume { ptr, i32 } %5
cleanup: ; preds = %start
%6 = landingpad { ptr, i32 }
cleanup
%7 = extractvalue { ptr, i32 } %6, 0
%8 = extractvalue { ptr, i32 } %6, 1
store ptr %7, ptr %0, align 8
%9 = getelementptr inbounds i8, ptr %0, i64 8
store i32 %8, ptr %9, align 8
br label %bb3
bb1: ; preds = %start
ret ptr %_0
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>
; Function Attrs: uwtable
define align 8 ptr @_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr align 4 %value_fmt) unnamed_addr #0 personality ptr @rust_eh_personality {
start:
%0 = alloca [16 x i8], align 8
%_6 = alloca [8 x i8], align 8
store ptr %value_fmt, ptr %_6, align 8
; invoke <core::fmt::builders::DebugStruct>::field
%_0 = invoke align 8 ptr @_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptr align 8 %self, ptr %name.0, i64 %name.1, ptr %_6, ptr align 8 @vtable.1)
to label %bb1 unwind label %cleanup
bb3: ; preds = %cleanup
%1 = load ptr, ptr %0, align 8
%2 = getelementptr inbounds i8, ptr %0, i64 8
%3 = load i32, ptr %2, align 8
%4 = insertvalue { ptr, i32 } poison, ptr %1, 0
%5 = insertvalue { ptr, i32 } %4, i32 %3, 1
resume { ptr, i32 } %5
cleanup: ; preds = %start
%6 = landingpad { ptr, i32 }
cleanup
%7 = extractvalue { ptr, i32 } %6, 0
%8 = extractvalue { ptr, i32 } %6, 1
store ptr %7, ptr %0, align 8
%9 = getelementptr inbounds i8, ptr %0, i64 8
store i32 %8, ptr %9, align 8
br label %bb3
bb1: ; preds = %start
ret ptr %_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#0}
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt0B4_(ptr align 4 %_1, ptr align 8 %f) unnamed_addr #1 {
start:
; call <u32 as core::fmt::Debug>::fmt
%_0 = call zeroext i1 @_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptr align 4 %_1, ptr align 8 %f) #4
ret i1 %_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#1}
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmts_0B4_(ptr align 4 %_1, ptr align 8 %f) unnamed_addr #1 {
start:
%_3 = getelementptr inbounds i8, ptr %_1, i64 4
; call <u32 as core::fmt::Debug>::fmt
%_0 = call zeroext i1 @_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptr align 4 %_3, ptr align 8 %f) #4
ret i1 %_0
}
; <repro::Point as core::fmt::Debug>::fmt
; Function Attrs: uwtable
define zeroext i1 @_RNvXCseUiCQVDuJCY_5reproNtB2_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt(ptr align 4 %self, ptr align 8 %f) unnamed_addr #0 {
start:
%_6 = alloca [16 x i8], align 8
; call <core::fmt::Formatter>::debug_struct
call void @_RNvMsa_NtCs1Jl4pBjAano_4core3fmtNtB5_9Formatter12debug_struct(ptr sret([16 x i8]) align 8 %_6, ptr align 8 %f, ptr @alloc_bf0ef947d182249ea2203578272460c5, i64 5)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>
%_4 = call align 8 ptr @_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptr align 8 %_6, ptr @alloc_37f62a15fae368a2423b3a16c75adcc9, i64 1, ptr align 4 %self)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>
%_3 = call align 8 ptr @_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptr align 8 %_4, ptr @alloc_cd51bc84b49b21a3fdb2800731f25c21, i64 1, ptr align 4 %self)
; call <core::fmt::builders::DebugStruct>::finish
%_0 = call zeroext i1 @_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct6finish(ptr align 8 %_3)
ret i1 %_0
}
; <core::fmt::builders::DebugOnce<<repro::Point as core::fmt::Debug>::fmt::{closure#0}> as core::fmt::Debug>::fmt
; Function Attrs: uwtable
define zeroext i1 @_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmt0EB1w_3fmtB10_(ptr align 8 %self, ptr align 8 %f) unnamed_addr #0 {
start:
%_3 = alloca [8 x i8], align 8
%0 = load ptr, ptr %self, align 8
store ptr %0, ptr %_3, align 8
store ptr null, ptr %self, align 8
%1 = load ptr, ptr %_3, align 8
%2 = ptrtoint ptr %1 to i64
%3 = icmp eq i64 %2, 0
%_5 = select i1 %3, i64 0, i64 1
%4 = trunc nuw i64 %_5 to i1
br i1 %4, label %bb3, label %bb2
bb3: ; preds = %start
%value_fmt = load ptr, ptr %_3, align 8
; call <repro::Point as core::fmt::Debug>::fmt::{closure#0}
%_0 = call zeroext i1 @_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt0B4_(ptr align 4 %value_fmt, ptr align 8 %f) #4
ret i1 %_0
bb2: ; preds = %start
; call core::panicking::panic_fmt
call void @_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr @alloc_67658ef8123446d70a96e7dbc7651d58, ptr inttoptr (i64 81 to ptr), ptr align 8 @alloc_7fd203ad775cd664e43a5c0ae4634671) #5
unreachable
bb1: ; No predecessors!
unreachable
}
; <core::fmt::builders::DebugOnce<<repro::Point as core::fmt::Debug>::fmt::{closure#1}> as core::fmt::Debug>::fmt
; Function Attrs: uwtable
define zeroext i1 @_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmts_0EB1w_3fmtB10_(ptr align 8 %self, ptr align 8 %f) unnamed_addr #0 {
start:
%_3 = alloca [8 x i8], align 8
%0 = load ptr, ptr %self, align 8
store ptr %0, ptr %_3, align 8
store ptr null, ptr %self, align 8
%1 = load ptr, ptr %_3, align 8
%2 = ptrtoint ptr %1 to i64
%3 = icmp eq i64 %2, 0
%_5 = select i1 %3, i64 0, i64 1
%4 = trunc nuw i64 %_5 to i1
br i1 %4, label %bb3, label %bb2
bb3: ; preds = %start
%value_fmt = load ptr, ptr %_3, align 8
; call <repro::Point as core::fmt::Debug>::fmt::{closure#1}
%_0 = call zeroext i1 @_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmts_0B4_(ptr align 4 %value_fmt, ptr align 8 %f) #4
ret i1 %_0
bb2: ; preds = %start
; call core::panicking::panic_fmt
call void @_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr @alloc_67658ef8123446d70a96e7dbc7651d58, ptr inttoptr (i64 81 to ptr), ptr align 8 @alloc_7fd203ad775cd664e43a5c0ae4634671) #5
unreachable
bb1: ; No predecessors!
unreachable
}
; <u32 as core::fmt::Debug>::fmt
; Function Attrs: inlinehint uwtable
define internal zeroext i1 @_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptr align 4 %self, ptr align 8 %f) unnamed_addr #1 {
start:
%_0 = alloca [1 x i8], align 1
%0 = getelementptr inbounds i8, ptr %f, i64 16
%_4 = load i32, ptr %0, align 8
%_3 = and i32 %_4, 33554432
%1 = icmp eq i32 %_3, 0
br i1 %1, label %bb2, label %bb1
bb2: ; preds = %start
%2 = getelementptr inbounds i8, ptr %f, i64 16
%_6 = load i32, ptr %2, align 8
%_5 = and i32 %_6, 67108864
%3 = icmp eq i32 %_5, 0
br i1 %3, label %bb4, label %bb3
bb1: ; preds = %start
; call <u32 as core::fmt::LowerHex>::fmt
%4 = call zeroext i1 @_RNvXsu_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8LowerHex3fmt(ptr align 4 %self, ptr align 8 %f)
%5 = zext i1 %4 to i8
store i8 %5, ptr %_0, align 1
br label %bb6
bb4: ; preds = %bb2
; call <u32 as core::fmt::Display>::fmt
%6 = call zeroext i1 @_RNvXs8_NtNtNtCs1Jl4pBjAano_4core3fmt3num3impmNtB9_7Display3fmt(ptr align 4 %self, ptr align 8 %f)
%7 = zext i1 %6 to i8
store i8 %7, ptr %_0, align 1
br label %bb5
bb3: ; preds = %bb2
; call <u32 as core::fmt::UpperHex>::fmt
%8 = call zeroext i1 @_RNvXsw_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8UpperHex3fmt(ptr align 4 %self, ptr align 8 %f)
%9 = zext i1 %8 to i8
store i8 %9, ptr %_0, align 1
br label %bb5
bb5: ; preds = %bb3, %bb4
br label %bb6
bb6: ; preds = %bb1, %bb5
%10 = load i8, ptr %_0, align 1
%11 = trunc nuw i8 %10 to i1
ret i1 %11
}
; Function Attrs: nounwind uwtable
declare i32 @rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #2
; <core::fmt::builders::DebugStruct>::field
; Function Attrs: uwtable
declare align 8 ptr @_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptr align 8, ptr, i64, ptr, ptr align 8) unnamed_addr #0
; <core::fmt::Formatter>::debug_struct
; Function Attrs: uwtable
declare void @_RNvMsa_NtCs1Jl4pBjAano_4core3fmtNtB5_9Formatter12debug_struct(ptr sret([16 x i8]) align 8, ptr align 8, ptr, i64) unnamed_addr #0
; <core::fmt::builders::DebugStruct>::finish
; Function Attrs: uwtable
declare zeroext i1 @_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct6finish(ptr align 8) unnamed_addr #0
; core::panicking::panic_fmt
; Function Attrs: cold noinline noreturn uwtable
declare void @_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr, ptr, ptr align 8) unnamed_addr #3
; <u32 as core::fmt::Display>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXs8_NtNtNtCs1Jl4pBjAano_4core3fmt3num3impmNtB9_7Display3fmt(ptr align 4, ptr align 8) unnamed_addr #0
; <u32 as core::fmt::UpperHex>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXsw_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8UpperHex3fmt(ptr align 4, ptr align 8) unnamed_addr #0
; <u32 as core::fmt::LowerHex>::fmt
; Function Attrs: uwtable
declare zeroext i1 @_RNvXsu_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8LowerHex3fmt(ptr align 4, ptr align 8) unnamed_addr #0
attributes #0 = { uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #1 = { inlinehint uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #2 = { nounwind uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #3 = { cold noinline noreturn uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" }
attributes #4 = { inlinehint }
attributes #5 = { noinline noreturn }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"uwtable", i32 2}
!2 = !{i32 7, !"frame-pointer", i32 1}
!3 = !{!"rustc version 1.99.0-dev"} |
Debug helpers that take closures with &mut dyn FnMut
|
r? me (happy to hand this back to @tgross35 if that’s preferred) @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Implement `Debug` helpers that take closures with `&mut dyn FnMut`
|
Oh thats fine @hanna-kruppe I just didn't know if you were in the rotation (I've only ever directly requested from 2 other people total in the past 🤣) |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (d43d144): comparison URL. Overall result: ❌✅ regressions and improvements - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (secondary 3.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary -2.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary -0.2%, secondary 0.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 491.202s -> 491.87s (0.14%) |
|
optional: As discussed in the other thread, since the pre-existing struct DebugOnce<F>(Cell<Option<F>>);
impl<F> fmt::Debug for DebugOnce<F>
where
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(x) = self.0.replace(None) {
return (x)(f);
}
Ok(())
}
}
// ...
pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self
where
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
{
self.field(name, &DebugOnce(Cell::new(Some(value_fmt))))
} |
No need, all yours :) |
|
@jmillikin could you help me understand why using this |
|
I wrote a bigger test program to compare the growth as number of
The "per field" column is just the extra lines of 6 vs 3 fields and 9 vs 6 fields divided by 3. Not sure why it's not an integer. Don't read too much into it. I also skimmed the LLVM IR generated for
I guess @jmillikin's approach side-steps the third problem by not involving closure trait objects. |
There was a problem hiding this comment.
By my measurements above, this PR does improve things significantly. But DebugStruct::field_with vs field still seems to be a ca 10x difference in LLVM IR per call site despite that improvement. I'd like to take the improvements anyway and try to squeeze out more gains in a follow up PR, but it looks like there's a runtime performance regression right now. So if you're up for it, I'd suggest trying the approach described by @jmillikin.
|
Reminder, once the PR becomes ready for a review, use |
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
8dd6849 to
b727274
Compare
Debug helpers that take closures with &mut dyn FnMutDebug helpers via Cell
|
@rustbot ready |
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Implement `Debug` helpers via `Cell`
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (fcf8e93): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary 1.0%, secondary 4.6%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 1.8%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 487.651s -> 489.459s (0.37%) |
| /// Wraps an `FnOnce` formatting closure in a type that implements [`fmt::Debug`] by calling the | ||
| /// closure, allowing the `*_with` builder methods to forward to their `&dyn fmt::Debug` | ||
| /// counterparts. |
There was a problem hiding this comment.
Nit: I think "a FnOnce" rather than "an" (at least, I read it as "a function once")
There was a problem hiding this comment.
Huh, guess this isn't the only case https://github.com/search?q=repo%3Arust-lang%2Frust+%2F%5Cban%3F+%60%3Ffn%2F&type=code. I guess some people read it as "an F N once"?
Also just realized this is internal documentation so doesn't matter, I was going to delete this comment but figured others might find it interesting.
There was a problem hiding this comment.
Yeah I've always read the Fn traits as "F N" but somehow I expand "fn" to function in my mind
There was a problem hiding this comment.
Is there any way we could reasonably cover this in a codegen test?
There was a problem hiding this comment.
I've asked myself that on other changes to reduce monomorphization, and I never came up with a satisfying answer. Matching against the structure of calling some shared monomorphic function is the closest thing, but that's not really reasonable because it's either way too unspecific or way too sensitive to details like function names.
|
I repeated the previous experiment with the
That's better but honestly still not great. Although a lot of the difference is due to debug info related overhead (the
And a lot of the remaining IR is the aforementioned (1) |
View all comments
Fixes #149745.
Following @jmillikin's suggestion, the builder logic now lives in the pre-existing non-generic methods taking
&dyn fmt::Debug(where it used to exist), and each*_withmethod wraps its closure in a privateDebugOncestruct that implementsDebugby calling the closure, so the body is compiled once.Just for context: A
dyn FnOncecan't be called behind a reference, hence theCell<Option<..>>stuff inDebugOnce.repro.rs
On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using
&mut dyn FnMutmeasured 372). Since the stable&dyn fmt::Debugmethods no longer go through any closure indirection, this should also avoid the potential runtime regression in thederive(Debug)microbenchmark.This was the only remaining blocker for stabilizing
debug_closure_helpers, so it should unblock #146099.