Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor codegen for Debug impls of C-like enums with many variants #114106

Open
wesleywiser opened this issue Jul 26, 2023 · 7 comments
Open

Poor codegen for Debug impls of C-like enums with many variants #114106

wesleywiser opened this issue Jul 26, 2023 · 7 comments
Assignees
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-heavy Issue: Problems and improvements with respect to binary size of generated code.

Comments

@wesleywiser
Copy link
Member

wesleywiser commented Jul 26, 2023

Take for instance nix::errno::Errno which has 132 variants. When passing -Copt-level=3:

llvm-ir
; <example::Errno as core::fmt::Debug>::fmt
; Function Attrs: nounwind nonlazybind
define noundef zeroext i1 @"_ZN51_$LT$example..Errno$u20$as$u20$core..fmt..Debug$GT$3fmt17h9b36b344bd3d49feE"(ptr noalias nocapture noundef readonly align 1 dereferenceable(1) %self, ptr noalias noundef align 8 dereferenceable(64) %f) unnamed_addr #0 {
start:
  %0 = load i8, ptr %self, align 1, !range !3, !noundef !4
  switch i8 %0, label %bb2 [
    i8 0, label %bb134
    i8 1, label %bb4
    i8 2, label %bb5
    i8 3, label %bb6
    i8 4, label %bb7
    i8 5, label %bb8
    i8 6, label %bb9
    i8 7, label %bb10
    i8 8, label %bb11
    i8 9, label %bb12
    i8 10, label %bb13
    i8 11, label %bb14
    i8 12, label %bb15
    i8 13, label %bb16
    i8 14, label %bb17
    i8 15, label %bb18
    i8 16, label %bb19
    i8 17, label %bb20
    i8 18, label %bb21
    i8 19, label %bb22
    i8 20, label %bb23
    i8 21, label %bb24
    i8 22, label %bb25
    i8 23, label %bb26
    i8 24, label %bb27
    i8 25, label %bb28
    i8 26, label %bb29
    i8 27, label %bb30
    i8 28, label %bb31
    i8 29, label %bb32
    i8 30, label %bb33
    i8 31, label %bb34
    i8 32, label %bb35
    i8 33, label %bb36
    i8 34, label %bb37
    i8 35, label %bb38
    i8 36, label %bb39
    i8 37, label %bb40
    i8 38, label %bb41
    i8 39, label %bb42
    i8 40, label %bb43
    i8 41, label %bb44
    i8 42, label %bb45
    i8 43, label %bb46
    i8 44, label %bb47
    i8 45, label %bb48
    i8 46, label %bb49
    i8 47, label %bb50
    i8 48, label %bb51
    i8 49, label %bb52
    i8 50, label %bb53
    i8 51, label %bb54
    i8 52, label %bb55
    i8 53, label %bb56
    i8 54, label %bb57
    i8 55, label %bb58
    i8 56, label %bb59
    i8 57, label %bb60
    i8 58, label %bb61
    i8 59, label %bb62
    i8 60, label %bb63
    i8 61, label %bb64
    i8 62, label %bb65
    i8 63, label %bb66
    i8 64, label %bb67
    i8 65, label %bb68
    i8 66, label %bb69
    i8 67, label %bb70
    i8 68, label %bb71
    i8 69, label %bb72
    i8 70, label %bb73
    i8 71, label %bb74
    i8 72, label %bb75
    i8 73, label %bb76
    i8 74, label %bb77
    i8 75, label %bb78
    i8 76, label %bb79
    i8 77, label %bb80
    i8 78, label %bb81
    i8 79, label %bb82
    i8 80, label %bb83
    i8 81, label %bb84
    i8 82, label %bb85
    i8 83, label %bb86
    i8 84, label %bb87
    i8 85, label %bb88
    i8 86, label %bb89
    i8 87, label %bb90
    i8 88, label %bb91
    i8 89, label %bb92
    i8 90, label %bb93
    i8 91, label %bb94
    i8 92, label %bb95
    i8 93, label %bb96
    i8 94, label %bb97
    i8 95, label %bb98
    i8 96, label %bb99
    i8 97, label %bb100
    i8 98, label %bb101
    i8 99, label %bb102
    i8 100, label %bb103
    i8 101, label %bb104
    i8 102, label %bb105
    i8 103, label %bb106
    i8 104, label %bb107
    i8 105, label %bb108
    i8 106, label %bb109
    i8 107, label %bb110
    i8 108, label %bb111
    i8 109, label %bb112
    i8 110, label %bb113
    i8 111, label %bb114
    i8 112, label %bb115
    i8 113, label %bb116
    i8 114, label %bb117
    i8 115, label %bb118
    i8 116, label %bb119
    i8 117, label %bb120
    i8 118, label %bb121
    i8 119, label %bb122
    i8 120, label %bb123
    i8 121, label %bb124
    i8 122, label %bb125
    i8 123, label %bb126
    i8 124, label %bb127
    i8 125, label %bb128
    i8 126, label %bb129
    i8 127, label %bb130
    i8 -128, label %bb131
    i8 -127, label %bb132
    i8 -126, label %bb133
    i8 -125, label %bb1
  ]

