compiler: Initialize union equality destinations

ef74a56898931f776511bf88a52317b3cfdff2767b35ba13117ba00eff92a9ab
Alexis Sellier committed ago 1 parent 9a2a5d6d
lib/std/lang/lower.rad +9 -18
4817 4817
    addPredecessor(self, mergeBlock, currentBlock(self));
4818 4818
4819 4819
    // Create comparison blocks for each non-void variant and build switch cases.
4820 4820
    // Void variants jump directly to merge with `true`.
4821 4821
    let trueArgs = try allocVal(self, il::Val::Imm(1));
4822 -
    let cases = try! alloc::allocRawSlice(
4823 -
        self.arena, @sizeOf(il::SwitchCase), @alignOf(il::SwitchCase), unionInfo.variants.len as u32
4824 -
    ) as *unsafe mut [il::SwitchCase];
4825 -
4826 -
    let mut caseBlocks: [?BlockId; resolver::MAX_UNION_VARIANTS] = undefined;
4822 +
    let mut cases: *unsafe mut [il::SwitchCase] = &mut [];
4827 4823
    for variant, i in unionInfo.variants {
4828 4824
        if variant.valueType == resolver::Type::Void {
4829 -
            set cases[i] = il::SwitchCase {
4825 +
            cases.append(il::SwitchCase {
4830 4826
                value: i as i64,
4831 4827
                target: *mergeBlock,
4832 4828
                args: trueArgs
4833 -
            };
4834 -
            set caseBlocks[i] = nil;
4829 +
            }, alloc::arenaAllocator(self.arena));
4835 4830
        } else {
4836 4831
            let payloadBlock = try createBlock(self, "eq#payload");
4837 -
            set cases[i] = il::SwitchCase {
4832 +
            cases.append(il::SwitchCase {
4838 4833
                value: i as i64,
4839 4834
                target: *payloadBlock,
4840 4835
                args: &mut []
4841 -
            };
4842 -
            set caseBlocks[i] = payloadBlock;
4836 +
            }, alloc::arenaAllocator(self.arena));
4843 4837
        }
4844 4838
    }
4845 4839
4846 4840
    // Emit switch in @tag block. Default arm is unreachable since we cover all variants.
4847 4841
    let unreachableBlock = try createBlock(self, "eq#unreachable");
4853 4847
        cases
4854 4848
    });
4855 4849
4856 4850
    // Add predecessor edges for switch targets.
4857 4851
    addPredecessor(self, unreachableBlock, tagBlock);
