Fix a bunch of disparate issues around integers

e0e2e01d246021251f5d5272f33ae2b84ee7e891f1e1f79a2ed614c072a4a05f
Use 64-bit integers by default.
Alexis Sellier committed ago 1 parent a1e8824d
lib/std/lang/lower.rad +11 -6
5884 5884
}
5885 5885
5886 5886
/// Check whether a resolver type is a signed integer type.
5887 5887
fn isSignedType(t: resolver::Type) -> bool {
5888 5888
    match t {
5889 -
        case resolver::Type::I8, resolver::Type::I16, resolver::Type::I32, resolver::Type::I64 => return true,
5889 +
        case resolver::Type::I8, resolver::Type::I16, resolver::Type::I32, resolver::Type::I64,
5890 +
             resolver::Type::Int => return true,
5890 5891
        else => return false,
5891 5892
    }
5892 5893
}
5893 5894
5894 5895
/// Check whether a resolver type is an unsigned integer type.
7011 7012
            if resolver::isVoidUnion(typ) {
7012 7013
                return il::Type::W8;
7013 7014
            }
7014 7015
            return il::Type::W64;
7015 7016
        }
7016 -
        case resolver::Type::Void,
7017 -
             // FIXME: We shouldn't try to lower this type, it should be behind a pointer.
7018 -
             resolver::Type::Opaque,
7019 -
             // FIXME: This should be resolved to a concrete integer type in the resolver.
7020 -
             resolver::Type::Int => return il::Type::W32,
7017 +
        case resolver::Type::Void => return il::Type::W64,
7018 +
        // [`Type::Int`] is the type of unsuffixed integer literals and their
7019 +
        // compound expressions (e.g. `1 + 2`). It defaults to W64 (i64) here,
7020 +
        // matching the native word size on RV64. It cannot be resolved earlier
7021 +
        // because the resolver uses [`Type::Int`] to distinguish unsuffixed
7022 +
        // expressions from explicitly typed ones, which affects coercion
7023 +
        // behavior (e.g. implicit narrowing).
7024 +
        case resolver::Type::Int => return il::Type::W64,
7025 +
        case resolver::Type::Opaque => panic "ilType: opaque type must be behind a pointer",
7021 7026
        else => panic "ilType: type cannot be lowered",
7022 7027
    }
7023 7028
}
lib/std/lang/parser.rad +0 -1
1184 1184
    return p.current.kind == kind;