bb2:                                              ; preds = %start
  unreachable

bb4:                                              ; preds = %start
  br label %bb134

bb5:                                              ; preds = %start
  br label %bb134

bb6:                                              ; preds = %start
  br label %bb134

bb7:                                              ; preds = %start
  br label %bb134

bb8:                                              ; preds = %start
  br label %bb134

bb9:                                              ; preds = %start
  br label %bb134

bb10:                                             ; preds = %start
  br label %bb134

bb11:                                             ; preds = %start
  br label %bb134

bb12:                                             ; preds = %start
  br label %bb134

bb13:                                             ; preds = %start
  br label %bb134

bb14:                                             ; preds = %start
  br label %bb134

bb15:                                             ; preds = %start
  br label %bb134

bb16:                                             ; preds = %start
  br label %bb134

bb17:                                             ; preds = %start
  br label %bb134

bb18:                                             ; preds = %start
  br label %bb134

bb19:                                             ; preds = %start
  br label %bb134

bb20:                                             ; preds = %start
  br label %bb134

bb21:                                             ; preds = %start
  br label %bb134

bb22:                                             ; preds = %start
  br label %bb134

bb23:                                             ; preds = %start
  br label %bb134

bb24:                                             ; preds = %start
  br label %bb134

bb25:                                             ; preds = %start
  br label %bb134

bb26:                                             ; preds = %start
  br label %bb134

bb27:                                             ; preds = %start
  br label %bb134

bb28:                                             ; preds = %start
  br label %bb134

bb29:                                             ; preds = %start
  br label %bb134

bb30:                                             ; preds = %start
  br label %bb134

bb31:                                             ; preds = %start
  br label %bb134

bb32:                                             ; preds = %start
  br label %bb134

bb33:                                             ; preds = %start
  br label %bb134

bb34:                                             ; preds = %start
  br label %bb134

bb35:                                             ; preds = %start
  br label %bb134

bb36:                                             ; preds = %start
  br label %bb134

bb37:                                             ; preds = %start
  br label %bb134

bb38:                                             ; preds = %start
  br label %bb134

bb39:                                             ; preds = %start
  br label %bb134

bb40:                                             ; preds = %start
  br label %bb134

bb41:                                             ; preds = %start
  br label %bb134

bb42:                                             ; preds = %start
  br label %bb134

bb43:                                             ; preds = %start
  br label %bb134

bb44:                                             ; preds = %start
  br label %bb134

bb45:                                             ; preds = %start
  br label %bb134

bb46:                                             ; preds = %start
  br label %bb134

bb47:                                             ; preds = %start
  br label %bb134

bb48:                                             ; preds = %start
  br label %bb134

bb49:                                             ; preds = %start
  br label %bb134

bb50:                                             ; preds = %start
  br label %bb134

bb51:                                             ; preds = %start
  br label %bb134

bb52:                                             ; preds = %start
  br label %bb134

bb53:                                             ; preds = %start
  br label %bb134

bb54:                                             ; preds = %start
  br label %bb134

bb55:                                             ; preds = %start
  br label %bb134

bb56:                                             ; preds = %start
  br label %bb134

bb57:                                             ; preds = %start
  br label %bb134

bb58:                                             ; preds = %start
  br label %bb134

bb59:                                             ; preds = %start
  br label %bb134

bb60:                                             ; preds = %start
  br label %bb134

bb61:                                             ; preds = %start
  br label %bb134

bb62:                                             ; preds = %start
  br label %bb134

bb63:                                             ; preds = %start
  br label %bb134

bb64:                                             ; preds = %start
  br label %bb134

bb65:                                             ; preds = %start
  br label %bb134

bb66:                                             ; preds = %start
  br label %bb134

bb67:                                             ; preds = %start
  br label %bb134

bb68:                                             ; preds = %start
  br label %bb134