4858 -
    for i in 0..unionInfo.variants.len {
4859 -
        if let caseBlock = caseBlocks[i] {
4860 -
            addPredecessor(self, caseBlock, tagBlock);
4861 -
        } else {
4862 -
            addPredecessor(self, mergeBlock, tagBlock);
4863 -
        }
4852 +
    for c in cases {
4853 +
        addPredecessor(self, BlockId(c.target), tagBlock);
4864 4854
    }
4865 4855
    let valOffset = unionInfo.valOffset as i32;
4866 4856
4867 4857
    // Emit payload comparison blocks for non-void variants.
4868 4858
    for variant, i in unionInfo.variants {
4869 -
        if let caseBlock = caseBlocks[i] {
4859 +
        let caseBlock = BlockId(cases[i].target);
4860 +
        if caseBlock <> mergeBlock {
4870 4861
            try switchToAndSeal(self, caseBlock);
4871 4862
            let payloadEq = try emitEqAtOffset(
4872 4863
                self, a, b, offset + valOffset, variant.valueType
4873 4864
            );
4874 4865
            try emitJmpWithArg(self, mergeBlock, payloadEq);
test/tests/union.equality.capacity.rad added +411 -0
1 +
//! returns: 0
2 +
//! Union equality handles every supported tag with mixed payload storage.
3 +
4 +
/// Union with the maximum supported variant count.
5 +
union Many: Copy {
6 +
    /// Variant 0 without a payload.
7 +
    V0,
8 +
    /// Variant 1 with a numeric payload.
9 +
    V1(u32),
10 +
    /// Variant 2 without a payload.
11 +
    V2,
12 +
    /// Variant 3 with a numeric payload.
13 +
    V3(u32),
14 +
    /// Variant 4 without a payload.
15 +
    V4,
16 +
    /// Variant 5 with a numeric payload.
17 +
    V5(u32),
18 +
    /// Variant 6 without a payload.
19 +
    V6,
20 +
    /// Variant 7 with a numeric payload.
21 +
    V7(u32),
22 +
    /// Variant 8 without a payload.
23 +
    V8,
24 +
    /// Variant 9 with a numeric payload.
25 +
    V9(u32),
26 +
    /// Variant 10 without a payload.
27 +
    V10,
28 +
    /// Variant 11 with a numeric payload.
29 +
    V11(u32),
30 +
    /// Variant 12 without a payload.
31 +
    V12,
32 +
    /// Variant 13 with a numeric payload.
33 +
    V13(u32),
34 +
    /// Variant 14 without a payload.
35 +
    V14,
36 +
    /// Variant 15 with a numeric payload.
37 +
    V15(u32),
38 +
    /// Variant 16 without a payload.
39 +
    V16,
40 +
    /// Variant 17 with a numeric payload.
41 +
    V17(u32),
42 +
    /// Variant 18 without a payload.
43 +
    V18,
44 +
    /// Variant 19 with a numeric payload.
45 +
    V19(u32),
46 +
    /// Variant 20 without a payload.
47 +
    V20,
48 +
    /// Variant 21 with a numeric payload.
49 +
    V21(u32),
50 +
    /// Variant 22 without a payload.
51 +
    V22,
52 +
    /// Variant 23 with a numeric payload.
53 +
    V23(u32),
54 +
    /// Variant 24 without a payload.
55 +
    V24,
56 +
    /// Variant 25 with a numeric payload.
57 +
    V25(u32),
58 +
    /// Variant 26 without a payload.
59 +
    V26,
60 +
    /// Variant 27 with a numeric payload.
61 +
    V27(u32),
62 +
    /// Variant 28 without a payload.
63 +
    V28,
64 +
    /// Variant 29 with a numeric payload.
65 +
    V29(u32),
66 +
    /// Variant 30 without a payload.
67 +
    V30,
68 +
    /// Variant 31 with a numeric payload.
69 +
    V31(u32),
70 +
    /// Variant 32 without a payload.
71 +
    V32,
72 +
    /// Variant 33 with a numeric payload.
73 +
    V33(u32),
74 +
    /// Variant 34 without a payload.
75 +
    V34,
76 +
    /// Variant 35 with a numeric payload.
77 +
    V35(u32),
78 +
    /// Variant 36 without a payload.
79 +
    V36,
80 +
    /// Variant 37 with a numeric payload.
81 +
    V37(u32),
82 +
    /// Variant 38 without a payload.
83 +
    V38,
84 +
    /// Variant 39 with a numeric payload.
85 +
    V39(u32),
86 +
    /// Variant 40 without a payload.
87 +
    V40,
88 +
    /// Variant 41 with a numeric payload.
89 +
    V41(u32),
90 +
    /// Variant 42 without a payload.
91 +
    V42,
92 +
    /// Variant 43 with a numeric payload.
93 +
    V43(u32),
94 +
    /// Variant 44 without a payload.
95 +
    V44,
96 +
    /// Variant 45 with a numeric payload.
97 +
    V45(u32),
98 +
    /// Variant 46 without a payload.
99 +
    V46,
100 +
    /// Variant 47 with a numeric payload.
101 +
    V47(u32),
102 +
    /// Variant 48 without a payload.
103 +
    V48,
104 +
    /// Variant 49 with a numeric payload.
105 +
    V49(u32),
106 +
    /// Variant 50 without a payload.
107 +
    V50,
108 +
    /// Variant 51 with a numeric payload.
109 +
    V51(u32),
110 +
    /// Variant 52 without a payload.
111 +
    V52,
112 +
    /// Variant 53 with a numeric payload.
113 +
    V53(u32),
114 +
    /// Variant 54 without a payload.
115 +
    V54,
116 +
    /// Variant 55 with a numeric payload.
117 +
    V55(u32),
118 +
    /// Variant 56 without a payload.
119 +
    V56,
120 +
    /// Variant 57 with a numeric payload.
121 +
    V57(u32),
122 +
    /// Variant 58 without a payload.
123 +
    V58,
124 +
    /// Variant 59 with a numeric payload.
125 +
    V59(u32),
126 +
    /// Variant 60 without a payload.
127 +
    V60,
128 +
    /// Variant 61 with a numeric payload.
129 +
    V61(u32),
130 +
    /// Variant 62 without a payload.
131 +
    V62,
132 +
    /// Variant 63 with a numeric payload.
133 +
    V63(u32),
134 +
    /// Variant 64 without a payload.
135 +
    V64,
136 +
    /// Variant 65 with a numeric payload.
137 +
    V65(u32),
138 +
    /// Variant 66 without a payload.
139 +
    V66,
140 +
    /// Variant 67 with a numeric payload.
141 +
    V67(u32),
142 +
    /// Variant 68 without a payload.
143 +
    V68,
144 +
    /// Variant 69 with a numeric payload.
145 +
    V69(u32),
146 +
    /// Variant 70 without a payload.
147 +
    V70,
148 +
    /// Variant 71 with a numeric payload.
149 +
    V71(u32),
150 +
    /// Variant 72 without a payload.
151 +
    V72,
152 +
    /// Variant 73 with a numeric payload.
153 +
    V73(u32),
154 +
    /// Variant 74 without a payload.
155 +
    V74,
156 +
    /// Variant 75 with a numeric payload.
157 +
    V75(u32),
158 +
    /// Variant 76 without a payload.
159 +
    V76,
160 +
    /// Variant 77 with a numeric payload.
161 +
    V77(u32),
162 +
    /// Variant 78 without a payload.
163 +
    V78,
164 +
    /// Variant 79 with a numeric payload.
165 +
    V79(u32),
166 +
    /// Variant 80 without a payload.
167 +
    V80,
168 +
    /// Variant 81 with a numeric payload.
169 +
    V81(u32),
170 +
    /// Variant 82 without a payload.
171 +
    V82,
172 +
    /// Variant 83 with a numeric payload.
173 +
    V83(u32),
174 +
    /// Variant 84 without a payload.
175 +
    V84,
176 +
    /// Variant 85 with a numeric payload.
177 +
    V85(u32),
178 +
    /// Variant 86 without a payload.
179 +
    V86,
180 +
    /// Variant 87 with a numeric payload.
181 +
    V87(u32),
182 +
    /// Variant 88 without a payload.
183 +
    V88,
184 +
    /// Variant 89 with a numeric payload.
185 +
    V89(u32),
186 +
    /// Variant 90 without a payload.
187 +
    V90,
188 +
    /// Variant 91 with a numeric payload.
189 +
    V91(u32),
190 +
    /// Variant 92 without a payload.
191 +
    V92,
192 +
    /// Variant 93 with a numeric payload.
193 +
    V93(u32),
194 +
    /// Variant 94 without a payload.
195 +
    V94,
196 +
    /// Variant 95 with a numeric payload.
197 +
    V95(u32),
198 +
    /// Variant 96 without a payload.
199 +
    V96,
200 +
    /// Variant 97 with a numeric payload.
201 +
    V97(u32),
202 +
    /// Variant 98 without a payload.
203 +
    V98,
204 +
    /// Variant 99 with a numeric payload.
205 +
    V99(u32),
206 +
    /// Variant 100 without a payload.
207 +
    V100,
208 +
    /// Variant 101 with a numeric payload.
209 +
    V101(u32),
210 +
    /// Variant 102 without a payload.
211 +
    V102,
212 +
    /// Variant 103 with a numeric payload.
213 +
    V103(u32),
214 +
    /// Variant 104 without a payload.
215 +
    V104,
216 +
    /// Variant 105 with a numeric payload.
217 +
    V105(u32),
218 +
    /// Variant 106 without a payload.
219 +
    V106,
220 +
    /// Variant 107 with a numeric payload.
221 +
    V107(u32),
222 +
    /// Variant 108 without a payload.
223 +
    V108,
224 +
    /// Variant 109 with a numeric payload.
225 +
    V109(u32),
226 +
    /// Variant 110 without a payload.
227 +
    V110,
228 +
    /// Variant 111 with a numeric payload.
229 +
    V111(u32),
230 +
    /// Variant 112 without a payload.
231 +
    V112,
232 +
    /// Variant 113 with a numeric payload.
233 +
    V113(u32),
234 +
    /// Variant 114 without a payload.
235 +
    V114,
236 +
    /// Variant 115 with a numeric payload.
237 +
    V115(u32),
238 +
    /// Variant 116 without a payload.
239 +
    V116,
240 +
    /// Variant 117 with a numeric payload.
241 +
    V117(u32),
242 +
    /// Variant 118 without a payload.
243 +
    V118,
244 +
    /// Variant 119 with a numeric payload.
245 +
    V119(u32),
246 +
    /// Variant 120 without a payload.
247 +
    V120,
248 +
    /// Variant 121 with a numeric payload.
249 +
    V121(u32),
250 +
    /// Variant 122 without a payload.
251 +
    V122,
252 +
    /// Variant 123 with a numeric payload.
253 +
    V123(u32),
254 +
    /// Variant 124 without a payload.
255 +
    V124,
256 +
    /// Variant 125 with a numeric payload.
257 +
    V125(u32),
258 +
    /// Variant 126 without a payload.
259 +
    V126,
260 +
    /// Variant 127 with a numeric payload.
261 +
    V127(u32),
262 +
}
263 +
264 +
/// Construct the selected variant and payload.
265 +
fn value(tag: u32, payload: u32) -> Many {
266 +
    match tag {
267 +
        case 0 => return Many::V0(),
268 +
        case 1 => return Many::V1(payload),
269 +
        case 2 => return Many::V2(),
270 +
        case 3 => return Many::V3(payload),
271 +
        case 4 => return Many::V4(),
272 +
        case 5 => return Many::V5(payload),
273 +
        case 6 => return Many::V6(),
274 +
        case 7 => return Many::V7(payload),
275 +
        case 8 => return Many::V8(),
276 +
        case 9 => return Many::V9(payload),
277 +
        case 10 => return Many::V10(),
278 +
        case 11 => return Many::V11(payload),
279 +
        case 12 => return Many::V12(),
280 +
        case 13 => return Many::V13(payload),
281 +
        case 14 => return Many::V14(),
282 +
        case 15 => return Many::V15(payload),
283 +
        case 16 => return Many::V16(),
284 +
        case 17 => return Many::V17(payload),
285 +
        case 18 => return Many::V18(),
286 +
        case 19 => return Many::V19(payload),
287 +
        case 20 => return Many::V20(),
288 +
        case 21 => return Many::V21(payload),
289 +
        case 22 => return Many::V22(),
290 +
        case 23 => return Many::V23(payload),
291 +
        case 24 => return Many::V24(),
292 +
        case 25 => return Many::V25(payload),
293 +
        case 26 => return Many::V26(),
294 +
        case 27 => return Many::V27(payload),
295 +
        case 28 => return Many::V28(),
296 +
        case 29 => return Many::V29(payload),
297 +
        case 30 => return Many::V30(),
298 +
        case 31 => return Many::V31(payload),
299 +
        case 32 => return Many::V32(),
300 +
        case 33 => return Many::V33(payload),
301 +
        case 34 => return Many::V34(),
302 +
        case 35 => return Many::V35(payload),
303 +
        case 36 => return Many::V36(),
304 +
        case 37 => return Many::V37(payload),
305 +
        case 38 => return Many::V38(),
306 +
        case 39 => return Many::V39(payload),
307 +
        case 40 => return Many::V40(),
308 +
        case 41 => return Many::V41(payload),
309 +
        case 42 => return Many::V42(),
310 +
        case 43 => return Many::V43(payload),
311 +
        case 44 => return Many::V44(),
312 +
        case 45 => return Many::V45(payload),
313 +
        case 46 => return Many::V46(),
314 +
        case 47 => return Many::V47(payload),
315 +
        case 48 => return Many::V48(),
316 +
        case 49 => return Many::V49(payload),
317 +
        case 50 => return Many::V50(),
318 +
        case 51 => return Many::V51(payload),
319 +
        case 52 => return Many::V52(),
320 +
        case 53 => return Many::V53(payload),
321 +
        case 54 => return Many::V54(),
322 +
        case 55 => return Many::V55(payload),
323 +
        case 56 => return Many::V56(),
324 +
        case 57 => return Many::V57(payload),
325 +
        case 58 => return Many::V58(),
326 +
        case 59 => return Many::V59(payload),
327 +
        case 60 => return Many::V60(),
328 +
        case 61 => return Many::V61(payload),
329 +
        case 62 => return Many::V62(),
330 +
        case 63 => return Many::V63(payload),
331 +
        case 64 => return Many::V64(),
332 +
        case 65 => return Many::V65(payload),
333 +
        case 66 => return Many::V66(),
334 +
        case 67 => return Many::V67(payload),
335 +
        case 68 => return Many::V68(),
336 +
        case 69 => return Many::V69(payload),
337 +
        case 70 => return Many::V70(),
338 +
        case 71 => return Many::V71(payload),
339 +
        case 72 => return Many::V72(),
340 +
        case 73 => return Many::V73(payload),
341 +
        case 74 => return Many::V74(),
342 +
        case 75 => return Many::V75(payload),
343 +
        case 76 => return Many::V76(),
344 +
        case 77 => return Many::V77(payload),
345 +
        case 78 => return Many::V78(),
346 +
        case 79 => return Many::V79(payload),
347 +
        case 80 => return Many::V80(),
348 +
        case 81 => return Many::V81(payload),
349 +
        case 82 => return Many::V82(),
350 +
        case 83 => return Many::V83(payload),
351 +
        case 84 => return Many::V84(),
352 +
        case 85 => return Many::V85(payload),
353 +
        case 86 => return Many::V86(),
354 +
        case 87 => return Many::V87(payload),
355 +
        case 88 => return Many::V88(),
356 +
        case 89 => return Many::V89(payload),
357 +
        case 90 => return Many::V90(),
358 +
        case 91 => return Many::V91(payload),
359 +
        case 92 => return Many::V92(),
360 +
        case 93 => return Many::V93(payload),
361 +
        case 94 => return Many::V94(),
362 +
        case 95 => return Many::V95(payload),
363 +
        case 96 => return Many::V96(),
364 +
        case 97 => return Many::V97(payload),
365 +
        case 98 => return Many::V98(),
366 +
        case 99 => return Many::V99(payload),
367 +
        case 100 => return Many::V100(),
368 +
        case 101 => return Many::V101(payload),
369 +
        case 102 => return Many::V102(),
370 +
        case 103 => return Many::V103(payload),
371 +
        case 104 => return Many::V104(),
372 +
        case 105 => return Many::V105(payload),
373 +
        case 106 => return Many::V106(),
374 +
        case 107 => return Many::V107(payload),
375 +
        case 108 => return Many::V108(),
376 +
        case 109 => return Many::V109(payload),
377 +
        case 110 => return Many::V110(),
378 +
        case 111 => return Many::V111(payload),
379 +
        case 112 => return Many::V112(),
380 +
        case 113 => return Many::V113(payload),
381 +
        case 114 => return Many::V114(),
382 +
        case 115 => return Many::V115(payload),
383 +
        case 116 => return Many::V116(),
384 +
        case 117 => return Many::V117(payload),
385 +
        case 118 => return Many::V118(),
386 +
        case 119 => return Many::V119(payload),
387 +
        case 120 => return Many::V120(),
388 +
        case 121 => return Many::V121(payload),
389 +
        case 122 => return Many::V122(),
390 +
        case 123 => return Many::V123(payload),
391 +
        case 124 => return Many::V124(),
392 +
        case 125 => return Many::V125(payload),
393 +
        case 126 => return Many::V126(),
394 +
        else => return Many::V127(payload),
395 +
    }
396 +
}
397 +
398 +
/// Compare runtime union values through the generated equality dispatch.
399 +
fn equal(a: Many, b: Many) -> bool {
400 +
    return a == b;
401 +
}
402 +
403 +
/// Check equal tags, differing tags, payload differences, and void cases.
404 +
@default fn main() -> u32 {
405 +
    for tag in 0..128 {
406 +
        assert equal(value(tag, 7), value(tag, 7));
407 +
        assert equal(value(tag, 7), value(tag, 8)) == (tag & 1 == 0);
408 +
        assert not equal(value(tag, 7), value((tag + 1) % 128, 7));
409 +
    }
410 +
    return 0;
411 +
}