1185 1185
}
1186 1186
1187 1187
/// Advance the parser by one token.
1188 1188
pub fn advance(p: *mut Parser) {
1189 -
    // FIXME: `previous` is garbage the first time this function is called.
1190 1189
    p.previous = p.current;
1191 1190
    p.current = scanner::next(&mut p.scanner);
1192 1191
}
1193 1192
1194 1193
/// Parse an `if let` pattern matching statement.
lib/std/lang/resolver.rad +32 -8
1347 1347
pub fn getTypeLayout(ty: Type) -> Layout {
1348 1348
    match ty {
1349 1349
        case Type::Void, Type::Never => return Layout { size: 0, alignment: 0 },
1350 1350
        case Type::Bool, Type::U8, Type::I8 => return Layout { size: 1, alignment: 1 },
1351 1351
        case Type::U16, Type::I16 => return Layout { size: 2, alignment: 2 },
1352 -
        case Type::U32, Type::I32, Type::Int => return Layout { size: 4, alignment: 4 },
1352 +
        case Type::U32, Type::I32 => return Layout { size: 4, alignment: 4 },
1353 +
        case Type::Int => return Layout { size: 8, alignment: 8 },
1353 1354
        case Type::U64, Type::I64 => return Layout { size: 8, alignment: 8 },
1354 1355
        case Type::Pointer { .. },
1355 1356
             Type::Fn(_) => return Layout { size: PTR_SIZE, alignment: PTR_SIZE },
1356 1357
        case Type::Slice { .. },
1357 1358
             Type::TraitObject { .. } => return Layout { size: PTR_SIZE * 2, alignment: PTR_SIZE },
1542 1543
            bits: 16,
1543 1544
            min: I16_MIN as i64,
1544 1545
            max: I16_MAX as i64,
1545 1546
            lim: (I16_MAX as u64) + 1,
1546 1547
        },
1547 -
        case Type::I32,
1548 -
             Type::Int => return IntegerRange::Signed {
1548 +
        case Type::I32 => return IntegerRange::Signed {
1549 1549
            bits: 32,
1550 1550
            min: I32_MIN as i64,
1551 1551
            max: I32_MAX as i64,
1552 1552
            lim: (I32_MAX as u64) + 1,
1553 1553
        },
1554 -
        case Type::I64 => return IntegerRange::Signed {
1554 +
        case Type::I64, Type::Int => return IntegerRange::Signed {
1555 1555
            bits: 64,
1556 1556
            min: I64_MIN,
1557 1557
            max: I64_MAX,
1558 1558
            lim: (I64_MAX as u64) + 1,
1559 1559
        },
1796 1796
                        if validateConstIntRange(value, to) {
1797 1797
                            return Coercion::Identity;
1798 1798
                        }
1799 1799
                        return nil;
1800 1800
                    }
1801 +
                    // Folded constant expression (e.g. `1 + 2`): if the
1802 +
                    // result fits the target, use identity. Otherwise allow
1803 +
                    // wrapping via numeric cast.
1804 +
                    if validateConstIntRange(value, to) {
1805 +
                        return Coercion::Identity;
1806 +
                    }
1801 1807
                }
1802 1808
                // Allow unsuffixed integer expressions to be inferred from context.
1803 1809
                if from == Type::Int {
1804 1810
                    return Coercion::NumericCast { from, to };
1805 1811
                }
2663 2669
            return setNodeType(self, node, *sliceTy);
2664 2670
        },
2665 2671
        case ast::NodeValue::Number(lit) => {
2666 2672
            setNodeConstValue(self, node, ConstValue::Int(ConstInt {
2667 2673
                magnitude: lit.magnitude,
2668 -
                bits: 32,
2674 +
                bits: 64,
2669 2675
                signed: lit.signed,
2670 2676
                negative: lit.negative,
2671 2677
            }));
2672 2678
            return setNodeType(self, node, Type::Int);
2673 2679
        },
5438 5444
    let length = items.len;
5439 5445
    let mut expectedTy: Type = Type::Unknown;
5440 5446
5441 5447
    if let case Type::Array(ary) = hint {
5442 5448
        expectedTy = *ary.item;
5449 +
    } else if let case Type::Optional(inner) = hint {
5450 +
        if let case Type::Array(ary) = *inner {
5451 +
            expectedTy = *ary.item;
5452 +
        }
5443 5453
    };
5444 5454
    for itemNode in items {
5445 5455
        let itemTy = try visit(self, itemNode, expectedTy);
5446 5456
        assert itemTy != Type::Unknown;
5447 5457
5461 5471
5462 5472
/// Analyze an array repeat literal expression.
5463 5473
fn resolveArrayRepeat(self: *mut Resolver, node: *ast::Node, lit: ast::ArrayRepeatLit, hint: Type) -> Type
5464 5474
    throws (ResolveError)
5465 5475
{
5466 -
    let valueTy = try visit(self, lit.item, hint);
5476 +
    let mut itemHint = hint;
5477 +
    if let case Type::Array(ary) = hint {
5478 +
        itemHint = *ary.item;
5479 +
    } else if let case Type::Optional(inner) = hint {
5480 +
        if let case Type::Array(ary) = *inner {
5481 +
            itemHint = *ary.item;
5482 +
        }
5483 +
    }
5484 +
    let valueTy = try visit(self, lit.item, itemHint);
5467 5485
    let count = try checkSizeInt(self, lit.count);
5468 5486
    let arrayTy = Type::Array(ArrayType {
5469 5487
        item: allocType(self, valueTy),
5470 5488
        length: count,
5471 5489
    });
5614 5632
                let fieldName = try nodeName(self, access.child);
5615 5633
                if let method = findMethod(self, subjectTy, fieldName) {
5616 5634
                    return setNodeType(self, node, Type::Fn(method.fnType));
5617 5635
                }
5618 5636
            }
5637 +
            throw emitError(self, access.parent, ErrorKind::ExpectedRecord);
5619 5638
        }