bb69:                                             ; preds = %start
  br label %bb134

bb70:                                             ; preds = %start
  br label %bb134

bb71:                                             ; preds = %start
  br label %bb134

bb72:                                             ; preds = %start
  br label %bb134

bb73:                                             ; preds = %start
  br label %bb134

bb74:                                             ; preds = %start
  br label %bb134

bb75:                                             ; preds = %start
  br label %bb134

bb76:                                             ; preds = %start
  br label %bb134

bb77:                                             ; preds = %start
  br label %bb134

bb78:                                             ; preds = %start
  br label %bb134

bb79:                                             ; preds = %start
  br label %bb134

bb80:                                             ; preds = %start
  br label %bb134

bb81:                                             ; preds = %start
  br label %bb134

bb82:                                             ; preds = %start
  br label %bb134

bb83:                                             ; preds = %start
  br label %bb134

bb84:                                             ; preds = %start
  br label %bb134

bb85:                                             ; preds = %start
  br label %bb134

bb86:                                             ; preds = %start
  br label %bb134

bb87:                                             ; preds = %start
  br label %bb134

bb88:                                             ; preds = %start
  br label %bb134

bb89:                                             ; preds = %start
  br label %bb134

bb90:                                             ; preds = %start
  br label %bb134

bb91:                                             ; preds = %start
  br label %bb134

bb92:                                             ; preds = %start
  br label %bb134

bb93:                                             ; preds = %start
  br label %bb134

bb94:                                             ; preds = %start
  br label %bb134

bb95:                                             ; preds = %start
  br label %bb134

bb96:                                             ; preds = %start
  br label %bb134

bb97:                                             ; preds = %start
  br label %bb134

bb98:                                             ; preds = %start
  br label %bb134

bb99:                                             ; preds = %start
  br label %bb134

bb100:                                            ; preds = %start
  br label %bb134

bb101:                                            ; preds = %start
  br label %bb134

bb102:                                            ; preds = %start
  br label %bb134

bb103:                                            ; preds = %start
  br label %bb134

bb104:                                            ; preds = %start
  br label %bb134

bb105:                                            ; preds = %start
  br label %bb134

bb106:                                            ; preds = %start
  br label %bb134

bb107:                                            ; preds = %start
  br label %bb134

bb108:                                            ; preds = %start
  br label %bb134

bb109:                                            ; preds = %start
  br label %bb134

bb110:                                            ; preds = %start
  br label %bb134

bb111:                                            ; preds = %start
  br label %bb134

bb112:                                            ; preds = %start
  br label %bb134

bb113:                                            ; preds = %start
  br label %bb134

bb114:                                            ; preds = %start
  br label %bb134

bb115:                                            ; preds = %start
  br label %bb134

bb116:                                            ; preds = %start
  br label %bb134

bb117:                                            ; preds = %start
  br label %bb134

bb118:                                            ; preds = %start
  br label %bb134

bb119:                                            ; preds = %start
  br label %bb134

bb120:                                            ; preds = %start
  br label %bb134

bb121:                                            ; preds = %start
  br label %bb134

bb122:                                            ; preds = %start
  br label %bb134

bb123:                                            ; preds = %start
  br label %bb134

bb124:                                            ; preds = %start
  br label %bb134

bb125:                                            ; preds = %start
  br label %bb134

bb126:                                            ; preds = %start
  br label %bb134

bb127:                                            ; preds = %start
  br label %bb134

bb128:                                            ; preds = %start
  br label %bb134

bb129:                                            ; preds = %start
  br label %bb134

bb130:                                            ; preds = %start
  br label %bb134

bb131:                                            ; preds = %start
  br label %bb134

bb132:                                            ; preds = %start
  br label %bb134

bb133:                                            ; preds = %start
  br label %bb134

bb1:                                              ; preds = %start
  br label %bb134

bb134:                                            ; preds = %start, %bb1, %bb133, %bb132, %bb131, %bb130, %bb129, %bb128, %bb127, %bb126, %bb125, %bb124, %bb123, %bb122, %bb121, %bb120, %bb119, %bb118, %bb117, %bb116, %bb115, %bb114, %bb113, %bb112, %bb111, %bb110, %bb109, %bb108, %bb107, %bb106, %bb105, %bb104, %bb103, %bb102, %bb101, %bb100, %bb99, %bb98, %bb97, %bb96, %bb95, %bb94, %bb93, %bb92, %bb91, %bb90, %bb89, %bb88, %bb87, %bb86, %bb85, %bb84, %bb83, %bb82, %bb81, %bb80, %bb79, %bb78, %bb77, %bb76, %bb75, %bb74, %bb73, %bb72, %bb71, %bb70, %bb69, %bb68, %bb67, %bb66, %bb65, %bb64, %bb63, %bb62, %bb61, %bb60, %bb59, %bb58, %bb57, %bb56, %bb55, %bb54, %bb53, %bb52, %bb51, %bb50, %bb49, %bb48, %bb47, %bb46, %bb45, %bb44, %bb43, %bb42, %bb41, %bb40, %bb39, %bb38, %bb37, %bb36, %bb35, %bb34, %bb33, %bb32, %bb31, %bb30, %bb29, %bb28, %bb27, %bb26, %bb25, %bb24, %bb23, %bb22, %bb21, %bb20, %bb19, %bb18, %bb17, %bb16, %bb15, %bb14, %bb13, %bb12, %bb11, %bb10, %bb9, %bb8, %bb7, %bb6, %bb5, %bb4
  %_3.sroa.135.0 = phi i64 [ 9, %bb1 ], [ 7, %bb133 ], [ 15, %bb132 ], [ 10, %bb131 ], [ 12, %bb130 ], [ 11, %bb129 ], [ 11, %bb128 ], [ 6, %bb127 ], [ 9, %bb126 ], [ 11, %bb125 ], [ 9, %bb124 ], [ 6, %bb123 ], [ 9, %bb122 ], [ 6, %bb121 ], [ 7, %bb120 ], [ 7, %bb119 ], [ 7, %bb118 ], [ 6, %bb117 ], [ 11, %bb116 ], [ 8, %bb115 ], [ 12, %bb114 ], [ 9, %bb113 ], [ 12, %bb112 ], [ 9, %bb111 ], [ 12, %bb110 ], [ 9, %bb109 ], [ 8, %bb108 ], [ 7, %bb107 ], [ 7, %bb106 ], [ 10, %bb105 ], [ 12, %bb104 ], [ 9, %bb103 ], [ 11, %bb102 ], [ 8, %bb101 ], [ 13, %bb100 ], [ 10, %bb99 ], [ 12, %bb98 ], [ 12, %bb97 ], [ 10, %bb96 ], [ 15, %bb95 ], [ 15, %bb94 ], [ 11, %bb93 ], [ 10, %bb92 ], [ 8, %bb91 ], [ 12, %bb90 ], [ 8, %bb89 ], [ 6, %bb88 ], [ 8, %bb87 ], [ 8, %bb86 ], [ 6, %bb85 ], [ 8, %bb84 ], [ 7, %bb83 ], [ 7, %bb82 ], [ 7, %bb81 ], [ 7, %bb80 ], [ 7, %bb79 ], [ 6, %bb78 ], [ 8, %bb77 ], [ 9, %bb76 ], [ 7, %bb75 ], [ 7, %bb74 ], [ 9, %bb73 ], [ 6, %bb72 ], [ 5, %bb71 ], [ 6, %bb70 ], [ 4, %bb69 ], [ 7, %bb68 ], [ 7, %bb67 ], [ 6, %bb66 ], [ 6, %bb65 ], [ 5, %bb64 ], [ 5, %bb63 ], [ 7, %bb62 ], [ 6, %bb61 ], [ 6, %bb60 ], [ 7, %bb59 ], [ 7, %bb58 ], [ 6, %bb57 ], [ 6, %bb56 ], [ 5, %bb55 ], [ 5, %bb54 ], [ 6, %bb53 ], [ 6, %bb52 ], [ 7, %bb51 ], [ 6, %bb50 ], [ 6, %bb49 ], [ 6, %bb48 ], [ 8, %bb47 ], [ 6, %bb46 ], [ 5, %bb45 ], [ 6, %bb44 ], [ 5, %bb43 ], [ 9, %bb42 ], [ 6, %bb41 ], [ 6, %bb40 ], [ 12, %bb39 ], [ 7, %bb38 ], [ 6, %bb37 ], [ 4, %bb36 ], [ 5, %bb35 ], [ 6, %bb34 ], [ 5, %bb33 ], [ 6, %bb32 ], [ 6, %bb31 ], [ 5, %bb30 ], [ 7, %bb29 ], [ 6, %bb28 ], [ 6, %bb27 ], [ 6, %bb26 ], [ 6, %bb25 ], [ 6, %bb24 ], [ 7, %bb23 ], [ 6, %bb22 ], [ 5, %bb21 ], [ 6, %bb20 ], [ 5, %bb19 ], [ 7, %bb18 ], [ 6, %bb17 ], [ 6, %bb16 ], [ 6, %bb15 ], [ 6, %bb14 ], [ 6, %bb13 ], [ 5, %bb12 ], [ 7, %bb11 ], [ 5, %bb10 ], [ 5, %bb9 ], [ 3, %bb8 ], [ 5, %bb7 ], [ 5, %bb6 ], [ 6, %bb5 ], [ 5, %bb4 ], [ 12, %start ]
  %_3.sroa.0.0 = phi ptr [ @alloc_eeeec90dba29775bdab7e5d8b2cb0355, %bb1 ], [ @alloc_b2966257a8ddc16adc71767cf5355c0b, %bb133 ], [ @alloc_38d47c498611f94c9b77481a9521b50b, %bb132 ], [ @alloc_e97612422e606a267463c474940daaaf, %bb131 ], [ @alloc_1685b860d57c20a4bb2090aa8ec3d72f, %bb130 ], [ @alloc_ad94dce71dc3943f9a9c4e3d5270371b, %bb129 ], [ @alloc_f1d202c0b4fc106d9cff99e09505e2ad, %bb128 ], [ @alloc_306701eddbce58119b3b452468e93bce, %bb127 ], [ @alloc_0d44e7c346ed8b0c54abae600d17883f, %bb126 ], [ @alloc_ce81fb960d0bc24749fb6d08ce7d6eaf, %bb125 ], [ @alloc_f92d97beb29ce5b2fada37971b57fbb2, %bb124 ], [ @alloc_a841989f0908480b181ad0c5abcfd68e, %bb123 ], [ @alloc_3d31068ff3e390fedfff0f812b0758d5, %bb122 ], [ @alloc_4a73cf61ecdfb06b8e4a08adceebcfe7, %bb121 ], [ @alloc_3e93dee092649f36ef58758f59c00094, %bb120 ], [ @alloc_2154a05f30b5c4831200572c2d3dab30, %bb119 ], [ @alloc_e4648413a87fcbab95e9f4571686a68d, %bb118 ], [ @alloc_4ab5a989f2022623ea1da48703f7f0bd, %bb117 ], [ @alloc_cf2d0d2856a8dd5bfcf40afd2d7b76e0, %bb116 ], [ @alloc_e2e0883fc1e4f0559ab4d2d7111e2922, %bb115 ], [ @alloc_6b19a2f72bfad61fe889042e59b4f67f, %bb114 ], [ @alloc_7abef68a189e3a7227af6f45c9ababfb, %bb113 ], [ @alloc_44e924003e74a16bc4fbdc8f7c4d0473, %bb112 ], [ @alloc_084da7b8bb6c075ce42a1d77b6c995ee, %bb111 ], [ @alloc_978ec0cb1924f1237f42007a79c519c4, %bb110 ], [ @alloc_4df2654afb1bc82031beadd281a36d0d, %bb109 ], [ @alloc_c5d8dae1133a9087a76df87c2d5ed81a, %bb108 ], [ @alloc_faae74309a203211323bc3327eb25264, %bb107 ], [ @alloc_34dc7edf149271d5a5b67eaf70023d0e, %bb106 ], [ @alloc_69e47bc266bacc5206a88f9fadcf9ec6, %bb105 ], [ @alloc_bb6002a14cc221cb091a29878e9508a5, %bb104 ], [ @alloc_9de36250f4a87fd97880c81cbf713309, %bb103 ], [ @alloc_5a2b78f7503004628f810781f9490c94, %bb102 ], [ @alloc_f2c3b2cac51e42fd971a324253febb13, %bb101 ], [ @alloc_dbca276093c054d8ae582acdce89067e, %bb100 ], [ @alloc_fbca4e93830943a32db7f0544291d7aa, %bb99 ], [ @alloc_3332711b35cc115dd6e0ea31d9faf09d, %bb98 ], [ @alloc_23a2b5b2e50f58b3b2ee5f4e3e9e2963, %bb97 ], [ @alloc_9b01972f1876c57567e9f91eaeac11c0, %bb96 ], [ @alloc_9351c29bf6440ce6cc1d1845b5b2239a, %bb95 ], [ @alloc_47506649da77a5b57506dead306e2262, %bb94 ], [ @alloc_32a5aa9c39e874a9077e926b86087f67, %bb93 ], [ @alloc_800983b72099bfc3abf962370abe5459, %bb92 ], [ @alloc_d1f02fa34d04bd4b912c0c8e2b5b9de6, %bb91 ], [ @alloc_2b516ee3757c032d8fcaaab47bdc82fc, %bb90 ], [ @alloc_86885d2f78b482de79d4322d24e4c411, %bb89 ], [ @alloc_675bba484e0ec186c533a4bd41bdb2c4, %bb88 ], [ @alloc_68ce7b92a59f96b9e4b322d0015566d5, %bb87 ], [ @alloc_5fbe7d2a6eb0974b5d6b9277c8ff292d, %bb86 ], [ @alloc_d8a7f9677534b52f0fedc4e0d3ac4a7f, %bb85 ], [ @alloc_5eee53aa540bac93f85b20a41c4136bb, %bb84 ], [ @alloc_ad2e799ecd66fe4eb367bf0cfe674da4, %bb83 ], [ @alloc_3f394c18d606ce36f2c50816a4c76e96, %bb82 ], [ @alloc_8718d28fb95e407cb1b53420fe73995a, %bb81 ], [ @alloc_8d476f9867546e010d6e0f0e9df2f10e, %bb80 ], [ @alloc_381a6f34b7bf5b9d95c448026655efd5, %bb79 ], [ @alloc_38a3703a08665e1172b160a08c52bf00, %bb78 ], [ @alloc_e6dd583da76751037d2f23e77b767378, %bb77 ], [ @alloc_85bba4fa26b4bc7d3af483aea8d53610, %bb76 ], [ @alloc_7057157759ac58a04dde0cb410735455, %bb75 ], [ @alloc_a2918dd88cad9f1065c1f1fd760d9807, %bb74 ], [ @alloc_be948f685de56bf71d50b73745f4ac60, %bb73 ], [ @alloc_9b9d5c7403c06c1b1893956c83187e72, %bb72 ], [ @alloc_d212a56767d4fb4d6607865d075729f8, %bb71 ], [ @alloc_4d938c510ebb651e82e8de4564215b72, %bb70 ], [ @alloc_28b6884878622fe718b239b613416571, %bb69 ], [ @alloc_9e83da2a1cc21915c62f8367c90fdadb, %bb68 ], [ @alloc_494c0a5ba61fbb7071ff748e4f1cb433, %bb67 ], [ @alloc_d9d5c1a3a4aa94c4d1ff7a160571061c, %bb66 ], [ @alloc_c36568b4b36c804e4870f1aa6bdf3a2a, %bb65 ], [ @alloc_66a462b7da34960c8beaefa60e208b11, %bb64 ], [ @alloc_9b7c24b73a05d66a1cd8ea616dddba58, %bb63 ], [ @alloc_928348b0fb8413d594c672ae38e90e22, %bb62 ], [ @alloc_1ce034ba68a18aae701ac601ad36bf22, %bb61 ], [ @alloc_d84eb78f389905ca0230de88458cb696, %bb60 ], [ @alloc_d9e4fde4db3281ab4c591fb20f834248, %bb59 ], [ @alloc_b4f3881bd3b5b5d43bf383cf86c486ed, %bb58 ], [ @alloc_0421b2104b61159b448eb1aaf9647256, %bb57 ], [ @alloc_723c4a58a17e4aae450d8d9957b22445, %bb56 ], [ @alloc_07b7fccd581de4a0f58043714c6bdb75, %bb55 ], [ @alloc_bbd696d7e836174617963e3a3b02c4bf, %bb54 ], [ @alloc_89a077ecdcb316fd3d18ea1802da26b1, %bb53 ], [ @alloc_2bf2316dde628223adb61e3b01869c64, %bb52 ], [ @alloc_f334c77768804055ec99d59fda099fb7, %bb51 ], [ @alloc_1cb2662dfdef045b8930644c453bf476, %bb50 ], [ @alloc_836b57fdf72146d7a3653eecc17a7200, %bb49 ], [ @alloc_6f36aa02338841494924dfd8849543f3, %bb48 ], [ @alloc_09d0693eba27d653ddd27e966fb83a8e, %bb47 ], [ @alloc_2939475bfabcad8c50c892fbf318f7dd, %bb46 ], [ @alloc_215d33806f4ba809a2b96795d1e7a0e6, %bb45 ], [ @alloc_0526207bb0c9401b11586abdea37a0ec, %bb44 ], [ @alloc_a82e52c8c91e88d90ecebbbba2dd9f9e, %bb43 ], [ @alloc_2603dd6381b9af60034e46608f8f66fc, %bb42 ], [ @alloc_01c4584c71d29ab89453b0c1dfa9f5c8, %bb41 ], [ @alloc_721e060f8ee21ebd020f01daad5f2975, %bb40 ], [ @alloc_de098db79b872822198968bbc383469f, %bb39 ], [ @alloc_dcb34ae2af2ce66e0e5dcfa999e3beb7, %bb38 ], [ @alloc_eb59d2b23a3d7b405fe7b10c3a0c3e5a, %bb37 ], [ @alloc_da0b686a5e1dc859499cae16431f96ae, %bb36 ], [ @alloc_2881bd0c21bd06bd22ebf60a0f3a2028, %bb35 ], [ @alloc_0c664ef1627eefa7120e5cb745bcf752, %bb34 ], [ @alloc_8563ec224e7b49c3c4502731d867c128, %bb33 ], [ @alloc_5b80a9cc4738a62be9f7d95c8d597dc7, %bb32 ], [ @alloc_28d4f003a3a8ed43710568c95fe9351a, %bb31 ], [ @alloc_3705aa602755f3be9a0919f381aa127f, %bb30 ], [ @alloc_351946230f087e85e556fe3b968b1981, %bb29 ], [ @alloc_c3301bc6520ccc9163bce47dddbff6b8, %bb28 ], [ @alloc_b00570ec474102351a8977332fa64d30, %bb27 ], [ @alloc_3b6bceff34f14ce8e4c2f343be15df26, %bb26 ], [ @alloc_31bae0bbf06c82dc196d425d3504b50d, %bb25 ], [ @alloc_8a55676c016656c683fd58df6cbbfcc8, %bb24 ], [ @alloc_e8207917a07ca92b599995c6bf68fdda, %bb23 ], [ @alloc_f1e9fdc6bc423e1edfbbcdf54c955cc1, %bb22 ], [ @alloc_bc821d93424984e9dcc8d410acb3401b, %bb21 ], [ @alloc_2dfe18e858cf93870a4cff1370e9c9b0, %bb20 ], [ @alloc_ff8994d9eba3e5343a9b53228010da31, %bb19 ], [ @alloc_f54eb14543977fe5fc802f49b30ccdca, %bb18 ], [ @alloc_8a8d12330b0edcc0ff37327ed998255f, %bb17 ], [ @alloc_3b2624a9f6c83698379a8f772e74bb38, %bb16 ], [ @alloc_f7b6042e65e87cd23a945053af86f2ef, %bb15 ], [ @alloc_82a96ddff67c3ec277e473895a80dd1e, %bb14 ], [ @alloc_98538349a2cd2820ed22bd9f0b9dc802, %bb13 ], [ @alloc_00ea1e26a59b8dc57996c8f8bd4a3717, %bb12 ], [ @alloc_bd057cb34460f661ef182ff156fc819e, %bb11 ], [ @alloc_42a580698ba93a37df51119b31cd88c1, %bb10 ], [ @alloc_6dedd2160d6d8f97ec4f1623b4302f7c, %bb9 ], [ @alloc_1ad3c9658acad47760e4c473a34c7d3b, %bb8 ], [ @alloc_ad0a99e246003c87ceb7d0f323ff2580, %bb7 ], [ @alloc_efa918ca8fd350104162f4b89715815c, %bb6 ], [ @alloc_56041ca6eaaf7e3ef282582e48dffd90, %bb5 ], [ @alloc_c0277d8038a6c64e72887cbcc884c3bb, %bb4 ], [ @alloc_94de12363f3ad82eb88f17c146010918, %start ]