5620 5639
    }
5621 -
    // FIXME: We can't move this to the `else` branch due to a resolver bug.
5622 -
    throw emitError(self, access.parent, ErrorKind::ExpectedRecord);
5623 5640
}
5624 5641
5625 5642
/// Determine whether an expression can yield a mutable location for borrowing.
5626 5643
fn canBorrowMutFrom(self: *mut Resolver, node: *ast::Node) -> bool
5627 5644
    throws (ResolveError)
6378 6395
                }
6379 6396
            }
6380 6397
        },
6381 6398
        case ast::UnaryOp::BitNot => {
6382 6399
            resultTy = try checkNumeric(self, unop.value);
6400 +
            if let value = constValueFor(self, unop.value) {
6401 +
                if let case ConstValue::Int(intVal) = value {
6402 +
                    let signed = constIntToSigned(intVal);
6403 +
                    let inverted = constIntFromSigned(-(signed + 1), intVal.bits, intVal.signed);
6404 +
                    setNodeConstValue(self, node, ConstValue::Int(inverted));
6405 +
                }
6406 +
            }
6383 6407
        },
6384 6408
    };
6385 6409
    return setNodeType(self, node, resultTy);
6386 6410
}
6387 6411
test/tests/binop.bitwise.rad +10 -10
1 1
//! returns: 0
2 2
@default fn main() -> i32 {
3 3
    // Test `&` (bitwise AND).
4 4
    // `12 = 0b1100`, `10 = 0b1010`, result = `0b1000 = 8`.
5 -
    let a: i32 = 12 & 10;
5 +
    let a: i64 = 12 & 10;
6 6
    assert a == 8;
7 7
8 8
    // Test `|` (bitwise OR).
9 9
    // `12 = 0b1100`, `10 = 0b1010`, result = `0b1110 = 14`.
10 -
    let b: i32 = 12 | 10;
10 +
    let b: i64 = 12 | 10;
11 11
    assert b == 14;
12 12
13 13
    // Test `^` (bitwise XOR).
14 14
    // `12 = 0b1100`, `10 = 0b1010`, result = `0b0110 = 6`.
15 -
    let c: i32 = 12 ^ 10;
15 +
    let c: i64 = 12 ^ 10;
16 16
    assert c == 6;
17 17
18 18
    // Test `<<` (shift left).
19 19
    // `3 << 4 = 48`.
20 -
    let d: i32 = 3 << 4;
20 +
    let d: i64 = 3 << 4;
21 21
    assert d == 48;
22 22
23 23
    // Test `>>` (shift right, arithmetic for signed).
24 24
    // `48 >> 2 = 12`.
25 -
    let e: i32 = 48 >> 2;
25 +
    let e: i64 = 48 >> 2;
26 26
    assert e == 12;
27 27
28 28
    // Test `>>` with negative (arithmetic shift preserves sign).
29 29
    // `-16 >> 2 = -4` (sign bit extended).
30 -
    let f: i32 = -16 >> 2;
30 +
    let f: i64 = -16 >> 2;
31 31
    assert f == -4;
32 32
33 33
    // Test `~` (bitwise NOT).
34 34
    // `~0 = -1` (all bits set).
35 -
    let g: i32 = ~0;
35 +
    let g: i64 = ~0;
36 36
    assert g == -1;
37 37
38 38
    // Test `~` with positive value.
39 39
    // `~1 = -2` (in two's complement).
40 -
    let h: i32 = ~1;
40 +
    let h: i64 = ~1;
41 41
    assert h == -2;
42 42
43 43
    // Combined operations.
44 44
    // `(5 | 3) & 6 = 7 & 6 = 6`.
45 -
    let i: i32 = (5 | 3) & 6;
45 +
    let i: i64 = (5 | 3) & 6;
46 46
    assert i == 6;
47 47
48 48
    // XOR self is `0`.
49 -
    let j: i32 = 42;
49 +
    let j: i64 = 42;
50 50
    assert (j ^ j) == 0;
51 51
    return 0;
52 52
}
test/tests/binop.bitwise.ril +21 -22
1 1
fn w32 $main() {
2 2
  @entry0
3 -
    and w32 %0 12 10;
4 -
    br.eq w32 %0 8 @assert.ok2 @assert.fail1;
3 +
    and w64 %0 12 10;
4 +
    br.eq w64 %0 8 @assert.ok2 @assert.fail1;
5 5
  @assert.fail1
6 6
    unreachable;
7 7
  @assert.ok2
8 -
    or w32 %1 12 10;
9 -
    br.eq w32 %1 14 @assert.ok4 @assert.fail3;
8 +
    or w64 %1 12 10;
9 +
    br.eq w64 %1 14 @assert.ok4 @assert.fail3;
10 10
  @assert.fail3
11 11
    unreachable;
12 12
  @assert.ok4
13 -
    xor w32 %2 12 10;
14 -
    br.eq w32 %2 6 @assert.ok6 @assert.fail5;
13 +
    xor w64 %2 12 10;
14 +
    br.eq w64 %2 6 @assert.ok6 @assert.fail5;
15 15
  @assert.fail5
16 16
    unreachable;
17 17
  @assert.ok6
18 -
    shl w32 %3 3 4;
19 -
    br.eq w32 %3 48 @assert.ok8 @assert.fail7;
18 +
    shl w64 %3 3 4;
19 +
    br.eq w64 %3 48 @assert.ok8 @assert.fail7;
20 20
  @assert.fail7
21 21
    unreachable;
22 22
  @assert.ok8
23 -
    sshr w32 %4 48 2;
24 -
    br.eq w32 %4 12 @assert.ok10 @assert.fail9;
23 +
    sshr w64 %4 48 2;
24 +
    br.eq w64 %4 12 @assert.ok10 @assert.fail9;
25 25
  @assert.fail9
26 26
    unreachable;
27 27
  @assert.ok10
28 -
    sshr w32 %5 -16 2;
29 -
    br.eq w32 %5 -4 @assert.ok12 @assert.fail11;
28 +
    sshr w64 %5 -16 2;
29 +
    br.eq w64 %5 -4 @assert.ok12 @assert.fail11;
30 30
  @assert.fail11
31 31
    unreachable;
32 32
  @assert.ok12
33 -
    not w32 %6 0;
34 -
    br.eq w32 %6 -1 @assert.ok14 @assert.fail13;
33 +
    not w64 %6 0;
34 +
    br.eq w64 %6 -1 @assert.ok14 @assert.fail13;
35 35
  @assert.fail13
36 36
    unreachable;
37 37
  @assert.ok14
38 -
    not w32 %7 1;
39 -
    br.eq w32 %7 -2 @assert.ok16 @assert.fail15;
38 +
    not w64 %7 1;
39 +
    br.eq w64 %7 -2 @assert.ok16 @assert.fail15;
40 40
  @assert.fail15
41 41
    unreachable;
42 42
  @assert.ok16
43 -
    or w32 %8 5 3;
44 -
    and w32 %9 %8 6;
45 -
    br.eq w32 %9 6 @assert.ok18 @assert.fail17;
43 +
    or w64 %8 5 3;
44 +
    and w64 %9 %8 6;
45 +
    br.eq w64 %9 6 @assert.ok18 @assert.fail17;
46 46
  @assert.fail17
47 47
    unreachable;
48 48
  @assert.ok18
49 -
    xor w32 %10 42 42;
50 -
    br.eq w32 %10 0 @assert.ok20 @assert.fail19;
49 +
    xor w64 %10 42 42;
50 +
    br.eq w64 %10 0 @assert.ok20 @assert.fail19;
51 51
  @assert.fail19
52 52
    unreachable;
53 53
  @assert.ok20
54 54
    ret 0;
55 55
}
56 -
test/tests/byte.load.store.ril +2 -2
2 2
  @entry0