; call core::fmt::Formatter::write_str
  %_0 = tail call noundef zeroext i1 @_ZN4core3fmt9Formatter9write_str17h8dee415c7bc221bcE(ptr noalias noundef nonnull align 8 dereferenceable(64) %f, ptr noalias noundef nonnull readonly align 1 %_3.sroa.0.0, i64 noundef %_3.sroa.135.0) #1
  ret i1 %_0
}

(godbolt)

Of note, the first case in the switch branches directly to bb134 while all others branch to their own basic block which immediately branches to bb134. I'm guessing some analysis in LLVM gives up on large switch terminators as removing 4 variants (so that there are exactly 128 cases) results in much more optimal IR:

; <example::Errno as core::fmt::Debug>::fmt
; Function Attrs: nounwind nonlazybind
define noundef zeroext i1 @"_ZN51_$LT$example..Errno$u20$as$u20$core..fmt..Debug$GT$3fmt17h0aaa260da578c4baE"(ptr noalias nocapture noundef readonly align 1 dereferenceable(1) %self, ptr noalias noundef align 8 dereferenceable(64) %f) unnamed_addr #0 {
start:
  %0 = load i8, ptr %self, align 1, !range !3, !noundef !4
  %_4 = zext i8 %0 to i64
  %switch.gep = getelementptr inbounds [128 x i64], ptr @"switch.table._ZN51_$LT$example..Errno$u20$as$u20$core..fmt..Debug$GT$3fmt17h0aaa260da578c4baE", i64 0, i64 %_4
  %switch.load = load i64, ptr %switch.gep, align 8
  %reltable.shift = shl i64 %_4, 2
  %reltable.intrinsic = call ptr @llvm.load.relative.i64(ptr @"reltable._ZN51_$LT$example..Errno$u20$as$u20$core..fmt..Debug$GT$3fmt17h0aaa260da578c4baE", i64 %reltable.shift)