3 3
    load w8 %1 %0 0;
4 4
    ret %1;
5 5
}
6 6
7 -
fn w32 $storeByte(w64 %0, w8 %1) {
7 +
fn w64 $storeByte(w64 %0, w8 %1) {
8 8
  @entry0
9 9
    store w8 %1 %0 0;
10 10
    ret;
11 11
}
12 12
13 -
fn w32 $loadStoreByte(w64 %0, w64 %1) {
13 +
fn w64 $loadStoreByte(w64 %0, w64 %1) {
14 14
  @entry0
15 15
    load w8 %2 %0 0;
16 16
    store w8 %2 %1 0;
17 17
    ret;
18 18
}
test/tests/call.tests.ril +2 -2
13 13
  @entry0
14 14
    add w32 %2 %0 %1;
15 15
    ret %2;
16 16
}
17 17
18 -
fn w32 $doNothing() {
18 +
fn w64 $doNothing() {
19 19
  @entry0
20 20
    ret;
21 21
}
22 22
23 23
fn w32 $callSimple(w32 %0) {
34 34
    ret %4;
35 35
}
36 36
37 37
fn w32 $callVoid() {
38 38
  @entry0
39 -
    call w32 $doNothing();
39 +
    call w64 $doNothing();
40 40
    ret 1;
41 41
}
42 42
43 43
fn w32 $callAndIgnore() {
44 44
  @entry0
test/tests/cond.expr.rad +2 -2
15 15
    return Color::Red if isRed else Color::Blue;
16 16
}
17 17
18 18
/// Test basic scalar conditional expression.
19 19
fn testScalar() -> i32 {
20 -
    let x: i32 = 10 if true else 20;
20 +
    let x: i64 = 10 if true else 20;
21 21
    assert x == 10;
22 -
    let y: i32 = 10 if false else 20;
22 +
    let y: i64 = 10 if false else 20;
23 23
    assert y == 20;
24 24
    return 0;
25 25
}
26 26
27 27
/// Test min-value pattern.
test/tests/cond.expr.ril +4 -5
37 37
    br.ne w32 %0 0 @cond#then1 @cond#else2;
38 38
  @cond#then1
39 39
    jmp @cond#merge3(10);
40 40
  @cond#else2
41 41
    jmp @cond#merge3(20);
42 -
  @cond#merge3(w32 %1)
43 -
    br.eq w32 %1 10 @assert.ok5 @assert.fail4;
42 +
  @cond#merge3(w64 %1)
43 +
    br.eq w64 %1 10 @assert.ok5 @assert.fail4;
44 44
  @assert.fail4
45 45
    unreachable;
46 46
  @assert.ok5
47 47
    copy %2 0;
48 48
    br.ne w32 %2 0 @cond#then6 @cond#else7;
49 49
  @cond#then6
50 50
    jmp @cond#merge8(10);
51 51
  @cond#else7
52 52
    jmp @cond#merge8(20);
53 -
  @cond#merge8(w32 %3)
54 -
    br.eq w32 %3 20 @assert.ok10 @assert.fail9;
53 +
  @cond#merge8(w64 %3)
54 +
    br.eq w64 %3 20 @assert.ok10 @assert.fail9;
55 55
  @assert.fail9
56 56
    unreachable;
57 57
  @assert.ok10
58 58
    ret 0;
59 59
}
176 176
  @then9
177 177
    ret %4;
178 178
  @merge10
179 179
    ret 0;
180 180
}
181 -
test/tests/int.default.i64.rad added +58 -0
1 +
//! returns: 0
2 +
//! Test that unsuffixed integer literals default to 64-bit (i64).
3 +
4 +
/// Test basic arithmetic on unsuffixed integers.
5 +
fn testArith() -> i32 {
6 +
    let x: i64 = 1 + 2;
7 +
    assert x == 3;
8 +
9 +
    let y: i64 = 100 * 100;
10 +
    assert y == 10000;
11 +
12 +
    // Large value that doesn't fit in 32 bits.
13 +
    let z: i64 = 2147483648;
14 +
    assert z == 2147483648;
15 +
16 +
    return 0;
17 +
}
18 +
19 +
/// Test unsuffixed integer coercion to i32.
20 +
fn testCoerceI32() -> i32 {
21 +
    let x: i32 = 42;
22 +
    assert x == 42;
23 +
24 +
    let y: i32 = 1 + 2;
25 +
    assert y == 3;
26 +
27 +
    return 0;
28 +
}
29 +
30 +
/// Test unsuffixed integer coercion to i8.
31 +
fn testCoerceI8() -> i32 {
32 +
    let x: i8 = 42;
33 +
    assert x == 42;
34 +
35 +
    let y: i8 = 1 + 2;
36 +
    assert y == 3;
37 +
38 +
    return 0;
39 +
}
40 +
41 +
/// Test unsuffixed integer in conditional expression.
42 +
fn testCondExpr() -> i32 {
43 +
    let x: i64 = 10 if true else 20;
44 +
    assert x == 10;
45 +
46 +
    let y: i32 = 10 if false else 20;
47 +
    assert y == 20;
48 +
49 +
    return 0;
50 +
}
51 +
52 +
@default fn main() -> i32 {
53 +
    assert testArith() == 0;
54 +
    assert testCoerceI32() == 0;
55 +
    assert testCoerceI8() == 0;
56 +
    assert testCondExpr() == 0;
57 +
    return 0;
58 +
}
test/tests/intrinsic.ebreak.ril +2 -2
1 -
extern fn w32 $ebreak();
1 +
extern fn w64 $ebreak();
2 2
3 -
fn w32 $test() {
3 +
fn w64 $test() {
4 4
  @entry0
5 5
    ebreak;
6 6
    ret;
7 7
}
test/tests/multiplefns.ril +1 -1
6 6
fn w32 $second(w32 %0, w32 %1) {
7 7
  @entry0
8 8
    ret %0;
9 9
}
10 10
11 -
fn w32 $third() {
11 +
fn w64 $third() {
12 12
  @entry0
13 13
    ret;
14 14
}
test/tests/mutref.loop.ril +2 -2
1 -
fn w32 $callback(w32 %0, w64 %1) {
1 +
fn w64 $callback(w32 %0, w64 %1) {
2 2
  @entry0
3 3
    store w32 %0 %1 0;
4 4
    ret;
5 5
}
6 6
10 10
    store w32 0 %0 0;
11 11
    jmp @while1(0, %0);
12 12
  @while1(w32 %1, w32 %2)
13 13
    br.ult w32 %1 3 @body2 @merge3;
14 14
  @body2
15 -
    call w32 $callback(%1, %2);
15 +
    call w64 $callback(%1, %2);
16 16
    add w32 %3 %1 1;
17 17
    jmp @while1(%3, %2);
18 18
  @merge3
19 19
    load w32 %4 %2 0;
20 20
    ret %4;
test/tests/opt.array.hint.rad added +45 -0
1 +
//! returns: 0
2 +
//! Test that array literal type hints propagate through optionals.
3 +
4 +
/// Return an optional array literal.
5 +
fn optArray() -> ?[i32; 3] {
6 +
    return [1, 2, 3];
7 +
}
8 +
9 +
/// Return an optional array repeat literal.
10 +
fn optRepeat() -> ?[i32; 4] {
11 +
    return [0; 4];
12 +
}
13 +
14 +
/// Test optional array literal hint propagation.
15 +
fn testOptArrayLit() -> i32 {
16 +
    if let a = optArray() {
17 +
        assert a.len == 3;
18 +
        assert a[0] == 1;
19 +
        assert a[1] == 2;
20 +
        assert a[2] == 3;
21 +
    } else {
22 +
        return 1;
23 +
    }
24 +
    return 0;
25 +
}
26 +
27 +
/// Test optional array repeat literal hint propagation.
28 +
fn testOptRepeat() -> i32 {
29 +
    if let a = optRepeat() {
30 +
        assert a.len == 4;
31 +
        assert a[0] == 0;
32 +
        assert a[1] == 0;
33 +
        assert a[2] == 0;
34 +
        assert a[3] == 0;
35 +
    } else {
36 +
        return 1;
37 +
    }
38 +
    return 0;
39 +
}
40 +
41 +
@default fn main() -> i32 {
42 +
    assert testOptArrayLit() == 0;
43 +
    assert testOptRepeat() == 0;
44 +
    return 0;
45 +
}
test/tests/ptr.subscript.assign.ril +1 -1
1 -
fn w32 $subscriptAssign(w64 %0, w32 %1, w32 %2) {
1 +
fn w64 $subscriptAssign(w64 %0, w32 %1, w32 %2) {
2 2
  @entry0
3 3
    load w32 %3 %0 8;
4 4
    br.ult w32 %1 %3 @guard#pass1 @guard#trap2;
5 5
  @guard#pass1
6 6
    load w64 %4 %0 0;
test/tests/record.assign.blit.ril +1 -1
1 -
fn w32 $copy() {
1 +
fn w64 $copy() {
2 2
  @entry0
3 3
    reserve %0 8 4;
4 4
    store w32 1 %0 0;
5 5
    store w32 2 %0 4;
6 6
    reserve %1 8 4;
test/tests/slice.mutable.ril +3 -3
1 -
fn w32 $mutSliceStore(w64 %0, w32 %1, w32 %2) {
1 +
fn w64 $mutSliceStore(w64 %0, w32 %1, w32 %2) {
2 2
  @entry0
3 3
    load w32 %3 %0 8;
4 4
    br.ult w32 %1 %3 @guard#pass1 @guard#trap2;
5 5
  @guard#pass1
6 6
    load w64 %4 %0 0;
11 11
  @guard#trap2
12 12
    ebreak;
13 13
    unreachable;
14 14
}
15 15
16 -
fn w32 $mutSliceIncrement(w64 %0, w32 %1) {
16 +
fn w64 $mutSliceIncrement(w64 %0, w32 %1) {
17 17
  @entry0
18 18
    load w32 %2 %0 8;
19 19
    br.ult w32 %1 %2 @guard#pass1 @guard#trap2;
20 20
  @guard#pass1
21 21
    load w64 %3 %0 0;
37 37
  @guard#trap4
38 38
    ebreak;
39 39
    unreachable;
40 40
}
41 41
42 -
fn w32 $mutSliceSwap(w64 %0, w32 %1, w32 %2) {
42 +
fn w64 $mutSliceSwap(w64 %0, w32 %1, w32 %2) {
43 43
  @entry0
44 44
    load w32 %3 %0 8;
45 45
    br.ult w32 %1 %3 @guard#pass1 @guard#trap2;
46 46
  @guard#pass1
47 47
    load w64 %4 %0 0;
test/tests/trait.dispatch.ril +2 -2
7 7
  @entry0
8 8
    sload w32 %1 %0 0;
9 9
    ret %1;
10 10
}
11 11
12 -
fn w32 $"Acc::set"(w64 %0, w32 %1) {
12 +
fn w64 $"Acc::set"(w64 %0, w32 %1) {
13 13
  @entry0
14 14
    store w32 %1 %0 0;
15 15
    ret;
16 16
}
17 17
18 18
fn w32 $dispatch(w64 %0) {
19 19
  @entry0
20 20
    load w64 %1 %0 0;
21 21
    load w64 %2 %0 8;
22 22
    load w64 %3 %2 8;
23 -
    call w32 %3(%1, 42);
23 +
    call w64 %3(%1, 42);
24 24
    load w64 %4 %0 0;
25 25
    load w64 %5 %0 8;
26 26
    load w64 %6 %5 0;
27 27
    call w32 %7 %6(%4);
28 28
    ret %7;
test/tests/voidfn.ril +1 -1
1 -
fn w32 $doNothing() {
1 +
fn w64 $doNothing() {
2 2
  @entry0
3 3
    ret;
4 4
}