; call core::fmt::Formatter::write_str
  %_0 = tail call noundef zeroext i1 @_ZN4core3fmt9Formatter9write_str17h8dee415c7bc221bcE(ptr noalias noundef nonnull align 8 dereferenceable(64) %f, ptr noalias noundef nonnull readonly align 1 %reltable.intrinsic, i64 noundef %switch.load) #2
  ret i1 %_0
}

(godbolt)

The impact on codesize is significant with the 132-variant version of <Errno as Debug>::fmt weighing in at 2,650 bytes and the 128-variant version occupying only 40 bytes.

@wesleywiser wesleywiser added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-heavy Issue: Problems and improvements with respect to binary size of generated code. labels Jul 26, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 26, 2023
@saethlin
Copy link
Member

It was even worse before #106884

We can probably get much better codegen and compile times by expanding to indexing into a &[&str] with the discriminant, which I think is what LLVM does for 4 or less blocks.

@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 27, 2023
@DaniPopes
Copy link
Contributor

@wesleywiser There is also another important difference between the two versions: all variants in the second enum have the default discriminant, meaning all valid values are 0..128 which Rustc uses to optimize the string lookup by creating a lookup table. You can see that this optimization vanishes if you set any discriminant manually: godbolt

@smmalis37
Copy link
Contributor

smmalis37 commented Jul 29, 2023

I wonder if part of the reason LLVM is having trouble here is the usage of an i8. Looking at the emitted IR you can see the values in the switch wrap around to -128. Could that be confusing its check for "continuousness"? Would casting the discriminant up to a bigger size so everything can stay positive change anything?

Of course it'd also be great if we had a solution to improve the situation here for non-continuous but still fieldless c-like enums. Would using something like a phf or some other lookup structure be an option?

@smmalis37
Copy link
Contributor

smmalis37 commented Jul 29, 2023

Actually I think I might be on to something. The optimization reappears at 256 variants https://godbolt.org/z/jd5WoqEWK

Putting a repr(i16) on an enum with fewer variants doesn't work however, as something still decides to truncate down to an i8 before the match, so the situation doesn't change.

@dianqk
Copy link
Member

dianqk commented Jul 30, 2023

I think this should be optimized to miss some edge cases.
Upstream issue: llvm/llvm-project#64231.

@Swatinem
Copy link
Contributor

Wow, this must be Karma, as I just experimented with a very similar case just yesterday, and documented all my finding on https://swatinem.de/blog/optimizing-enums/

The usecase I was looking at was enums with sparse discriminants, see rust-minidump/rust-minidump#847.

In my example, using sparse discriminants works up to a certain threshold (haven’t figured out which one exactly though)

// creates a lookup table with some empty/duplicate rows:
pub enum EnumLookup {
    A = 0,
    BB = 4,
    CCC,
    ABCD,
}

// creates a chain of conditional jumps:
pub enum EnumCmp {
    A = 0,
    BB = 200,
    CCC,
    ABCD,
}

As in my example the discriminants are very sparse, I was experimenting successfully with using a perfect hash function to transform the sparse discriminant into an dense index for lookup, see rust-minidump/rust-minidump#861

@dianqk
Copy link
Member

dianqk commented Aug 10, 2023

@rustbot claim

@workingjubilee workingjubilee added the C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such label Oct 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. C-optimization Category: An issue highlighting optimization opportunities or PRs implementing such I-heavy Issue: Problems and improvements with respect to binary size of generated code.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants