Combine lowering and execution tests

a0bdac6ce4e76bd94a0141d8f82d9c43ea5cbfe9c4f085c29f1960f67ff4b321
We simplify things by having only one set of integration tests.
Alexis Sellier committed ago 1 parent 3df5cf97
Makefile +31 -39
20 20
21 21
# Verify the emulator binary exists.
22 22
EMU_PATH := $(shell command -v $(EMU) 2>/dev/null)
23 23
24 24
default: emulator $(RAD_BIN)
25 -
test: emulator std-test lower-test asm-test
25 +
test: emulator std-test bin-test
26 26
27 27
# Emulator command check
28 28
29 29
emulator:
30 30
ifeq ($(EMU_PATH),)
58 58
		lib/std.test.rv64.s \
59 59
		lib/std.test.rv64.o \
60 60
		lib/std.test.rv64.rw.data \
61 61
		lib/std.test.rv64.ro.data
62 62
63 -
# Lowering Tests
63 +
# Binary Tests
64 64
65 -
LOWER_TEST     := test/lower/lower-test.rv64
66 -
LOWER_TEST_RUN := test/lower/run
65 +
BIN_TEST_DIR := test/tests
66 +
# Only tests with `//! returns:` are compiled to binaries and executed.
67 +
BIN_TEST_EXE_SRC := $(shell grep -rl '^//! returns:' $(BIN_TEST_DIR))
68 +
BIN_TEST_EXE_BIN := $(BIN_TEST_EXE_SRC:.rad=.rv64)
69 +
BIN_RUNNER   := test/runner.rv64
70 +
BIN_TEST_RUN := test/run
67 71
68 -
lower-test: $(LOWER_TEST)
72 +
bin-test: $(BIN_RUNNER) $(BIN_TEST_EXE_BIN)
69 73
	@echo
70 -
	@$(LOWER_TEST_RUN)
74 +
	@$(BIN_TEST_RUN)
71 75
72 -
$(LOWER_TEST): test/lower/lower-test.rad $(STD_LIB) $(RAD_BIN)
73 -
	@echo "radiance $(STD) -pkg lower -mod test/lower/lower-test.rad -entry lower -o $@"
74 -
	@$(RADIANCE) $(STD) -pkg lower -mod test/lower/lower-test.rad -entry lower -o $@
76 +
# Runner binary: the lowering IL checker.
77 +
$(BIN_RUNNER): test/runner.rad $(STD_LIB) $(RAD_BIN)
78 +
	@echo "radiance test/runner.rad => $@"
79 +
	@$(RADIANCE) $(STD) -pkg runner -mod test/runner.rad -entry runner -o $@
75 80
76 -
clean-lower-test:
77 -
	@rm -f $(LOWER_TEST) \
78 -
		test/lower/lower-test.rv64.debug \
79 -
		test/lower/lower-test.rv64.s \
80 -
		test/lower/lower-test.rv64.o \
81 -
		test/lower/lower-test.rv64.rw.data \
82 -
		test/lower/lower-test.rv64.ro.data
83 -
84 -
# Code generation tests.
85 -
86 -
ASM_TEST_DIR := lib/std/arch/rv64/tests
87 -
ASM_TEST_SRC := $(wildcard $(ASM_TEST_DIR)/*.rad)
88 -
ASM_TEST_BIN := $(ASM_TEST_SRC:.rad=.rv64)
89 -
ASM_TEST_RUN := test/asm/run
90 -
91 -
asm-test: $(ASM_TEST_BIN) $(RAD_BIN)
92 -
	@echo
93 -
	@$(ASM_TEST_RUN) $(ASM_TEST_SRC)
94 -
95 -
$(ASM_TEST_DIR)/%.rv64: $(ASM_TEST_DIR)/%.rad $(RAD_BIN)
81 +
# Compile each executable test to a binary.
82 +
$(BIN_TEST_DIR)/%.rv64: $(BIN_TEST_DIR)/%.rad $(RAD_BIN)
96 83
	@echo "radiance $< => $@"
97 84
	@$(RADIANCE) -pkg test -mod $< -o $@
98 85
99 -
clean-asm-test:
100 -
	@rm -f $(ASM_TEST_BIN) \
101 -
		$(wildcard $(ASM_TEST_DIR)/*.rv64.debug) \
102 -
		$(wildcard $(ASM_TEST_DIR)/*.rv64.s) \
103 -
		$(wildcard $(ASM_TEST_DIR)/*.rv64) \
104 -
		$(wildcard $(ASM_TEST_DIR)/*.rv64.rw.data) \
105 -
		$(wildcard $(ASM_TEST_DIR)/*.rv64.ro.data)
86 +
clean-bin-test:
87 +
	@rm -f $(BIN_RUNNER) \
88 +
		$(BIN_RUNNER:.rv64=.rv64.debug) \
89 +
		$(BIN_RUNNER:.rv64=.rv64.s) \
90 +
		$(BIN_RUNNER:.rv64=.rv64.o) \
91 +
		$(BIN_RUNNER:.rv64=.rv64.rw.data) \
92 +
		$(BIN_RUNNER:.rv64=.rv64.ro.data) \
93 +
		$(BIN_TEST_EXE_BIN) \
94 +
		$(wildcard $(BIN_TEST_DIR)/*.rv64.debug) \
95 +
		$(wildcard $(BIN_TEST_DIR)/*.rv64.s) \
96 +
		$(wildcard $(BIN_TEST_DIR)/*.rv64.rw.data) \
97 +
		$(wildcard $(BIN_TEST_DIR)/*.rv64.ro.data)
106 98
107 99
seed:
108 100
	seed/update
109 101
110 102
clean-rad:
111 103
	rm -f $(RAD_BIN) $(RAD_BIN).ro.data $(RAD_BIN).rw.data
112 104
	rm -f seed/radiance.rv64.s[0-9]*
113 105
114 -
clean: clean-std-test clean-lower-test clean-asm-test clean-rad
106 +
clean: clean-std-test clean-bin-test clean-rad
115 107
116 108
t: test
117 109
c: clean
118 110
119 -
.PHONY: test clean default std-test lower-test asm-test seed \
120 -
	clean-std-test clean-lower-test clean-asm-test clean-rad emulator
111 +
.PHONY: test clean default std-test bin-test seed \
112 +
	clean-std-test clean-bin-test clean-rad emulator
121 113
.SUFFIXES:
122 114
.DELETE_ON_ERROR:
123 115
.SILENT:
lib/std/lang/lower/tests/arith.subword.rad deleted +0 -64
1 -
/// Add two i8 values.
2 -
fn addI8(a: i8, b: i8) -> i8 {
3 -
    return a + b;
4 -
}
5 -
6 -
/// Subtract two i8 values.
7 -
fn subI8(a: i8, b: i8) -> i8 {
8 -
    return a - b;
9 -
}
10 -
11 -
/// Multiply two i8 values.
12 -
fn mulI8(a: i8, b: i8) -> i8 {
13 -
    return a * b;
14 -
}
15 -
16 -
/// Add two u8 values.
17 -
fn addU8(a: u8, b: u8) -> u8 {
18 -
    return a + b;
19 -
}
20 -
21 -
/// Subtract two u8 values.
22 -
fn subU8(a: u8, b: u8) -> u8 {
23 -
    return a - b;
24 -
}
25 -
26 -
/// Multiply two u8 values.
27 -
fn mulU8(a: u8, b: u8) -> u8 {
28 -
    return a * b;
29 -
}
30 -
31 -
/// Add two i16 values.
32 -
fn addI16(a: i16, b: i16) -> i16 {
33 -
    return a + b;
34 -
}
35 -
36 -
/// Add two u16 values.
37 -
fn addU16(a: u16, b: u16) -> u16 {
38 -
    return a + b;
39 -
}
40 -
41 -
/// Left-shift i8.
42 -
fn shlI8(a: i8, b: i8) -> i8 {
43 -
    return a << b;
44 -
}
45 -
46 -
/// Left-shift u16.
47 -
fn shlU16(a: u16, b: u16) -> u16 {
48 -
    return a << b;
49 -
}
50 -
51 -
/// Divide i8 values.
52 -
fn divI8(a: i8, b: i8) -> i8 {
53 -
    return a / b;
54 -
}
55 -
56 -
/// Divide i16 values.
57 -
fn divI16(a: i16, b: i16) -> i16 {
58 -
    return a / b;
59 -
}
60 -
61 -
/// i32 add (should NOT get Sext/Zext).
62 -
fn addI32(a: i32, b: i32) -> i32 {
63 -
    return a + b;
64 -
}
lib/std/lang/lower/tests/arith.subword.ril deleted +0 -89
1 -
fn w8 $addI8(w8 %0, w8 %1) {
2 -
  @entry0
3 -
    add w8 %2 %0 %1;
4 -
    sext w8 %3 %2;
5 -
    ret %3;
6 -
}
7 -
8 -
fn w8 $subI8(w8 %0, w8 %1) {
9 -
  @entry0
10 -
    sub w8 %2 %0 %1;
11 -
    sext w8 %3 %2;
12 -
    ret %3;
13 -
}
14 -
15 -
fn w8 $mulI8(w8 %0, w8 %1) {
16 -
  @entry0
17 -
    mul w8 %2 %0 %1;
18 -
    sext w8 %3 %2;
19 -
    ret %3;
20 -
}
21 -
22 -
fn w8 $addU8(w8 %0, w8 %1) {
23 -
  @entry0
24 -
    add w8 %2 %0 %1;
25 -
    zext w8 %3 %2;
26 -
    ret %3;
27 -
}
28 -
29 -
fn w8 $subU8(w8 %0, w8 %1) {
30 -
  @entry0
31 -
    sub w8 %2 %0 %1;
32 -
    zext w8 %3 %2;
33 -
    ret %3;
34 -
}
35 -
36 -
fn w8 $mulU8(w8 %0, w8 %1) {
37 -
  @entry0
38 -
    mul w8 %2 %0 %1;
39 -
    zext w8 %3 %2;
40 -
    ret %3;
41 -
}
42 -
43 -
fn w16 $addI16(w16 %0, w16 %1) {
44 -
  @entry0
45 -
    add w16 %2 %0 %1;
46 -
    sext w16 %3 %2;
47 -
    ret %3;
48 -
}
49 -
50 -
fn w16 $addU16(w16 %0, w16 %1) {
51 -
  @entry0
52 -
    add w16 %2 %0 %1;
53 -
    zext w16 %3 %2;
54 -
    ret %3;
55 -
}
56 -
57 -
fn w8 $shlI8(w8 %0, w8 %1) {
58 -
  @entry0
59 -
    shl w8 %2 %0 %1;
60 -
    sext w8 %3 %2;
61 -
    ret %3;
62 -
}
63 -
64 -
fn w16 $shlU16(w16 %0, w16 %1) {
65 -
  @entry0
66 -
    shl w16 %2 %0 %1;
67 -
    zext w16 %3 %2;
68 -
    ret %3;
69 -
}
70 -
71 -
fn w8 $divI8(w8 %0, w8 %1) {
72 -
  @entry0
73 -
    sdiv w8 %2 %0 %1;
74 -
    sext w8 %3 %2;
75 -
    ret %3;
76 -
}
77 -
78 -
fn w16 $divI16(w16 %0, w16 %1) {
79 -
  @entry0
80 -
    sdiv w16 %2 %0 %1;
81 -
    sext w16 %3 %2;
82 -
    ret %3;
83 -
}
84 -
85 -
fn w32 $addI32(w32 %0, w32 %1) {
86 -
  @entry0
87 -
    add w32 %2 %0 %1;
88 -
    ret %2;
89 -
}
lib/std/lang/lower/tests/arith.w64.rad deleted +0 -69
1 -
/// Add two i64 values.
2 -
fn addI64(a: i64, b: i64) -> i64 {
3 -
    return a + b;
4 -
}
5 -
6 -
/// Subtract two i64 values.
7 -
fn subI64(a: i64, b: i64) -> i64 {
8 -
    return a - b;
9 -
}
10 -
11 -
/// Multiply two i64 values.
12 -
fn mulI64(a: i64, b: i64) -> i64 {
13 -
    return a * b;
14 -
}
15 -
16 -
/// Add two u64 values.
17 -
fn addU64(a: u64, b: u64) -> u64 {
18 -
    return a + b;
19 -
}
20 -
21 -
/// Subtract two u64 values.
22 -
fn subU64(a: u64, b: u64) -> u64 {
23 -
    return a - b;
24 -
}
25 -
26 -
/// Multiply two u64 values.
27 -
fn mulU64(a: u64, b: u64) -> u64 {
28 -
    return a * b;
29 -
}
30 -
31 -
/// Left-shift u64.
32 -
fn shlU64(a: u64, b: u64) -> u64 {
33 -
    return a << b;
34 -
}
35 -
36 -
/// Right-shift i64 (arithmetic).
37 -
fn shrI64(a: i64, b: i64) -> i64 {
38 -
    return a >> b;
39 -
}
40 -
41 -
/// Divide i64 values.
42 -
fn divI64(a: i64, b: i64) -> i64 {
43 -
    return a / b;
44 -
}
45 -
46 -
/// Divide u64 values.
47 -
fn divU64(a: u64, b: u64) -> u64 {
48 -
    return a / b;
49 -
}
50 -
51 -
/// Widen i32 to i64.
52 -
fn widenI32ToI64(a: i32) -> i64 {
53 -
    return a as i64;
54 -
}
55 -
56 -
/// Widen u32 to u64.
57 -
fn widenU32ToU64(a: u32) -> u64 {
58 -
    return a as u64;
59 -
}
60 -
61 -
/// Narrow i64 to i32.
62 -
fn narrowI64ToI32(a: i64) -> i32 {
63 -
    return a as i32;
64 -
}
65 -
66 -
/// Narrow u64 to u32.
67 -
fn narrowU64ToU32(a: u64) -> u32 {
68 -
    return a as u32;
69 -
}
lib/std/lang/lower/tests/arith.w64.ril deleted +0 -83
1 -
fn w64 $addI64(w64 %0, w64 %1) {
2 -
  @entry0
3 -
    add w64 %2 %0 %1;
4 -
    ret %2;
5 -
}
6 -
7 -
fn w64 $subI64(w64 %0, w64 %1) {
8 -
  @entry0
9 -
    sub w64 %2 %0 %1;
10 -
    ret %2;
11 -
}
12 -
13 -
fn w64 $mulI64(w64 %0, w64 %1) {
14 -
  @entry0
15 -
    mul w64 %2 %0 %1;
16 -
    ret %2;
17 -
}
18 -
19 -
fn w64 $addU64(w64 %0, w64 %1) {
20 -
  @entry0
21 -
    add w64 %2 %0 %1;
22 -
    ret %2;
23 -
}
24 -
25 -
fn w64 $subU64(w64 %0, w64 %1) {
26 -
  @entry0
27 -
    sub w64 %2 %0 %1;
28 -
    ret %2;
29 -
}
30 -
31 -
fn w64 $mulU64(w64 %0, w64 %1) {
32 -
  @entry0
33 -
    mul w64 %2 %0 %1;
34 -
    ret %2;
35 -
}
36 -
37 -
fn w64 $shlU64(w64 %0, w64 %1) {
38 -
  @entry0
39 -
    shl w64 %2 %0 %1;
40 -
    ret %2;
41 -
}
42 -
43 -
fn w64 $shrI64(w64 %0, w64 %1) {
44 -
  @entry0
45 -
    sshr w64 %2 %0 %1;
46 -
    ret %2;
47 -
}
48 -
49 -
fn w64 $divI64(w64 %0, w64 %1) {
50 -
  @entry0
51 -
    sdiv w64 %2 %0 %1;
52 -
    ret %2;
53 -
}
54 -
55 -
fn w64 $divU64(w64 %0, w64 %1) {
56 -
  @entry0
57 -
    udiv w64 %2 %0 %1;
58 -
    ret %2;
59 -
}
60 -
61 -
fn w64 $widenI32ToI64(w32 %0) {
62 -
  @entry0
63 -
    sext w32 %1 %0;
64 -
    ret %1;
65 -
}
66 -
67 -
fn w64 $widenU32ToU64(w32 %0) {
68 -
  @entry0
69 -
    zext w32 %1 %0;
70 -
    ret %1;
71 -
}
72 -
73 -
fn w32 $narrowI64ToI32(w64 %0) {
74 -
  @entry0
75 -
    sext w32 %1 %0;
76 -
    ret %1;
77 -
}
78 -
79 -
fn w32 $narrowU64ToU32(w64 %0) {
80 -
  @entry0
81 -
    zext w32 %1 %0;
82 -
    ret %1;
83 -
}
lib/std/lang/lower/tests/array.assign.rad deleted +0 -5
1 -
/// Copies an array using assignment.
2 -
fn arrayCopy(a: [i32; 2]) -> [i32; 2] {
3 -
    let b: [i32; 2] = a;
4 -
    return b;
5 -
}
lib/std/lang/lower/tests/array.assign.ril deleted +0 -7
1 -
fn w64 $arrayCopy(w64 %0, w64 %1) {
2 -
  @entry0
3 -
    reserve %2 8 4;
4 -
    blit %2 %1 8;
5 -
    blit %0 %2 8;
6 -
    ret %0;
7 -
}
lib/std/lang/lower/tests/array.index.rad deleted +0 -4
1 -
/// Returns an element from an array parameter.
2 -
fn arrayIndex(arr: [i32; 4], idx: u32) -> i32 {
3 -
    return arr[idx];
4 -
}
lib/std/lang/lower/tests/array.index.ril deleted +0 -12
1 -
fn w32 $arrayIndex(w64 %0, w32 %1) {
2 -
  @entry0
3 -
    br.ult w32 %1 4 @guard#pass1 @guard#trap2;
4 -
  @guard#pass1
5 -
    mul w64 %2 %1 4;
6 -
    add w64 %3 %0 %2;
7 -
    sload w32 %4 %3 0;
8 -
    ret %4;
9 -
  @guard#trap2
10 -
    ebreak;
11 -
    unreachable;
12 -
}
lib/std/lang/lower/tests/array.nested.rad deleted +0 -4
1 -
/// Accesses a nested array element.
2 -
fn nestedAccess(m: [[i32; 2]; 2], i: u32, j: u32) -> i32 {
3 -
    return m[i][j];
4 -
}
lib/std/lang/lower/tests/array.nested.ril deleted +0 -19
1 -
fn w32 $nestedAccess(w64 %0, w32 %1, w32 %2) {
2 -
  @entry0
3 -
    br.ult w32 %1 2 @guard#pass1 @guard#trap2;
4 -
  @guard#pass1
5 -
    mul w64 %3 %1 8;
6 -
    add w64 %4 %0 %3;
7 -
    br.ult w32 %2 2 @guard#pass3 @guard#trap4;
8 -
  @guard#trap2
9 -
    ebreak;
10 -
    unreachable;
11 -
  @guard#pass3
12 -
    mul w64 %5 %2 4;
13 -
    add w64 %6 %4 %5;
14 -
    sload w32 %7 %6 0;
15 -
    ret %7;
16 -
  @guard#trap4
17 -
    ebreak;
18 -
    unreachable;
19 -
}
lib/std/lang/lower/tests/array.repeat.rad deleted +0 -33
1 -
/// Creates an array with repeated i32 values.
2 -
fn arrayRepeatI32() -> i32 {
3 -
    let arr: [i32; 3] = [42; 3];
4 -
    return arr[0];
5 -
}
6 -
7 -
/// Creates an array with repeated bool values.
8 -
fn arrayRepeatBool() -> bool {
9 -
    let arr: [bool; 3] = [true; 3];
10 -
    return arr[1];
11 -
}
12 -
13 -
/// Creates an array with repeated char values.
14 -
fn arrayRepeatChar() -> u8 {
15 -
    let arr: [u8; 3] = ['x'; 3];
16 -
    return arr[2];
17 -
}
18 -
19 -
/// Const array with repeated bool values.
20 -
const BOOLS: [bool; 3] = [true; 3];
21 -
22 -
/// Const array with repeated char values.
23 -
const CHARS: [u8; 3] = ['x'; 3];
24 -
25 -
/// Access const bool array.
26 -
fn constRepeatBool() -> bool {
27 -
    return BOOLS[1];
28 -
}
29 -
30 -
/// Access const char array.
31 -
fn constRepeatChar() -> u8 {
32 -
    return CHARS[2];
33 -
}
lib/std/lang/lower/tests/array.repeat.ril deleted +0 -55
1 -
data $BOOLS align 1 {
2 -
    w8 1 * 3;
3 -
}
4 -
5 -
data $CHARS align 1 {
6 -
    w8 120 * 3;
7 -
}
8 -
9 -
fn w32 $arrayRepeatI32() {
10 -
  @entry0
11 -
    reserve %0 12 4;
12 -
    store w32 42 %0 0;
13 -
    store w32 42 %0 4;
14 -
    store w32 42 %0 8;
15 -
    sload w32 %1 %0 0;
16 -
    ret %1;
17 -
}
18 -
19 -
fn w8 $arrayRepeatBool() {
20 -
  @entry0
21 -
    reserve %0 3 1;
22 -
    store w8 1 %0 0;
23 -
    store w8 1 %0 1;
24 -
    store w8 1 %0 2;
25 -
    add w64 %1 %0 1;
26 -
    load w8 %2 %1 0;
27 -
    ret %2;
28 -
}
29 -
30 -
fn w8 $arrayRepeatChar() {
31 -
  @entry0
32 -
    reserve %0 3 1;
33 -
    store w8 120 %0 0;
34 -
    store w8 120 %0 1;
35 -
    store w8 120 %0 2;
36 -
    add w64 %1 %0 2;
37 -
    load w8 %2 %1 0;
38 -
    ret %2;
39 -
}
40 -
41 -
fn w8 $constRepeatBool() {
42 -
  @entry0
43 -
    copy %0 $BOOLS;
44 -
    add w64 %1 %0 1;
45 -
    load w8 %2 %1 0;
46 -
    ret %2;
47 -
}
48 -
49 -
fn w8 $constRepeatChar() {
50 -
  @entry0
51 -
    copy %0 $CHARS;
52 -
    add w64 %1 %0 2;
53 -
    load w8 %2 %1 0;
54 -
    ret %2;
55 -
}
lib/std/lang/lower/tests/assert.basic.rad deleted +0 -5
1 -
/// Test lowering of assert statement.
2 -
fn test(x: bool) -> i32 {
3 -
    assert x;
4 -
    return 0;
5 -
}
lib/std/lang/lower/tests/assert.basic.ril deleted +0 -8
1 -
fn w32 $test(w8 %0) {
2 -
  @entry0
3 -
    br.ne w32 %0 0 @assert.ok2 @assert.fail1;
4 -
  @assert.fail1
5 -
    unreachable;
6 -
  @assert.ok2
7 -
    ret 0;
8 -
}
lib/std/lang/lower/tests/binop.bitwise.rad deleted +0 -14
1 -
/// Returns the bitwise AND of two integers.
2 -
fn bitAnd(a: i32, b: i32) -> i32 {
3 -
    return a & b;
4 -
}
5 -
6 -
/// Returns the bitwise OR of two integers.
7 -
fn bitOr(a: i32, b: i32) -> i32 {
8 -
    return a | b;
9 -
}
10 -
11 -
/// Returns the bitwise XOR of two integers.
12 -
fn bitXor(a: i32, b: i32) -> i32 {
13 -
    return a ^ b;
14 -
}
lib/std/lang/lower/tests/binop.bitwise.ril deleted +0 -17
1 -
fn w32 $bitAnd(w32 %0, w32 %1) {
2 -
  @entry0
3 -
    and w32 %2 %0 %1;
4 -
    ret %2;
5 -
}
6 -
7 -
fn w32 $bitOr(w32 %0, w32 %1) {
8 -
  @entry0
9 -
    or w32 %2 %0 %1;
10 -
    ret %2;
11 -
}
12 -
13 -
fn w32 $bitXor(w32 %0, w32 %1) {
14 -
  @entry0
15 -
    xor w32 %2 %0 %1;
16 -
    ret %2;
17 -
}
lib/std/lang/lower/tests/cast.same.size.rad deleted +0 -43
1 -
/// Cast i8 to u8 (same size, no-op in lowering).
2 -
fn i8ToU8(x: i8) -> u8 {
3 -
    return x as u8;
4 -
}
5 -
6 -
/// Cast u8 to i8 (same size, no-op in lowering).
7 -
fn u8ToI8(x: u8) -> i8 {
8 -
    return x as i8;
9 -
}
10 -
11 -
/// Cast i16 to u16 (same size, no-op in lowering).
12 -
fn i16ToU16(x: i16) -> u16 {
13 -
    return x as u16;
14 -
}
15 -
16 -
/// Cast u16 to i16 (same size, no-op in lowering).
17 -
fn u16ToI16(x: u16) -> i16 {
18 -
    return x as i16;
19 -
}
20 -
21 -
/// Equality via same-size cast should lower to `eq w8`.
22 -
fn eqI8ToU8(x: i8) -> bool {
23 -
    let y: u8 = x as u8;
24 -
    return y == 255;
25 -
}
26 -
27 -
/// Inequality via same-size cast should lower to `ne w8`.
28 -
fn neI8ToU8(x: i8) -> bool {
29 -
    let y: u8 = x as u8;
30 -
    return y != 255;
31 -
}
32 -
33 -
/// Equality via same-size cast should lower to `eq w8`.
34 -
fn eqU8ToI8(x: u8) -> bool {
35 -
    let y: i8 = x as i8;
36 -
    return y == -1;
37 -
}
38 -
39 -
/// Inequality via same-size cast should lower to `ne w8`.
40 -
fn neU8ToI8(x: u8) -> bool {
41 -
    let y: i8 = x as i8;
42 -
    return y != -1;
43 -
}
lib/std/lang/lower/tests/cast.same.size.ril deleted +0 -43
1 -
fn w8 $i8ToU8(w8 %0) {
2 -
  @entry0
3 -
    ret %0;
4 -
}
5 -
6 -
fn w8 $u8ToI8(w8 %0) {
7 -
  @entry0
8 -
    ret %0;
9 -
}
10 -
11 -
fn w16 $i16ToU16(w16 %0) {
12 -
  @entry0
13 -
    ret %0;
14 -
}
15 -
16 -
fn w16 $u16ToI16(w16 %0) {
17 -
  @entry0
18 -
    ret %0;
19 -
}
20 -
21 -
fn w8 $eqI8ToU8(w8 %0) {
22 -
  @entry0
23 -
    eq w8 %1 %0 255;
24 -
    ret %1;
25 -
}
26 -
27 -
fn w8 $neI8ToU8(w8 %0) {
28 -
  @entry0
29 -
    ne w8 %1 %0 255;
30 -
    ret %1;
31 -
}
32 -
33 -
fn w8 $eqU8ToI8(w8 %0) {
34 -
  @entry0
35 -
    eq w8 %1 %0 -1;
36 -
    ret %1;
37 -
}
38 -
39 -
fn w8 $neU8ToI8(w8 %0) {
40 -
  @entry0
41 -
    ne w8 %1 %0 -1;
42 -
    ret %1;
43 -
}
lib/std/lang/lower/tests/compound.assign.rad deleted +0 -6
1 -
/// Compound assignment with local variable.
2 -
fn compoundLocal(x: i32) -> i32 {
3 -
    let mut a: i32 = x;
4 -
    a += 10;
5 -
    return a;
6 -
}
lib/std/lang/lower/tests/compound.assign.ril deleted +0 -5
1 -
fn w32 $compoundLocal(w32 %0) {
2 -
  @entry0
3 -
    add w32 %1 %0 10;
4 -
    ret %1;
5 -
}
lib/std/lang/lower/tests/cond.expr.rad deleted +0 -5
1 -
//! Test lowering of conditional expressions.
2 -
fn condExpr(flag: bool) -> i32 {
3 -
    let x: i32 = 1 if flag else 2;
4 -
    return x;
5 -
}
lib/std/lang/lower/tests/cond.expr.ril deleted +0 -10
1 -
fn w32 $condExpr(w8 %0) {
2 -
  @entry0
3 -
    br.ne w32 %0 0 @cond#then1 @cond#else2;
4 -
  @cond#then1
5 -
    jmp @cond#merge3(1);
6 -
  @cond#else2
7 -
    jmp @cond#merge3(2);
8 -
  @cond#merge3(w32 %1)
9 -
    ret %1;
10 -
}
lib/std/lang/lower/tests/const.array.rad deleted +0 -6
1 -
/// Test array constant lowering.
2 -
const VALUES: [i32; 3] = [10, 20, 30];
3 -
4 -
fn getSum() -> i32 {
5 -
    return VALUES[0] + VALUES[1] + VALUES[2];
6 -
}
lib/std/lang/lower/tests/const.array.ril deleted +0 -22
1 -
data $VALUES align 4 {
2 -
    w32 10;
3 -
    w32 20;
4 -
    w32 30;
5 -
}
6 -
7 -
fn w32 $getSum() {
8 -
  @entry0
9 -
    copy %0 $VALUES;
10 -
    sload w32 %1 %0 0;
11 -
    copy %2 $VALUES;
12 -
    mul w64 %3 1 4;
13 -
    add w64 %4 %2 %3;
14 -
    sload w32 %5 %4 0;
15 -
    add w32 %6 %1 %5;
16 -
    copy %7 $VALUES;
17 -
    mul w64 %8 2 4;
18 -
    add w64 %9 %7 %8;
19 -
    sload w32 %10 %9 0;
20 -
    add w32 %11 %6 %10;
21 -
    ret %11;
22 -
}
lib/std/lang/lower/tests/const.record.ctor.rad deleted +0 -8
1 -
/// Constant unlabeled record constructor.
2 -
record Pair(i32, i32);
3 -
4 -
const P: Pair = Pair(40, 2);
5 -
6 -
fn isExpected() -> bool {
7 -
    return P == Pair(40, 2);
8 -
}
lib/std/lang/lower/tests/const.record.rad deleted +0 -11
1 -
/// Test record constant lowering.
2 -
record Point {
3 -
    x: i32,
4 -
    y: i32,
5 -
}
6 -
7 -
const ORIGIN: Point = Point { x: 3, y: 4 };
8 -
9 -
fn getSum() -> i32 {
10 -
    return ORIGIN.x + ORIGIN.y;
11 -
}
lib/std/lang/lower/tests/const.union.payload.ctor.rad deleted +0 -16
1 -
/// Constant union payload constructor call.
2 -
union Value {
3 -
    Int(i32),
4 -
    Bool(bool),
5 -
    None,
6 -
}
7 -
8 -
const V: Value = Value::Int(42);
9 -
10 -
fn toInt() -> i32 {
11 -
    match V {
12 -
        case Value::Int(x) => return x,
13 -
        case Value::Bool(_) => return -1,
14 -
        case Value::None => return -2,
15 -
    }
16 -
}
lib/std/lang/lower/tests/const.union.record.literal.rad deleted +0 -14
1 -
/// Constant union record payload literal.
2 -
union Expr {
3 -
    Nil,
4 -
    Pair { first: i32, second: i32 },
5 -
}
6 -
7 -
const E: Expr = Expr::Pair { first: 20, second: 22 };
8 -
9 -
fn sum() -> i32 {
10 -
    match E {
11 -
        case Expr::Nil => return -1,
12 -
        case Expr::Pair { first, second } => return first + second,
13 -
    }
14 -
}
lib/std/lang/lower/tests/match.multi.seal.rad deleted +0 -12
1 -
/// Regression test: intermediate arm blocks in multi-pattern matches must be
2 -
/// sealed so that SSA construction uses single-predecessor optimization
3 -
/// instead of creating unresolved block parameters.
4 -
5 -
union Kind { A, B, C, D }
6 -
7 -
fn classify(k: Kind, y: i32) -> i32 {
8 -
    match k {
9 -
        case Kind::A, Kind::B => return y,
10 -
        else => return y + 1,
11 -
    }
12 -
}
lib/std/lang/lower/tests/match.multi.seal.ril deleted +0 -15
1 -
fn w32 $classify(w8 %0, w32 %1) {
2 -
  @entry0
3 -
    jmp @arm1;
4 -
  @arm1
5 -
    br.eq w8 %0 0 @case2 @arm4;
6 -
  @case2
7 -
    ret %1;
8 -
  @arm3
9 -
    jmp @else5;
10 -
  @arm4
11 -
    br.eq w8 %0 1 @case2 @arm3;
12 -
  @else5
13 -
    add w32 %3 %1 1;
14 -
    ret %3;
15 -
}
lib/std/lang/lower/tests/match.nested.iflet.rad deleted +0 -18
1 -
/// Nested record pattern in if-let-case.
2 -
record Inner {
3 -
    x: i32,
4 -
    y: i32,
5 -
}
6 -
7 -
union Outer {
8 -
    A { inner: Inner, z: i32 },
9 -
    B,
10 -
}
11 -
12 -
/// If-let-case with nested record destructuring.
13 -
fn extract(o: Outer) -> i32 {
14 -
    if let case Outer::A { inner: Inner { x, y }, z } = o {
15 -
        return x + y + z;
16 -
    }
17 -
    return 0;
18 -
}
lib/std/lang/lower/tests/match.nested.iflet.ril deleted +0 -19
1 -
fn w32 $extract(w64 %0) {
2 -
  @entry0
3 -
    reserve %1 16 4;
4 -
    blit %1 %0 16;
5 -
    load w8 %2 %1 0;
6 -
    br.eq w8 %2 0 @then1 @else2;
7 -
  @then1
8 -
    add w64 %3 %1 4;
9 -
    sload w32 %4 %3 0;
10 -
    sload w32 %5 %3 4;
11 -
    sload w32 %6 %3 8;
12 -
    add w32 %7 %4 %5;
13 -
    add w32 %8 %7 %6;
14 -
    ret %8;
15 -
  @else2
16 -
    jmp @merge3;
17 -
  @merge3
18 -
    ret 0;
19 -
}
lib/std/lang/lower/tests/match.nested.pattern.rad deleted +0 -18
1 -
/// Nested pattern matching in case arms.
2 -
record Inner {
3 -
    x: i32,
4 -
    y: i32,
5 -
}
6 -
7 -
union Outer {
8 -
    A { inner: Inner, z: i32 },
9 -
    B,
10 -
}
11 -
12 -
/// Destructure a nested record inside a union variant pattern.
13 -
fn nested(o: Outer) -> i32 {
14 -
    match o {
15 -
        case Outer::A { inner: Inner { x, y }, z } => return x + y + z,
16 -
        case Outer::B => return 0,
17 -
    }
18 -
}
lib/std/lang/lower/tests/match.nested.pattern.ril deleted +0 -21
1 -
fn w32 $nested(w64 %0) {
2 -
  @entry0
3 -
    reserve %1 16 4;
4 -
    blit %1 %0 16;
5 -
    jmp @arm1;
6 -
  @arm1
7 -
    load w8 %2 %1 0;
8 -
    br.eq w8 %2 0 @case2 @arm3;
9 -
  @case2
10 -
    add w64 %3 %1 4;
11 -
    sload w32 %4 %3 0;
12 -
    sload w32 %5 %3 4;
13 -
    sload w32 %6 %3 8;
14 -
    add w32 %7 %4 %5;
15 -
    add w32 %8 %7 %6;
16 -
    ret %8;
17 -
  @arm3
18 -
    jmp @case4;
19 -
  @case4
20 -
    ret 0;
21 -
}
lib/std/lang/lower/tests/match.nested.record.rad deleted +0 -18
1 -
/// Nested record destructuring inside a union variant.
2 -
record Point {
3 -
    x: i32,
4 -
    y: i32,
5 -
}
6 -
7 -
union Shape {
8 -
    Circle { center: Point, radius: i32 },
9 -
    None,
10 -
}
11 -
12 -
/// Destructure nested record fields in both arms.
13 -
fn getX(s: Shape) -> i32 {
14 -
    match s {
15 -
        case Shape::Circle { center: Point { x, .. }, .. } => return x,
16 -
        case Shape::None => return 0,
17 -
    }
18 -
}
lib/std/lang/lower/tests/match.nested.record.ril deleted +0 -17
1 -
fn w32 $getX(w64 %0) {
2 -
  @entry0
3 -
    reserve %1 16 4;
4 -
    blit %1 %0 16;
5 -
    jmp @arm1;
6 -
  @arm1
7 -
    load w8 %2 %1 0;
8 -
    br.eq w8 %2 0 @case2 @arm3;
9 -
  @case2
10 -
    add w64 %3 %1 4;
11 -
    sload w32 %4 %3 0;
12 -
    ret %4;
13 -
  @arm3
14 -
    jmp @case4;
15 -
  @case4
16 -
    ret 0;
17 -
}
lib/std/lang/lower/tests/match.nested.union.rad deleted +0 -16
1 -
/// Nested union variant pattern inside a record field.
2 -
union Dir { N, S }
3 -
4 -
union Cmd {
5 -
    Move { dir: Dir, speed: i32 },
6 -
    Stop,
7 -
}
8 -
9 -
/// Match nested union variants inside record fields.
10 -
fn dispatch(c: Cmd) -> i32 {
11 -
    match c {
12 -
        case Cmd::Move { dir: Dir::N, speed } => return speed,
13 -
        case Cmd::Move { dir: Dir::S, speed } => return 0 - speed,
14 -
        else => return 0,
15 -
    }
16 -
}
lib/std/lang/lower/tests/match.nested.union.ril deleted +0 -35
1 -
fn w32 $dispatch(w64 %0) {
2 -
  @entry0
3 -
    reserve %1 12 4;
4 -
    blit %1 %0 12;
5 -
    jmp @arm1;
6 -
  @arm1
7 -
    load w8 %2 %1 0;
8 -
    br.eq w8 %2 0 @case2 @arm3;
9 -
  @case2
10 -
    add w64 %3 %1 4;
11 -
    load w8 %4 %3 0;
12 -
    br.eq w8 %4 0 @nest4 @arm3;
13 -
  @arm3
14 -
    load w8 %6 %1 0;
15 -
    br.eq w8 %6 0 @case6 @arm7;
16 -
  @nest4
17 -
    sload w32 %5 %3 4;
18 -
    jmp @case5;
19 -
  @case5
20 -
    ret %5;
21 -
  @case6
22 -
    add w64 %7 %1 4;
23 -
    load w8 %8 %7 0;
24 -
    br.eq w8 %8 1 @nest8 @arm7;
25 -
  @arm7
26 -
    jmp @else10;
27 -
  @nest8
28 -
    sload w32 %9 %7 4;
29 -
    jmp @case9;
30 -
  @case9
31 -
    sub w32 %10 0 %9;
32 -
    ret %10;
33 -
  @else10
34 -
    ret 0;
35 -
}
lib/std/lang/lower/tests/opt.record.eq.rad deleted +0 -17
1 -
/// Tests equality between a record and an optional record (T == ?T).
2 -
3 -
record Id { n: u32 }
4 -
5 -
/// Wraps a record in an optional.
6 -
fn makeOpt(id: Id) -> ?Id {
7 -
    return id;
8 -
}
9 -
10 -
@default fn main() -> i32 {
11 -
    let a = Id { n: 5 };
12 -
    let b = makeOpt(a);
13 -
    if a == b {
14 -
        return 0;
15 -
    }
16 -
    return 1;
17 -
}
lib/std/lang/lower/tests/opt.record.eq.ril deleted +0 -35
1 -
fn w64 $makeOpt(w64 %0, w64 %1) {
2 -
  @entry0
3 -
    reserve %2 8 4;
4 -
    store w8 1 %2 0;
5 -
    add w64 %3 %2 4;
6 -
    blit %3 %1 4;
7 -
    blit %0 %2 8;
8 -
    ret %0;
9 -
}
10 -
11 -
fn w32 $main() {
12 -
  @entry0
13 -
    reserve %0 4 4;
14 -
    store w32 5 %0 0;
15 -
    reserve %1 8 4;
16 -
    call w64 %2 $makeOpt(%1, %0);
17 -
    reserve %3 8 4;
18 -
    store w8 1 %3 0;
19 -
    add w64 %4 %3 4;
20 -
    blit %4 %0 4;
21 -
    load w8 %5 %3 0;
22 -
    load w8 %6 %2 0;
23 -
    eq w8 %7 %5 %6;
24 -
    eq w8 %8 %5 0;
25 -
    load w32 %9 %3 4;
26 -
    load w32 %10 %2 4;
27 -
    eq w32 %11 %9 %10;
28 -
    or w32 %12 %8 %11;
29 -
    and w32 %13 %7 %12;
30 -
    br.ne w32 %13 0 @then1 @merge2;
31 -
  @then1
32 -
    ret 0;
33 -
  @merge2
34 -
    ret 1;
35 -
}
lib/std/lang/lower/tests/opt.slice.npo.rad deleted +0 -14
1 -
//! Test null pointer optimization for optional slices.
2 -
//! ?*[T] uses the same representation as *[T], with nil = null data pointer.
3 -
4 -
fn wrapSlice(s: *[u8]) -> ?*[u8] {
5 -
    return s;
6 -
}
7 -
8 -
fn nilSlice() -> ?*[u8] {
9 -
    return nil;
10 -
}
11 -
12 -
fn nilCheck(s: ?*[u8]) -> bool {
13 -
    return s == nil;
14 -
}
lib/std/lang/lower/tests/opt.slice.npo.ril deleted +0 -22
1 -
fn w64 $wrapSlice(w64 %0, w64 %1) {
2 -
  @entry0
3 -
    blit %0 %1 16;
4 -
    ret %0;
5 -
}
6 -
7 -
fn w64 $nilSlice(w64 %0) {
8 -
  @entry0
9 -
    reserve %1 16 8;
10 -
    store w64 0 %1 0;
11 -
    store w32 0 %1 8;
12 -
    store w32 0 %1 12;
13 -
    blit %0 %1 16;
14 -
    ret %0;
15 -
}
16 -
17 -
fn w8 $nilCheck(w64 %0) {
18 -
  @entry0
19 -
    load w64 %1 %0 0;
20 -
    eq w64 %2 %1 0;
21 -
    ret %2;
22 -
}
lib/std/lang/lower/tests/ptr.assign.rad deleted +0 -4
1 -
/// Writes through a pointer dereference.
2 -
fn derefAssign(p: *mut i32, val: i32) {
3 -
    *p = val;
4 -
}
lib/std/lang/lower/tests/ptr.assign.ril deleted +0 -5
1 -
fn w32 $derefAssign(w64 %0, w32 %1) {
2 -
  @entry0
3 -
    store w32 %1 %0 0;
4 -
    ret;
5 -
}
lib/std/lang/lower/tests/ptr.deref.rad deleted +0 -4
1 -
/// Dereferences a pointer to read a scalar value.
2 -
fn deref(p: *i32) -> i32 {
3 -
    return *p;
4 -
}
lib/std/lang/lower/tests/ptr.deref.ril deleted +0 -5
1 -
fn w32 $deref(w64 %0) {
2 -
  @entry0
3 -
    sload w32 %1 %0 0;
4 -
    ret %1;
5 -
}
lib/std/lang/lower/tests/record.field.assign.rad deleted +0 -6
1 -
record Point { x: i32, y: i32 }
2 -
3 -
fn set() {
4 -
    let mut p = Point { x: 1, y: 2 };
5 -
    p.x = 3;
6 -
}
lib/std/lang/lower/tests/record.field.assign.ril deleted +0 -8
1 -
fn w32 $set() {
2 -
  @entry0
3 -
    reserve %0 8 4;
4 -
    store w32 1 %0 0;
5 -
    store w32 2 %0 4;
6 -
    store w32 3 %0 0;
7 -
    ret;
8 -
}
lib/std/lang/lower/tests/record.ptr.access.rad deleted +0 -5
1 -
record Point { x: i32, y: i32 }
2 -
3 -
fn get(p: *Point) -> i32 {
4 -
    return p.x;
5 -
}
lib/std/lang/lower/tests/record.ptr.access.ril deleted +0 -5
1 -
fn w32 $get(w64 %0) {
2 -
  @entry0
3 -
    sload w32 %1 %0 0;
4 -
    ret %1;
5 -
}
lib/std/lang/lower/tests/reserve.loop.rad deleted +0 -12
1 -
record Pair { a: i32, b: i32 }
2 -
3 -
fn reserveInLoop(n: i32) -> i32 {
4 -
    let mut sum: i32 = 0;
5 -
    let mut i: i32 = 0;
6 -
    while i < n {
7 -
        let p: Pair = Pair { a: i, b: i + 1 };
8 -
        sum += p.a + p.b;
9 -
        i += 1;
10 -
    }
11 -
    return sum;
12 -
}
lib/std/lang/lower/tests/reserve.loop.ril deleted +0 -19
1 -
fn w32 $reserveInLoop(w32 %0) {
2 -
  @entry0
3 -
    jmp @while1(0, %0, 0);
4 -
  @while1(w32 %1, w32 %2, w32 %5)
5 -
    br.slt w32 %1 %2 @body2 @merge3;
6 -
  @body2
7 -
    reserve %3 8 4;
8 -
    store w32 %1 %3 0;
9 -
    add w32 %4 %1 1;
10 -
    store w32 %4 %3 4;
11 -
    sload w32 %6 %3 0;
12 -
    sload w32 %7 %3 4;
13 -
    add w32 %8 %6 %7;
14 -
    add w32 %9 %5 %8;
15 -
    add w32 %10 %1 1;
16 -
    jmp @while1(%10, %2, %9);
17 -
  @merge3
18 -
    ret %5;
19 -
}
lib/std/lang/lower/tests/slice.append.rad deleted +0 -10
1 -
/// Allocator-like record used by .append().
2 -
record Alloc {
3 -
    func: fn(*mut opaque, u32, u32) -> *mut opaque,
4 -
    ctx: *mut opaque,
5 -
}
6 -
7 -
/// Append an i32 to a mutable slice.
8 -
fn appendI32(s: *mut [i32], val: i32, a: Alloc) {
9 -
    s.append(val, a);
10 -
}
lib/std/lang/lower/tests/slice.append.ril deleted +0 -37
1 -
fn w32 $appendI32(w64 %0, w32 %1, w64 %2) {
2 -
  @entry0
3 -
    load w32 %3 %0 8;
4 -
    load w32 %4 %0 12;
5 -
    br.ult w32 %3 %4 @append.store1 @append.grow2;
6 -
  @append.store1
7 -
    load w64 %18 %0 0;
8 -
    mul w64 %19 %3 4;
9 -
    add w64 %20 %18 %19;
10 -
    store w32 %1 %20 0;
11 -
    add w32 %21 %3 1;
12 -
    store w32 %21 %0 8;
13 -
    ret;
14 -
  @append.grow2
15 -
    shl w32 %5 %4 1;
16 -
    or w32 %6 %5 1;
17 -
    load w64 %7 %2 0;
18 -
    load w64 %8 %2 8;
19 -
    mul w32 %9 %6 4;
20 -
    call w64 %10 %7(%8, %9, 4);
21 -
    load w64 %11 %0 0;
22 -
    mul w32 %12 %3 4;
23 -
    jmp @append3(0);
24 -
  @append3(w32 %13)
25 -
    br.ult w32 %13 %12 @append4 @append5;
26 -
  @append4
27 -
    add w64 %14 %11 %13;
28 -
    load w8 %15 %14 0;
29 -
    add w64 %16 %10 %13;
30 -
    store w8 %15 %16 0;
31 -
    add w32 %17 %13 1;
32 -
    jmp @append3(%17);
33 -
  @append5
34 -
    store w64 %10 %0 0;
35 -
    store w32 %6 %0 12;
36 -
    jmp @append.store1;
37 -
}
lib/std/lang/lower/tests/slice.delete.rad deleted +0 -4
1 -
/// Delete an element from a mutable i32 slice by index.
2 -
fn deleteI32(s: *mut [i32], idx: u32) {
3 -
    s.delete(idx);
4 -
}
lib/std/lang/lower/tests/slice.delete.ril deleted +0 -30
1 -
fn w32 $deleteI32(w64 %0, w32 %1) {
2 -
  @entry0
3 -
    load w32 %2 %0 8;
4 -
    br.ult w32 %1 %2 @guard#pass1 @guard#trap2;
5 -
  @guard#pass1
6 -
    load w64 %3 %0 0;
7 -
    mul w64 %4 %1 4;
8 -
    add w64 %5 %3 %4;
9 -
    add w64 %6 %5 4;
10 -
    sub w32 %7 %2 %1;
11 -
    sub w32 %8 %7 1;
12 -
    mul w32 %9 %8 4;
13 -
    jmp @delete3(0);
14 -
  @guard#trap2
15 -
    ebreak;
16 -
    unreachable;
17 -
  @delete3(w32 %10)
18 -
    br.ult w32 %10 %9 @delete4 @delete5;
19 -
  @delete4
20 -
    add w64 %11 %6 %10;
21 -
    load w8 %12 %11 0;
22 -
    add w64 %13 %5 %10;
23 -
    store w8 %12 %13 0;
24 -
    add w32 %14 %10 1;
25 -
    jmp @delete3(%14);
26 -
  @delete5
27 -
    sub w32 %15 %2 1;
28 -
    store w32 %15 %0 8;
29 -
    ret;
30 -
}
lib/std/lang/lower/tests/trait.supertrait.rad deleted +0 -23
1 -
record Widget {
2 -
    x: i32,
3 -
}
4 -
5 -
trait Base {
6 -
    fn (*Base) get() -> i32;
7 -
}
8 -
9 -
trait Child: Base {
10 -
    fn (*mut Child) set(n: i32);
11 -
}
12 -
13 -
instance Base for Widget {
14 -
    fn (w: *Widget) get() -> i32 {
15 -
        return w.x;
16 -
    }
17 -
}
18 -
19 -
instance Child for Widget {
20 -
    fn (w: *mut Widget) set(n: i32) {
21 -
        w.x = n;
22 -
    }
23 -
}
lib/std/lang/lower/tests/trait.supertrait.ril deleted +0 -20
1 -
data $"vtable::Widget::Base" align 8 {
2 -
    fn $"Widget::get";
3 -
}
4 -
5 -
data $"vtable::Widget::Child" align 8 {
6 -
    fn $"Widget::get";
7 -
    fn $"Widget::set";
8 -
}
9 -
10 -
fn w32 $"Widget::get"(w64 %0) {
11 -
  @entry0
12 -
    sload w32 %1 %0 0;
13 -
    ret %1;
14 -
}
15 -
16 -
fn w32 $"Widget::set"(w64 %0, w32 %1) {
17 -
  @entry0
18 -
    store w32 %1 %0 0;
19 -
    ret;
20 -
}
test/asm/run deleted +0 -57
1 -
#!/bin/sh
2 -
# Run assembly generation tests.
3 -
# Usage: test/asm/run <test.rad>..
4 -
#
5 -
# Each test is compiled to a binary and run with the emulator.
6 -
7 -
EMU="${RAD_EMULATOR:-emulator} -run"
8 -
9 -
if [ $# -eq 0 ]; then
10 -
  echo "error: no tests specified" >&2
11 -
  exit 1
12 -
fi
13 -
14 -
# Disable core dumps for tests.
15 -
ulimit -c 0
16 -
17 -
passed=0
18 -
failed=0
19 -
20 -
# Run each test.
21 -
for test in "$@"; do
22 -
  bin="${test%.rad}.rv64"
23 -
  echo -n "test $test ... "
24 -
25 -
  if [ ! -f "$bin" ]; then
26 -
    echo "FAILED (binary not found: $bin)"
27 -
    failed=$((failed + 1))
28 -
    continue
29 -
  fi
30 -
31 -
  # Parse expected return code from `//! returns: N` header (default 0).
32 -
  expected=0
33 -
  line=$(grep -m1 '^//! returns:' "$test" | sed 's/^\/\/! returns: *//')
34 -
  if [ -n "$line" ]; then
35 -
    expected="$line"
36 -
  fi
37 -
38 -
  $EMU "$bin" >/dev/null 2>&1
39 -
  ret=$?
40 -
41 -
  if [ "$ret" -eq "$expected" ]; then
42 -
    echo "ok"
43 -
    passed=$((passed + 1))
44 -
  else
45 -
    echo "FAILED (expected: $expected, got: $ret)"
46 -
    failed=$((failed + 1))
47 -
  fi
48 -
done
49 -
echo
50 -
51 -
if [ "$failed" -eq 0 ]; then
52 -
  echo "test result: ok. $passed passed; $failed failed"
53 -
  exit 0
54 -
else
55 -
  echo "test result: FAILED. $passed passed; $failed failed"
56 -
  exit 1
57 -
fi
test/lower/run deleted +0 -50
1 -
#!/bin/sh
2 -
# Run lowering tests.
3 -
# Usage: test/lower/run [<test.rad>...]
4 -
#
5 -
# If no arguments are provided, runs all tests in `lib/std/lang/lower/tests/`.
6 -
7 -
BINARY="test/lower/lower-test.rv64"
8 -
TEST_DIR="lib/std/lang/lower/tests"
9 -
EMU="${RAD_EMULATOR:-emulator} -stack-size=1024 -run"
10 -
11 -
if [ ! -f "$BINARY" ]; then
12 -
  echo "error: test binary not found: $BINARY" >&2
13 -
  echo "hint: run 'make lower-test' first" >&2
14 -
  exit 1
15 -
fi
16 -
17 -
# Disable core dumps for tests.
18 -
ulimit -c 0
19 -
20 -
# Collect tests.
21 -
if [ $# -eq 0 ]; then
22 -
  tests=$(find "$TEST_DIR" -name '*.rad' | sort)
23 -
else
24 -
  tests="$*"
25 -
fi
26 -
27 -
if [ -z "$tests" ]; then
28 -
  echo "error: no tests found" >&2
29 -
  exit 1
30 -
fi
31 -
32 -
passed=0
33 -
failed=0
34 -
35 -
for test in $tests; do
36 -
  if $EMU "$BINARY" -- "$test"; then
37 -
    passed=$((passed + 1))
38 -
  else
39 -
    failed=$((failed + 1))
40 -
  fi
41 -
done
42 -
echo
43 -
44 -
if [ "$failed" -eq 0 ]; then
45 -
  echo "test result: ok. $passed passed; $failed failed"
46 -
  exit 0
47 -
else
48 -
  echo "test result: FAILED. $passed passed; $failed failed"
49 -
  exit 1
50 -
fi
test/run added +86 -0
1 +
#!/bin/sh
2 +
# Run binary tests.
3 +
# Usage: test/run [<test.rad>...]
4 +
#
5 +
# If no arguments are provided, runs all tests in `test/tests/`.
6 +
#
7 +
# For each test:
8 +
#   - If a `.ril` file exists alongside it, the IL output is checked
9 +
#     against it via the runner binary.
10 +
#   - If `//! returns: N` appears in the file, the test is compiled to
11 +
#     a binary and executed; the exit code must match N.
12 +
13 +
RUNNER="test/runner.rv64"
14 +
TEST_DIR="test/tests"
15 +
EMU="${RAD_EMULATOR:-emulator} -stack-size=1024 -run"
16 +
EMU_RUN="${RAD_EMULATOR:-emulator} -run"
17 +
18 +
if [ ! -f "$RUNNER" ]; then
19 +
  echo "error: runner binary not found: $RUNNER" >&2
20 +
  echo "hint: run 'make test' first" >&2
21 +
  exit 1
22 +
fi
23 +
24 +
# Disable core dumps for tests.
25 +
ulimit -c 0
26 +
27 +
# Collect tests.
28 +
if [ $# -eq 0 ]; then
29 +
  tests=$(find "$TEST_DIR" -name '*.rad' | sort)
30 +
else
31 +
  tests="$*"
32 +
fi
33 +
34 +
if [ -z "$tests" ]; then
35 +
  echo "error: no tests found" >&2
36 +
  exit 1
37 +
fi
38 +
39 +
passed=0
40 +
failed=0
41 +
42 +
for test in $tests; do
43 +
  ril="${test%.rad}.ril"
44 +
  bin="${test%.rad}.rv64"
45 +
46 +
  # IL check: run the runner if a .ril file exists.
47 +
  if [ -f "$ril" ]; then
48 +
    if $EMU "$RUNNER" -- "$test"; then
49 +
      passed=$((passed + 1))
50 +
    else
51 +
      failed=$((failed + 1))
52 +
    fi
53 +
  fi
54 +
55 +
  # Execution check: run the binary if //! returns: is present.
56 +
  returns=$(grep -m1 '^//! returns:' "$test" | sed 's/^\/\/! returns: *//')
57 +
  if [ -n "$returns" ]; then
58 +
    echo -n "test $test ... "
59 +
60 +
    if [ ! -f "$bin" ]; then
61 +
      echo "FAILED (binary not found: $bin)"
62 +
      failed=$((failed + 1))
63 +
      continue
64 +
    fi
65 +
66 +
    $EMU_RUN "$bin" >/dev/null 2>&1
67 +
    ret=$?
68 +
69 +
    if [ "$ret" -eq "$returns" ]; then
70 +
      echo "ok"
71 +
      passed=$((passed + 1))
72 +
    else
73 +
      echo "FAILED (expected: $returns, got: $ret)"
74 +
      failed=$((failed + 1))
75 +
    fi
76 +
  fi
77 +
done
78 +
echo
79 +
80 +
if [ "$failed" -eq 0 ]; then
81 +
  echo "test result: ok. $passed passed; $failed failed"
82 +
  exit 0
83 +
else
84 +
  echo "test result: FAILED. $passed passed; $failed failed"
85 +
  exit 1
86 +
fi
test/lower/lower-test.rad → test/runner.rad renamed +68 -61
1 -
//! Standalone lowering pass test runner.
1 +
//! IL snapshot test runner.
2 2
//!
3 -
//! Runs a single test that compares generated IL against expected output.
4 -
//! The test path should be a .rad source file; the expected .ril file is
5 -
//! derived by replacing the extension.
3 +
//! Given a `.rad` source file, lowers it to IL and compares the output
4 +
//! against the corresponding `.ril` snapshot file. Called by `test/run`
5 +
//! for every test that has a `.ril` file.
6 6
7 7
use std::io;
8 8
use std::mem;
9 9
use std::sys;
10 10
use std::sys::unix;
11 11
use std::lang::alloc;
12 12
use std::lang::ast;
13 -
use std::lang::il;
14 13
use std::lang::il::printer;
15 14
use std::lang::parser;
16 15
use std::lang::scanner;
17 -
use std::lang::module;
18 16
use std::lang::resolver;
19 17
use std::lang::strings;
20 18
use std::lang::lower;
21 19
22 -
/// Buffer size for reading source files (4 KB).
23 -
const SOURCE_BUF_SIZE: u32 = 4096;
24 -
/// Buffer size for reading expected IL files (4 KB).
25 -
const EXPECTED_BUF_SIZE: u32 = 4096;
26 -
/// Buffer size for generated IL output (4 KB).
27 -
const OUTPUT_BUF_SIZE: u32 = 4096;
28 -
/// Arena size for AST/IL allocations (64 KB).
29 -
const ARENA_SIZE: u32 = 65536;
20 +
/// Buffer size for reading source files (8 KB).
21 +
const SOURCE_BUF_SIZE: u32 = 8192;
22 +
/// Buffer size for reading expected IL files (32 KB).
23 +
const EXPECTED_BUF_SIZE: u32 = 32768;
24 +
/// Buffer size for generated IL output (32 KB).
25 +
const OUTPUT_BUF_SIZE: u32 = 32768;
26 +
/// Arena size for AST/IL allocations (512 KB).
27 +
const ARENA_SIZE: u32 = 524288;
30 28
/// Maximum path length for expected IL file path.
31 29
const MAX_PATH_LEN: u32 = 256;
32 30
33 31
/// String pool.
34 32
static STRING_POOL: strings::Pool = strings::Pool { table: undefined, count: 0 };
35 33
34 +
/// Maximum number of AST nodes per test file.
35 +
const MAX_NODE_DATA: u32 = 4096;
36 +
/// Maximum number of resolver errors per test file.
37 +
const MAX_ERRORS: u32 = 16;
38 +
39 +
// Static storage for large buffers to avoid stack overflow.
40 +
// Tests run serially so sharing these is safe.
41 +
static SOURCE_BUF: [u8; SOURCE_BUF_SIZE] = undefined;
42 +
static EXPECTED_BUF: [u8; EXPECTED_BUF_SIZE] = undefined;
43 +
static OUTPUT_BUF: [u8; OUTPUT_BUF_SIZE] = undefined;
44 +
static AST_ARENA_STORAGE: [u8; ARENA_SIZE] = undefined;
45 +
static IL_ARENA_STORAGE: [u8; ARENA_SIZE] = undefined;
46 +
static PRINT_ARENA_STORAGE: [u8; ARENA_SIZE] = undefined;
47 +
static RESOLVER_ARENA_STORAGE: [u8; ARENA_SIZE] = undefined;
48 +
static NODE_DATA_STORAGE: [resolver::NodeData; MAX_NODE_DATA] = undefined;
49 +
static ERROR_STORAGE: [resolver::Error; MAX_ERRORS] = undefined;
50 +
36 51
/// Strip comment from a line. Returns sub-slice up to ';', trimmed of trailing whitespace.
37 52
fn stripLine(line: *[u8]) -> *[u8] {
38 53
    let mut end: u32 = 0;
39 54
    let mut i: u32 = 0;
40 55
84 99
    }
85 100
    return true;
86 101
}
87 102
88 103
/// Print diff between expected and actual output.
89 -
fn printDiff(testName: *[u8], expected: *[u8], actual: *[u8]) {
104 +
fn printDiff(expected: *[u8], actual: *[u8]) {
90 105
    io::printLn("\n;; Expected");
91 106
    io::print(expected);
92 107
    io::print("\n");
93 108
94 109
    io::printLn(";; Actual");
95 110
    io::print(actual);
96 111
    io::print("\n");
97 112
}
98 113
99 -
/// Derive the expected .ril path from a .rad source path. Replaces the .rad
100 -
/// extension with .ril. The output is null-terminated for use with syscalls.
101 -
fn deriveExpectedPath(sourcePath: *[u8], buf: *mut [u8]) -> ?*[u8] {
114 +
/// Derive the `.ril` path from a `.rad` source path. Returns nil if the path
115 +
/// does not end in `.rad` or the buffer is too small. The result is
116 +
/// null-terminated for use with syscalls.
117 +
fn deriveRilPath(sourcePath: *[u8], buf: *mut [u8]) -> ?*[u8] {
102 118
    let len = sourcePath.len;
103 119
    if len < 4 {
104 120
        return nil;
105 121
    }
106 122
    // Check for .rad extension.
109 125
        return nil;
110 126
    }
111 127
    if len + 1 > buf.len {
112 128
        return nil;
113 129
    }
114 -
    // Copy full path then overwrite extension with null terminator.
130 +
    // Copy full path then overwrite extension and add null terminator.
115 131
    try mem::copy(buf, sourcePath) catch {
116 132
        return nil;
117 133
    };
118 134
    // TODO: Rewrite this once we fix the compiler bug and add support for
119 135
    // additions in ranges.
123 139
    buf[len] = 0;
124 140
125 141
    return &buf[..len];
126 142
}
127 143
128 -
/// Run a single lowering test case. Returns `true` on success.
144 +
/// Run a single IL snapshot test case. Returns `true` on success.
129 145
fn runTest(sourcePath: *[u8]) -> bool {
130 -
    // Buffers for file I/O.
131 -
    let mut sourceBuf: [u8; SOURCE_BUF_SIZE] = undefined;
132 -
    let mut expectedBuf: [u8; EXPECTED_BUF_SIZE] = undefined;
133 -
    let mut outputBuf: [u8; OUTPUT_BUF_SIZE] = undefined;
134 -
    let mut expectedPathBuf: [u8; MAX_PATH_LEN] = undefined;
135 -
136 -
    // Parser and resolver storage.
137 -
    let mut astArenaStorage: [u8; ARENA_SIZE] = undefined;
138 -
    let mut ilArenaStorage: [u8; ARENA_SIZE] = undefined;
139 -
    let mut printArenaStorage: [u8; ARENA_SIZE] = undefined;
140 -
    let mut resolverArenaStorage: [u8; ARENA_SIZE] = undefined;
141 -
    let mut moduleArenaStorage: [u8; 1024] = undefined;
142 -
    let mut nodeDataStorage: [resolver::NodeData; 256] = undefined;
143 -
    let mut errorStorage: [resolver::Error; 4] = undefined;
146 +
    // Path buffer.
147 +
    let mut rilPathBuf: [u8; MAX_PATH_LEN] = undefined;
144 148
    let mut pkgScope: resolver::Scope = undefined;
145 -
    let mut moduleEntries: [module::ModuleEntry; 4] = undefined;
146 149
147 -
    // Derive expected path from source path.
148 -
    let expectedPath = deriveExpectedPath(sourcePath, &mut expectedPathBuf[..]) else {
149 -
        io::print("error: Invalid source path (must end in .rad): ");
150 +
    // Derive .ril path from source path.
151 +
    let rilPath = deriveRilPath(sourcePath, &mut rilPathBuf[..]) else {
152 +
        io::print("error: invalid source path (must end in .rad): ");
150 153
        io::printLn(sourcePath);
151 154
        return false;
152 155
    };
153 -
    // Read source file.
154 -
    let source = unix::readFile(sourcePath, &mut sourceBuf[..]) else {
155 -
        io::print("error: Could not read source: ");
156 -
        io::printLn(sourcePath);
156 +
157 +
    // Read expected IL.
158 +
    let expected = unix::readFile(rilPath, &mut EXPECTED_BUF[..]) else {
159 +
        io::print("error: could not read expected IL: ");
160 +
        io::printLn(rilPath);
157 161
        return false;
158 162
    };
159 -
    // Read expected IL.
160 -
    let expected = unix::readFile(expectedPath, &mut expectedBuf[..]) else {
161 -
        io::print("error: Could not read expected: ");
162 -
        io::printLn(expectedPath);
163 +
164 +
    // Read source file.
165 +
    let source = unix::readFile(sourcePath, &mut SOURCE_BUF[..]) else {
166 +
        io::print("error: could not read source: ");
167 +
        io::printLn(sourcePath);
163 168
        return false;
164 169
    };
170 +
165 171
    // Parse source.
166 -
    let mut astArena = ast::nodeArena(&mut astArenaStorage[..]);
172 +
    let mut astArena = ast::nodeArena(&mut AST_ARENA_STORAGE[..]);
167 173
    let root = try parser::parse(scanner::SourceLoc::String, source, &mut astArena, &mut STRING_POOL) catch {
168 -
        io::printLn("error: Parsing failed");
174 +
        io::printLn("error: parsing failed");
169 175
        return false;
170 176
    };
177 +
171 178
    // Run resolver.
172 -
    let mut moduleArena = ast::nodeArena(&mut moduleArenaStorage[..]);
173 -
    let mut moduleGraph = module::moduleGraph(&mut moduleEntries[..], &mut STRING_POOL, &mut moduleArena);
174 179
    let storage = resolver::ResolverStorage {
175 -
        arena: alloc::new(&mut resolverArenaStorage[..]),
176 -
        nodeData: &mut nodeDataStorage[..],
180 +
        arena: alloc::new(&mut RESOLVER_ARENA_STORAGE[..]),
181 +
        nodeData: &mut NODE_DATA_STORAGE[..],
177 182
        pkgScope: &mut pkgScope,
178 -
        errors: &mut errorStorage[..],
183 +
        errors: &mut ERROR_STORAGE[..],
179 184
    };
180 185
    let config = resolver::Config { buildTest: false };
181 186
    let mut res = resolver::resolver(storage, config);
182 187
    let diag = try resolver::resolveModuleRoot(&mut res, root) catch {
183 -
        io::printLn("error: Resolver failed");
188 +
        io::printLn("error: resolver failed");
184 189
        return false;
185 190
    };
186 191
    if not resolver::success(&diag) {
187 -
        io::printLn("error: Resolver failed");
192 +
        io::printLn("error: resolver failed");
188 193
        return false;
189 194
    }
195 +
190 196
    // Lower to IL.
191 -
    let mut ilArena = alloc::new(&mut ilArenaStorage[..]);
197 +
    let mut ilArena = alloc::new(&mut IL_ARENA_STORAGE[..]);
192 198
    let program = try lower::lower(&res, root, "test", &mut ilArena) catch err {
193 -
        io::print("error: Lowering failed: ");
199 +
        io::print("error: lowering failed: ");
194 200
        lower::printError(err);
195 201
        io::printLn("");
196 202
        return false;
197 203
    };
204 +
198 205
    // Print IL to buffer.
199 -
    let mut printArena = alloc::new(&mut printArenaStorage[..]);
200 -
    let actual = printer::printProgramToBuffer(&program, &mut printArena, &mut outputBuf[..]);
206 +
    let mut printArena = alloc::new(&mut PRINT_ARENA_STORAGE[..]);
207 +
    let actual = printer::printProgramToBuffer(&program, &mut printArena, &mut OUTPUT_BUF[..]);
201 208
202 209
    // Compare ignoring comments.
203 210
    if not stringsEqual(actual, expected) {
204 211
        io::printLn("FAILED");
205 -
        printDiff(sourcePath, expected, actual);
212 +
        printDiff(expected, actual);
206 213
        return false;
207 214
    }
208 215
    io::printLn("ok");
209 216
210 217
    return true;
213 220
/// Run a single test specified as an argument.
214 221
@default fn main(env: *sys::Env) -> i32 {
215 222
    let args = env.args;
216 223
217 224
    if args.len != 2 {
218 -
        io::printError("error: expected test name and file path");
225 +
        io::printError("error: expected test file path as argument");
219 226
        return 1;
220 227
    }
221 228
    let sourcePath = args[1];
222 229
    io::print("test ");
223 230
    io::print(sourcePath);
lib/std/arch/rv64/tests/abi.sizes.rad → test/tests/abi.sizes.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test size-based ABI: small aggregates (<= 8 bytes) are passed/returned
2 3
//! by value in registers, while larger aggregates use hidden pointers.
3 4
4 5
record Byte {
5 6
    x: u8,
lib/std/lang/lower/tests/addfn.rad → test/tests/addfn.rad renamed +0 -0
lib/std/lang/lower/tests/addfn.ril → test/tests/addfn.ril renamed +0 -0
lib/std/arch/rv64/tests/aggregate.return.rad → test/tests/aggregate.return.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test that returning aggregate types via hidden return buffer does not
2 3
//! corrupt the caller's stack. Modifying a returned aggregate must not affect
3 4
//! other locals or previously returned values.
4 5
5 6
record Pair {
lib/std/arch/rv64/tests/arith.assignment.rad → test/tests/arith.assignment.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut a: i32 = 6;
3 4
    let mut b: i32 = 3;
4 5
    let mut c: i32 = 0;
5 6
    let mut d: i32 = 0;
lib/std/arch/rv64/tests/arith.basic.rad → test/tests/arith.basic.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // This expression will require multiple registers
3 4
    // to evaluate the nested operations.
4 5
    return (1 + (2 + (3 + (4 + (5 + 6))))) - 21;
5 6
}
lib/std/arch/rv64/tests/arith.modulo.rad → test/tests/arith.modulo.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let a: i32 = 17;
3 4
    let b: i32 = 5;
4 5
5 6
    return (a % b) - 2;
lib/std/arch/rv64/tests/arith.subword.rad → test/tests/arith.subword.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test sub-word arithmetic normalization.
2 3
//! Verifies that W8/W16 arithmetic results are properly sign/zero-extended,
3 4
//! and that W32 operations use the correct *w instruction variants.
4 5
5 6
fn testI8Overflow() -> bool {
test/tests/arith.subword.ril added +247 -0
1 +
fn w8 $testI8Overflow() {
2 +
  @entry0
3 +
    add w8 %0 120 10;
4 +
    sext w8 %1 %0;
5 +
    br.ne w8 %1 -126 @then1 @merge2;
6 +
  @then1
7 +
    ret 0;
8 +
  @merge2
9 +
    ret 1;
10 +
}
11 +
12 +
fn w8 $testU8Overflow() {
13 +
  @entry0
14 +
    add w8 %0 250 10;
15 +
    zext w8 %1 %0;
16 +
    br.ne w8 %1 4 @then1 @merge2;
17 +
  @then1
18 +
    ret 0;
19 +
  @merge2
20 +
    ret 1;
21 +
}
22 +
23 +
fn w8 $testI8Subtraction() {
24 +
  @entry0
25 +
    sub w8 %0 -100 50;
26 +
    sext w8 %1 %0;
27 +
    br.ne w8 %1 106 @then1 @merge2;
28 +
  @then1
29 +
    ret 0;
30 +
  @merge2
31 +
    ret 1;
32 +
}
33 +
34 +
fn w8 $testU8Subtraction() {
35 +
  @entry0
36 +
    sub w8 %0 5 10;
37 +
    zext w8 %1 %0;
38 +
    br.ne w8 %1 251 @then1 @merge2;
39 +
  @then1
40 +
    ret 0;
41 +
  @merge2
42 +
    ret 1;
43 +
}
44 +
45 +
fn w8 $testI16Overflow() {
46 +
  @entry0
47 +
    add w16 %0 32000 1000;
48 +
    sext w16 %1 %0;
49 +
    br.ne w16 %1 -32536 @then1 @merge2;
50 +
  @then1
51 +
    ret 0;
52 +
  @merge2
53 +
    ret 1;
54 +
}
55 +
56 +
fn w8 $testU16Overflow() {
57 +
  @entry0
58 +
    add w16 %0 65530 10;
59 +
    zext w16 %1 %0;
60 +
    br.ne w16 %1 4 @then1 @merge2;
61 +
  @then1
62 +
    ret 0;
63 +
  @merge2
64 +
    ret 1;
65 +
}
66 +
67 +
fn w8 $testI8Multiply() {
68 +
  @entry0
69 +
    mul w8 %0 15 10;
70 +
    sext w8 %1 %0;
71 +
    br.ne w8 %1 -106 @then1 @merge2;
72 +
  @then1
73 +
    ret 0;
74 +
  @merge2
75 +
    ret 1;
76 +
}
77 +
78 +
fn w8 $testU8Multiply() {
79 +
  @entry0
80 +
    mul w8 %0 20 15;
81 +
    zext w8 %1 %0;
82 +
    br.ne w8 %1 44 @then1 @merge2;
83 +
  @then1
84 +
    ret 0;
85 +
  @merge2
86 +
    ret 1;
87 +
}
88 +
89 +
fn w8 $testI8Comparison() {
90 +
  @entry0
91 +
    add w8 %0 127 1;
92 +
    sext w8 %1 %0;
93 +
    br.slt w8 %1 0 @merge2 @then1;
94 +
  @then1
95 +
    ret 0;
96 +
  @merge2
97 +
    br.ne w8 %1 -128 @then3 @merge4;
98 +
  @then3
99 +
    ret 0;
100 +
  @merge4
101 +
    ret 1;
102 +
}
103 +
104 +
fn w8 $testU8Comparison() {
105 +
  @entry0
106 +
    zext w8 %0 1;
107 +
    add w8 %1 255 %0;
108 +
    zext w8 %2 %1;
109 +
    br.ne w8 %2 0 @then1 @merge2;
110 +
  @then1
111 +
    ret 0;
112 +
  @merge2
113 +
    ret 1;
114 +
}
115 +
116 +
fn w8 $testNarrowingCast() {
117 +
  @entry0
118 +
    zext w8 %0 1000;
119 +
    br.ne w8 %0 232 @then1 @merge2;
120 +
  @then1
121 +
    ret 0;
122 +
  @merge2
123 +
    ret 1;
124 +
}
125 +
126 +
fn w8 $testW32ShiftRight() {
127 +
  @entry0
128 +
    ushr w32 %0 4294967295 16;
129 +
    br.ne w32 %0 65535 @then1 @merge2;
130 +
  @then1
131 +
    ret 0;
132 +
  @merge2
133 +
    ret 1;
134 +
}
135 +
136 +
fn w8 $testI8NegOverflow() {
137 +
  @entry0
138 +
    neg w8 %0 -128;
139 +
    sext w8 %1 %0;
140 +
    br.ne w8 %1 -128 @then1 @merge2;
141 +
  @then1
142 +
    ret 0;
143 +
  @merge2
144 +
    ret 1;
145 +
}
146 +
147 +
fn w8 $testU8BitNot() {
148 +
  @entry0
149 +
    not w8 %0 0;
150 +
    zext w8 %1 %0;
151 +
    br.ne w8 %1 255 @then1 @merge2;
152 +
  @then1
153 +
    ret 0;
154 +
  @merge2
155 +
    ret 1;
156 +
}
157 +
158 +
fn w8 $testW32ShiftLargeImmediate() {
159 +
  @entry0
160 +
    shl w32 %0 1 40;
161 +
    br.ne w32 %0 256 @then1 @merge2;
162 +
  @then1
163 +
    ret 0;
164 +
  @merge2
165 +
    ret 1;
166 +
}
167 +
168 +
fn w32 $main() {
169 +
  @entry0
170 +
    call w8 %0 $testI8Overflow();
171 +
    br.ne w32 %0 0 @assert.ok2 @assert.fail1;
172 +
  @assert.fail1
173 +
    unreachable;
174 +
  @assert.ok2
175 +
    call w8 %1 $testU8Overflow();
176 +
    br.ne w32 %1 0 @assert.ok4 @assert.fail3;
177 +
  @assert.fail3
178 +
    unreachable;
179 +
  @assert.ok4
180 +
    call w8 %2 $testI8Subtraction();
181 +
    br.ne w32 %2 0 @assert.ok6 @assert.fail5;
182 +
  @assert.fail5
183 +
    unreachable;
184 +
  @assert.ok6
185 +
    call w8 %3 $testU8Subtraction();
186 +
    br.ne w32 %3 0 @assert.ok8 @assert.fail7;
187 +
  @assert.fail7
188 +
    unreachable;
189 +
  @assert.ok8
190 +
    call w8 %4 $testI16Overflow();
191 +
    br.ne w32 %4 0 @assert.ok10 @assert.fail9;
192 +
  @assert.fail9
193 +
    unreachable;
194 +
  @assert.ok10
195 +
    call w8 %5 $testU16Overflow();
196 +
    br.ne w32 %5 0 @assert.ok12 @assert.fail11;
197 +
  @assert.fail11
198 +
    unreachable;
199 +
  @assert.ok12
200 +
    call w8 %6 $testI8Multiply();
201 +
    br.ne w32 %6 0 @assert.ok14 @assert.fail13;
202 +
  @assert.fail13
203 +
    unreachable;
204 +
  @assert.ok14
205 +
    call w8 %7 $testU8Multiply();
206 +
    br.ne w32 %7 0 @assert.ok16 @assert.fail15;
207 +
  @assert.fail15
208 +
    unreachable;
209 +
  @assert.ok16
210 +
    call w8 %8 $testI8Comparison();
211 +
    br.ne w32 %8 0 @assert.ok18 @assert.fail17;
212 +
  @assert.fail17
213 +
    unreachable;
214 +
  @assert.ok18
215 +
    call w8 %9 $testU8Comparison();
216 +
    br.ne w32 %9 0 @assert.ok20 @assert.fail19;
217 +
  @assert.fail19
218 +
    unreachable;
219 +
  @assert.ok20
220 +
    call w8 %10 $testNarrowingCast();
221 +
    br.ne w32 %10 0 @assert.ok22 @assert.fail21;
222 +
  @assert.fail21
223 +
    unreachable;
224 +
  @assert.ok22
225 +
    call w8 %11 $testW32ShiftRight();
226 +
    br.ne w32 %11 0 @assert.ok24 @assert.fail23;
227 +
  @assert.fail23
228 +
    unreachable;
229 +
  @assert.ok24
230 +
    call w8 %12 $testI8NegOverflow();
231 +
    br.ne w32 %12 0 @assert.ok26 @assert.fail25;
232 +
  @assert.fail25
233 +
    unreachable;
234 +
  @assert.ok26
235 +
    call w8 %13 $testU8BitNot();
236 +
    br.ne w32 %13 0 @assert.ok28 @assert.fail27;
237 +
  @assert.fail27
238 +
    unreachable;
239 +
  @assert.ok28
240 +
    call w8 %14 $testW32ShiftLargeImmediate();
241 +
    br.ne w32 %14 0 @assert.ok30 @assert.fail29;
242 +
  @assert.fail29
243 +
    unreachable;
244 +
  @assert.ok30
245 +
    ret 0;
246 +
}
247 +
lib/std/arch/rv64/tests/arith.sum.rad → test/tests/arith.sum.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // This expression will require multiple registers
3 4
    // to evaluate the nested operations.
4 5
    return -21 + (1 + (2 + (3 + (4 + (5 + 6)))));
5 6
}
lib/std/arch/rv64/tests/arith.w64.rad → test/tests/arith.w64.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test 64-bit integer arithmetic.
2 3
//! Verifies that i64/u64 operations use full-width instructions
3 4
//! and that widening/narrowing casts work correctly.
4 5
5 6
fn testI64Add() -> bool {
test/tests/arith.w64.ril added +298 -0
1 +
fn w8 $testI64Add() {
2 +
  @entry0
3 +
    add w64 %0 100 200;
4 +
    br.ne w64 %0 300 @then1 @merge2;
5 +
  @then1
6 +
    ret 0;
7 +
  @merge2
8 +
    ret 1;
9 +
}
10 +
11 +
fn w8 $testU64Add() {
12 +
  @entry0
13 +
    add w64 %0 100 200;
14 +
    br.ne w64 %0 300 @then1 @merge2;
15 +
  @then1
16 +
    ret 0;
17 +
  @merge2
18 +
    ret 1;
19 +
}
20 +
21 +
fn w8 $testI64Sub() {
22 +
  @entry0
23 +
    sub w64 %0 500 300;
24 +
    br.ne w64 %0 200 @then1 @merge2;
25 +
  @then1
26 +
    ret 0;
27 +
  @merge2
28 +
    ret 1;
29 +
}
30 +
31 +
fn w8 $testI64Mul() {
32 +
  @entry0
33 +
    mul w64 %0 1000 2000;
34 +
    br.ne w64 %0 2000000 @then1 @merge2;
35 +
  @then1
36 +
    ret 0;
37 +
  @merge2
38 +
    ret 1;
39 +
}
40 +
41 +
fn w8 $testI64Div() {
42 +
  @entry0
43 +
    sdiv w64 %0 1000 10;
44 +
    br.ne w64 %0 100 @then1 @merge2;
45 +
  @then1
46 +
    ret 0;
47 +
  @merge2
48 +
    ret 1;
49 +
}
50 +
51 +
fn w8 $testU64Div() {
52 +
  @entry0
53 +
    udiv w64 %0 1000 10;
54 +
    br.ne w64 %0 100 @then1 @merge2;
55 +
  @then1
56 +
    ret 0;
57 +
  @merge2
58 +
    ret 1;
59 +
}
60 +
61 +
fn w8 $testI64Neg() {
62 +
  @entry0
63 +
    neg w64 %0 42;
64 +
    br.ne w64 %0 -42 @then1 @merge2;
65 +
  @then1
66 +
    ret 0;
67 +
  @merge2
68 +
    ret 1;
69 +
}
70 +
71 +
fn w8 $testI64Shift() {
72 +
  @entry0
73 +
    shl w64 %0 1 40;
74 +
    br.ne w64 %0 1099511627776 @then1 @merge2;
75 +
  @then1
76 +
    ret 0;
77 +
  @merge2
78 +
    sshr w64 %1 %0 40;
79 +
    br.ne w64 %1 1 @then3 @merge4;
80 +
  @then3
81 +
    ret 0;
82 +
  @merge4
83 +
    ret 1;
84 +
}
85 +
86 +
fn w8 $testU64Shift() {
87 +
  @entry0
88 +
    shl w64 %0 1 32;
89 +
    ushr w64 %1 %0 32;
90 +
    br.ne w64 %1 1 @then1 @merge2;
91 +
  @then1
92 +
    ret 0;
93 +
  @merge2
94 +
    ret 1;
95 +
}
96 +
97 +
fn w8 $testI64Bitwise() {
98 +
  @entry0
99 +
    and w64 %0 65280 4080;
100 +
    br.ne w64 %0 3840 @then1 @merge2;
101 +
  @then1
102 +
    ret 0;
103 +
  @merge2
104 +
    or w64 %1 65280 4080;
105 +
    br.ne w64 %1 65520 @then3 @merge4;
106 +
  @then3
107 +
    ret 0;
108 +
  @merge4
109 +
    xor w64 %2 65280 4080;
110 +
    br.ne w64 %2 61680 @then5 @merge6;
111 +
  @then5
112 +
    ret 0;
113 +
  @merge6
114 +
    ret 1;
115 +
}
116 +
117 +
fn w8 $testWidenI32ToI64() {
118 +
  @entry0
119 +
    sext w32 %0 -42;
120 +
    br.ne w64 %0 -42 @then1 @merge2;
121 +
  @then1
122 +
    ret 0;
123 +
  @merge2
124 +
    ret 1;
125 +
}
126 +
127 +
fn w8 $testWidenU32ToU64() {
128 +
  @entry0
129 +
    zext w32 %0 4294967295;
130 +
    ushr w64 %1 %0 32;
131 +
    br.ne w64 %1 0 @then1 @merge2;
132 +
  @then1
133 +
    ret 0;
134 +
  @merge2
135 +
    ret 1;
136 +
}
137 +
138 +
fn w8 $testNarrowI64ToI32() {
139 +
  @entry0
140 +
    sext w32 %0 42;
141 +
    br.ne w32 %0 42 @then1 @merge2;
142 +
  @then1
143 +
    ret 0;
144 +
  @merge2
145 +
    ret 1;
146 +
}
147 +
148 +
fn w8 $testNarrowU64ToU32() {
149 +
  @entry0
150 +
    zext w32 %0 42;
151 +
    br.ne w32 %0 42 @then1 @merge2;
152 +
  @then1
153 +
    ret 0;
154 +
  @merge2
155 +
    ret 1;
156 +
}
157 +
158 +
fn w8 $testI64Compare() {
159 +
  @entry0
160 +
    br.slt w64 -1 1 @merge2 @then1;
161 +
  @then1
162 +
    ret 0;
163 +
  @merge2
164 +
    br.slt w64 -1 1 @merge4 @then3;
165 +
  @then3
166 +
    ret 0;
167 +
  @merge4
168 +
    ret 1;
169 +
}
170 +
171 +
fn w8 $testU64Compare() {
172 +
  @entry0
173 +
    br.ult w64 100 200 @merge2 @then1;
174 +
  @then1
175 +
    ret 0;
176 +
  @merge2
177 +
    br.ult w64 100 200 @merge4 @then3;
178 +
  @then3
179 +
    ret 0;
180 +
  @merge4
181 +
    ret 1;
182 +
}
183 +
184 +
fn w8 $testI64Modulo() {
185 +
  @entry0
186 +
    srem w64 %0 17 5;
187 +
    br.ne w64 %0 2 @then1 @merge2;
188 +
  @then1
189 +
    ret 0;
190 +
  @merge2
191 +
    ret 1;
192 +
}
193 +
194 +
fn w8 $testU64Modulo() {
195 +
  @entry0
196 +
    urem w64 %0 17 5;
197 +
    br.ne w64 %0 2 @then1 @merge2;
198 +
  @then1
199 +
    ret 0;
200 +
  @merge2
201 +
    ret 1;
202 +
}
203 +
204 +
fn w32 $main() {
205 +
  @entry0
206 +
    call w8 %0 $testI64Add();
207 +
    br.ne w32 %0 0 @assert.ok2 @assert.fail1;
208 +
  @assert.fail1
209 +
    unreachable;
210 +
  @assert.ok2
211 +
    call w8 %1 $testU64Add();
212 +
    br.ne w32 %1 0 @assert.ok4 @assert.fail3;
213 +
  @assert.fail3
214 +
    unreachable;
215 +
  @assert.ok4
216 +
    call w8 %2 $testI64Sub();
217 +
    br.ne w32 %2 0 @assert.ok6 @assert.fail5;
218 +
  @assert.fail5
219 +
    unreachable;
220 +
  @assert.ok6
221 +
    call w8 %3 $testI64Mul();
222 +
    br.ne w32 %3 0 @assert.ok8 @assert.fail7;
223 +
  @assert.fail7
224 +
    unreachable;
225 +
  @assert.ok8
226 +
    call w8 %4 $testI64Div();
227 +
    br.ne w32 %4 0 @assert.ok10 @assert.fail9;
228 +
  @assert.fail9
229 +
    unreachable;
230 +
  @assert.ok10
231 +
    call w8 %5 $testU64Div();
232 +
    br.ne w32 %5 0 @assert.ok12 @assert.fail11;
233 +
  @assert.fail11
234 +
    unreachable;
235 +
  @assert.ok12
236 +
    call w8 %6 $testI64Neg();
237 +
    br.ne w32 %6 0 @assert.ok14 @assert.fail13;
238 +
  @assert.fail13
239 +
    unreachable;
240 +
  @assert.ok14
241 +
    call w8 %7 $testI64Shift();
242 +
    br.ne w32 %7 0 @assert.ok16 @assert.fail15;
243 +
  @assert.fail15
244 +
    unreachable;
245 +
  @assert.ok16
246 +
    call w8 %8 $testU64Shift();
247 +
    br.ne w32 %8 0 @assert.ok18 @assert.fail17;
248 +
  @assert.fail17
249 +
    unreachable;
250 +
  @assert.ok18
251 +
    call w8 %9 $testI64Bitwise();
252 +
    br.ne w32 %9 0 @assert.ok20 @assert.fail19;
253 +
  @assert.fail19
254 +
    unreachable;
255 +
  @assert.ok20
256 +
    call w8 %10 $testWidenI32ToI64();
257 +
    br.ne w32 %10 0 @assert.ok22 @assert.fail21;
258 +
  @assert.fail21
259 +
    unreachable;
260 +
  @assert.ok22
261 +
    call w8 %11 $testWidenU32ToU64();
262 +
    br.ne w32 %11 0 @assert.ok24 @assert.fail23;
263 +
  @assert.fail23
264 +
    unreachable;
265 +
  @assert.ok24
266 +
    call w8 %12 $testNarrowI64ToI32();
267 +
    br.ne w32 %12 0 @assert.ok26 @assert.fail25;
268 +
  @assert.fail25
269 +
    unreachable;
270 +
  @assert.ok26
271 +
    call w8 %13 $testNarrowU64ToU32();
272 +
    br.ne w32 %13 0 @assert.ok28 @assert.fail27;
273 +
  @assert.fail27
274 +
    unreachable;
275 +
  @assert.ok28
276 +
    call w8 %14 $testI64Compare();
277 +
    br.ne w32 %14 0 @assert.ok30 @assert.fail29;
278 +
  @assert.fail29
279 +
    unreachable;
280 +
  @assert.ok30
281 +
    call w8 %15 $testU64Compare();
282 +
    br.ne w32 %15 0 @assert.ok32 @assert.fail31;
283 +
  @assert.fail31
284 +
    unreachable;
285 +
  @assert.ok32
286 +
    call w8 %16 $testI64Modulo();
287 +
    br.ne w32 %16 0 @assert.ok34 @assert.fail33;
288 +
  @assert.fail33
289 +
    unreachable;
290 +
  @assert.ok34
291 +
    call w8 %17 $testU64Modulo();
292 +
    br.ne w32 %17 0 @assert.ok36 @assert.fail35;
293 +
  @assert.fail35
294 +
    unreachable;
295 +
  @assert.ok36
296 +
    ret 0;
297 +
}
298 +
lib/std/lang/lower/tests/array.aggregate.stride.rad → test/tests/array.aggregate.stride.rad renamed +0 -0
lib/std/lang/lower/tests/array.aggregate.stride.ril → test/tests/array.aggregate.stride.ril renamed +0 -0
lib/std/arch/rv64/tests/array.assign.rad → test/tests/array.assign.rad renamed +0 -0
test/tests/array.assign.ril added +27 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    reserve %0 20 4;
4 +
    store w32 1 %0 0;
5 +
    store w32 2 %0 4;
6 +
    store w32 3 %0 8;
7 +
    store w32 4 %0 12;
8 +
    store w32 5 %0 16;
9 +
    reserve %1 20 4;
10 +
    store w32 8 %1 0;
11 +
    store w32 9 %1 4;
12 +
    store w32 7 %1 8;
13 +
    store w32 6 %1 12;
14 +
    store w32 0 %1 16;
15 +
    blit %1 %0 20;
16 +
    sload w32 %2 %1 0;
17 +
    mul w64 %3 3 4;
18 +
    add w64 %4 %1 %3;
19 +
    sload w32 %5 %4 0;
20 +
    add w32 %6 %2 %5;
21 +
    mul w64 %7 2 4;
22 +
    add w64 %8 %1 %7;
23 +
    sload w32 %9 %8 0;
24 +
    sub w32 %10 %6 %9;
25 +
    ret %10;
26 +
}
27 +
lib/std/arch/rv64/tests/array.bounds.check.rad → test/tests/array.bounds.check.rad renamed +0 -0
lib/std/arch/rv64/tests/array.index.assign.rad → test/tests/array.index.assign.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test array index assignment and reading.
2 3
3 4
@default fn main() -> i32 {
4 5
    let mut arr: [i32; 5] = [1, 2, 3, 4, 5];
5 6
lib/std/arch/rv64/tests/array.index.rad → test/tests/array.index.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Basic array test: literals and indexing.
2 3
3 4
@default fn main() -> i32 {
4 5
    let mut arr: [i32; 4] = [10, 20, 30, 40];
5 6
    let mut sum: i32 = 0;
test/tests/array.index.ril added +25 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    reserve %0 16 4;
4 +
    store w32 10 %0 0;
5 +
    store w32 20 %0 4;
6 +
    store w32 30 %0 8;
7 +
    store w32 40 %0 12;
8 +
    sload w32 %1 %0 0;
9 +
    add w32 %2 0 %1;
10 +
    mul w64 %3 1 4;
11 +
    add w64 %4 %0 %3;
12 +
    sload w32 %5 %4 0;
13 +
    add w32 %6 %2 %5;
14 +
    mul w64 %7 2 4;
15 +
    add w64 %8 %0 %7;
16 +
    sload w32 %9 %8 0;
17 +
    add w32 %10 %6 %9;
18 +
    mul w64 %11 3 4;
19 +
    add w64 %12 %0 %11;
20 +
    sload w32 %13 %12 0;
21 +
    add w32 %14 %10 %13;
22 +
    sub w32 %15 %14 100;
23 +
    ret %15;
24 +
}
25 +
lib/std/lang/lower/tests/array.len.const.rad → test/tests/array.len.const.rad renamed +0 -0
lib/std/lang/lower/tests/array.len.const.ril → test/tests/array.len.const.ril renamed +0 -0
lib/std/arch/rv64/tests/array.length.rad → test/tests/array.length.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Test the `len` field on arrays.
2 3
3 4
@default fn main() -> i32 {
4 5
    let mut ary: [i32; 7] = [1, 2, 3, 4, 5, 6, 7];
5 6
    let mut sum: i32 = 0;
lib/std/lang/lower/tests/array.literal.rad → test/tests/array.literal.rad renamed +0 -0
lib/std/lang/lower/tests/array.literal.ril → test/tests/array.literal.ril renamed +0 -0
lib/std/arch/rv64/tests/array.math.rad → test/tests/array.math.rad renamed +0 -0
lib/std/arch/rv64/tests/array.nested.assign.rad → test/tests/array.nested.assign.rad renamed +0 -0
lib/std/arch/rv64/tests/array.nested.rad → test/tests/array.nested.rad renamed +0 -0
test/tests/array.nested.ril added +44 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    reserve %0 24 4;
4 +
    reserve %1 12 4;
5 +
    store w32 1 %1 0;
6 +
    store w32 2 %1 4;
7 +
    store w32 3 %1 8;
8 +
    blit %0 %1 12;
9 +
    reserve %2 12 4;
10 +
    store w32 4 %2 0;
11 +
    store w32 5 %2 4;
12 +
    store w32 6 %2 8;
13 +
    add w64 %3 %0 12;
14 +
    blit %3 %2 12;
15 +
    reserve %4 24 4;
16 +
    blit %4 %0 24;
17 +
    sload w32 %5 %0 0;
18 +
    mul w64 %6 1 4;
19 +
    add w64 %7 %4 %6;
20 +
    sload w32 %8 %7 0;
21 +
    add w32 %9 %5 %8;
22 +
    mul w64 %10 2 4;
23 +
    add w64 %11 %0 %10;
24 +
    sload w32 %12 %11 0;
25 +
    add w32 %13 %9 %12;
26 +
    mul w64 %14 1 12;
27 +
    add w64 %15 %4 %14;
28 +
    sload w32 %16 %15 0;
29 +
    add w32 %17 %13 %16;
30 +
    mul w64 %18 1 12;
31 +
    add w64 %19 %0 %18;
32 +
    mul w64 %20 1 4;
33 +
    add w64 %21 %19 %20;
34 +
    sload w32 %22 %21 0;
35 +
    add w32 %23 %17 %22;
36 +
    mul w64 %24 1 12;
37 +
    add w64 %25 %4 %24;
38 +
    mul w64 %26 2 4;
39 +
    add w64 %27 %25 %26;
40 +
    sload w32 %28 %27 0;
41 +
    add w32 %29 %23 %28;
42 +
    ret %29;
43 +
}
44 +
lib/std/arch/rv64/tests/array.record.elements.rad → test/tests/array.record.elements.rad renamed +0 -0
lib/std/arch/rv64/tests/array.repeat.edge.rad → test/tests/array.repeat.edge.rad renamed +0 -0
lib/std/arch/rv64/tests/array.repeat.rad → test/tests/array.repeat.rad renamed +0 -0
test/tests/array.repeat.ril added +153 -0
1 +
fn w8 $testBasic() {
2 +
  @entry0
3 +
    reserve %0 12 4;
4 +
    store w32 42 %0 0;
5 +
    store w32 42 %0 4;
6 +
    store w32 42 %0 8;
7 +
    sload w32 %3 %0 0;
8 +
    br.eq w32 %3 42 @and#then4 @and#else5;
9 +
  @and#then1
10 +
    mul w64 %9 2 4;
11 +
    add w64 %10 %0 %9;
12 +
    sload w32 %11 %10 0;
13 +
    eq w32 %12 %11 42;
14 +
    jmp @and#end3(%12);
15 +
  @and#else2
16 +
    jmp @and#end3(0);
17 +
  @and#end3(w8 %1)
18 +
    ret %1;
19 +
  @and#then4
20 +
    mul w64 %4 1 4;
21 +
    add w64 %5 %0 %4;
22 +
    sload w32 %6 %5 0;
23 +
    eq w32 %7 %6 42;
24 +
    jmp @and#end6(%7);
25 +
  @and#else5
26 +
    jmp @and#end6(0);
27 +
  @and#end6(w8 %2)
28 +
    br.ne w32 %2 0 @and#then1 @and#else2;
29 +
}
30 +
31 +
fn w8 $testZero() {
32 +
  @entry0
33 +
    reserve %0 20 4;
34 +
    store w32 0 %0 0;
35 +
    store w32 0 %0 4;
36 +
    store w32 0 %0 8;
37 +
    store w32 0 %0 12;
38 +
    store w32 0 %0 16;
39 +
    sload w32 %5 %0 0;
40 +
    br.eq w32 %5 0 @and#then10 @and#else11;
41 +
  @and#then1
42 +
    mul w64 %21 4 4;
43 +
    add w64 %22 %0 %21;
44 +
    sload w32 %23 %22 0;
45 +
    eq w32 %24 %23 0;
46 +
    jmp @and#end3(%24);
47 +
  @and#else2
48 +
    jmp @and#end3(0);
49 +
  @and#end3(w8 %1)
50 +
    ret %1;
51 +
  @and#then4
52 +
    mul w64 %16 3 4;
53 +
    add w64 %17 %0 %16;
54 +
    sload w32 %18 %17 0;
55 +
    eq w32 %19 %18 0;
56 +
    jmp @and#end6(%19);
57 +
  @and#else5
58 +
    jmp @and#end6(0);
59 +
  @and#end6(w8 %2)
60 +
    br.ne w32 %2 0 @and#then1 @and#else2;
61 +
  @and#then7
62 +
    mul w64 %11 2 4;
63 +
    add w64 %12 %0 %11;
64 +
    sload w32 %13 %12 0;
65 +
    eq w32 %14 %13 0;
66 +
    jmp @and#end9(%14);
67 +
  @and#else8
68 +
    jmp @and#end9(0);
69 +
  @and#end9(w8 %3)
70 +
    br.ne w32 %3 0 @and#then4 @and#else5;
71 +
  @and#then10
72 +
    mul w64 %6 1 4;
73 +
    add w64 %7 %0 %6;
74 +
    sload w32 %8 %7 0;
75 +
    eq w32 %9 %8 0;
76 +
    jmp @and#end12(%9);
77 +
  @and#else11
78 +
    jmp @and#end12(0);
79 +
  @and#end12(w8 %4)
80 +
    br.ne w32 %4 0 @and#then7 @and#else8;
81 +
}
82 +
83 +
fn w8 $testBoolean() {
84 +
  @entry0
85 +
    reserve %0 4 1;
86 +
    store w8 1 %0 0;
87 +
    store w8 1 %0 1;
88 +
    store w8 1 %0 2;
89 +
    store w8 1 %0 3;
90 +
    load w8 %4 %0 0;
91 +
    br.ne w32 %4 0 @and#then7 @and#else8;
92 +
  @and#then1
93 +
    add w64 %11 %0 3;
94 +
    load w8 %12 %11 0;
95 +
    jmp @and#end3(%12);
96 +
  @and#else2
97 +
    jmp @and#end3(0);
98 +
  @and#end3(w8 %1)
99 +
    ret %1;
100 +
  @and#then4
101 +
    add w64 %8 %0 2;
102 +
    load w8 %9 %8 0;
103 +
    jmp @and#end6(%9);
104 +
  @and#else5
105 +
    jmp @and#end6(0);
106 +
  @and#end6(w8 %2)
107 +
    br.ne w32 %2 0 @and#then1 @and#else2;
108 +
  @and#then7
109 +
    add w64 %5 %0 1;
110 +
    load w8 %6 %5 0;
111 +
    jmp @and#end9(%6);
112 +
  @and#else8
113 +
    jmp @and#end9(0);
114 +
  @and#end9(w8 %3)
115 +
    br.ne w32 %3 0 @and#then4 @and#else5;
116 +
}
117 +
118 +
fn w8 $testSingle() {
119 +
  @entry0
120 +
    reserve %0 4 4;
121 +
    store w32 99 %0 0;
122 +
    sload w32 %1 %0 0;
123 +
    eq w32 %2 %1 99;
124 +
    ret %2;
125 +
}
126 +
127 +
fn w8 $main() {
128 +
  @entry0
129 +
    call w8 %3 $testBasic();
130 +
    br.ne w32 %3 0 @and#then7 @and#else8;
131 +
  @and#then1
132 +
    call w8 %6 $testSingle();
133 +
    jmp @and#end3(%6);
134 +
  @and#else2
135 +
    jmp @and#end3(0);
136 +
  @and#end3(w8 %0)
137 +
    ret %0;
138 +
  @and#then4
139 +
    call w8 %5 $testBoolean();
140 +
    jmp @and#end6(%5);
141 +
  @and#else5
142 +
    jmp @and#end6(0);
143 +
  @and#end6(w8 %1)
144 +
    br.ne w32 %1 0 @and#then1 @and#else2;
145 +
  @and#then7
146 +
    call w8 %4 $testZero();
147 +
    jmp @and#end9(%4);
148 +
  @and#else8
149 +
    jmp @and#end9(0);
150 +
  @and#end9(w8 %2)
151 +
    br.ne w32 %2 0 @and#then4 @and#else5;
152 +
}
153 +
lib/std/arch/rv64/tests/array.return.rad → test/tests/array.return.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Test calling functions that return array values.
2 3
3 4
fn compute(ary: [i32; 4]) -> [i32; 4] {
4 5
    return [
5 6
        ary[0] * 1,
lib/std/arch/rv64/tests/array.slice.empty.rad → test/tests/array.slice.empty.rad renamed +1 -0
1 +
//! returns: 0
1 2
fn length(slice: *[u8]) -> u32 {
2 3
  return slice.len;
3 4
}
4 5
5 6
@default fn main() -> u32 {
lib/std/lang/lower/tests/array.slice.full.rad → test/tests/array.slice.full.rad renamed +0 -0
lib/std/lang/lower/tests/array.slice.full.ril → test/tests/array.slice.full.ril renamed +0 -0
lib/std/arch/rv64/tests/array.slice.gen.end.rad → test/tests/array.slice.gen.end.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut arr: [i32; 4] = [1, 2, 3, 4];
3 4
    let mut slice: *[i32] = &arr[..2];
4 5
5 6
    return 0;
lib/std/arch/rv64/tests/array.slice.gen.index.rad → test/tests/array.slice.gen.index.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut arr: [i32; 4] = [1, 2, 3, 4];
3 4
    let mut slice: *[i32] = &arr[1..];
4 5
5 6
    return (slice[1]) - 3;
lib/std/arch/rv64/tests/array.slice.gen.open.rad → test/tests/array.slice.gen.open.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut arr: [i32; 4] = [1, 2, 3, 4];
3 4
    let mut slice: *[i32] = &arr[..];
4 5
5 6
    return 0;
lib/std/arch/rv64/tests/array.slice.gen.start.end.rad → test/tests/array.slice.gen.start.end.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut arr: [i32; 4] = [1, 2, 3, 4];
3 4
    let mut slice: *[i32] = &arr[1..3];
4 5
5 6
    return 0;
lib/std/arch/rv64/tests/array.slice.gen.start.rad → test/tests/array.slice.gen.start.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut arr: [i32; 4] = [1, 2, 3, 4];
3 4
    let mut slice: *[i32] = &arr[2..];
4 5
5 6
    return 0;
lib/std/lang/lower/tests/array.slice.openend.rad → test/tests/array.slice.openend.rad renamed +0 -0
lib/std/lang/lower/tests/array.slice.openend.ril → test/tests/array.slice.openend.ril renamed +0 -0
lib/std/lang/lower/tests/array.slice.openstart.rad → test/tests/array.slice.openstart.rad renamed +0 -0
lib/std/lang/lower/tests/array.slice.openstart.ril → test/tests/array.slice.openstart.ril renamed +0 -0
lib/std/arch/rv64/tests/array.slice.rad → test/tests/array.slice.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test array slicing with various ranges.
2 3
3 4
@default fn main() -> i32 {
4 5
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
5 6
lib/std/arch/rv64/tests/as.precedence.rad → test/tests/as.precedence.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
3 4
@default fn main() -> i32 {
4 5
    let p1: u8 = 1;
5 6
    let p2: u8 = 2;
lib/std/arch/rv64/tests/assert.basic.rad → test/tests/assert.basic.rad renamed +1 -0
1 +
//! returns: 0
1 2
/// Test assert keyword.
2 3
@default fn main() -> i32 {
3 4
    // Assert with true condition should pass.
4 5
    assert true;
5 6
test/tests/assert.basic.ril added +30 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    copy %0 1;
4 +
    br.ne w32 %0 0 @assert.ok2 @assert.fail1;
5 +
  @assert.fail1
6 +
    unreachable;
7 +
  @assert.ok2
8 +
    br.eq w32 42 42 @assert.ok4 @assert.fail3;
9 +
  @assert.fail3
10 +
    unreachable;
11 +
  @assert.ok4
12 +
    br.slt w32 0 42 @assert.ok6 @assert.fail5;
13 +
  @assert.fail5
14 +
    unreachable;
15 +
  @assert.ok6
16 +
    br.ne w32 42 0 @assert.ok8 @assert.fail7;
17 +
  @assert.fail7
18 +
    unreachable;
19 +
  @assert.ok8
20 +
    br.eq w32 42 42 @assert.ok10 @assert.fail9;
21 +
  @assert.fail9
22 +
    unreachable;
23 +
  @assert.ok10
24 +
    br.slt w32 0 42 @assert.ok12 @assert.fail11;
25 +
  @assert.fail11
26 +
    unreachable;
27 +
  @assert.ok12
28 +
    ret 0;
29 +
}
30 +
lib/std/arch/rv64/tests/assert.fail.rad → test/tests/assert.fail.rad renamed +0 -0
lib/std/arch/rv64/tests/assert.false.rad → test/tests/assert.false.rad renamed +0 -0
lib/std/lang/lower/tests/assert.message.rad → test/tests/assert.message.rad renamed +0 -0
lib/std/lang/lower/tests/assert.message.ril → test/tests/assert.message.ril renamed +0 -0
lib/std/arch/rv64/tests/assert.true.rad → test/tests/assert.true.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    assert true;
4 5
    assert 1 == 1;
5 6
    assert 5 > 3;
lib/std/lang/lower/tests/assign.loop.rad → test/tests/assign.loop.rad renamed +0 -0
lib/std/lang/lower/tests/assign.loop.ril → test/tests/assign.loop.ril renamed +0 -0
lib/std/lang/lower/tests/assign.multi.var.rad → test/tests/assign.multi.var.rad renamed +0 -0
lib/std/lang/lower/tests/assign.multi.var.ril → test/tests/assign.multi.var.ril renamed +0 -0
lib/std/arch/rv64/tests/assign.mutable.rad → test/tests/assign.mutable.rad renamed +0 -0
lib/std/lang/lower/tests/assign.param.rad → test/tests/assign.param.rad renamed +0 -0
lib/std/lang/lower/tests/assign.param.ril → test/tests/assign.param.ril renamed +0 -0
lib/std/arch/rv64/tests/assign.rad → test/tests/assign.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 36;
3 4
    i += 1; // 37
4 5
    i += 2; // 39
5 6
    i += 3; // 42
lib/std/lang/lower/tests/assign.self.ref.rad → test/tests/assign.self.ref.rad renamed +0 -0
lib/std/lang/lower/tests/assign.self.ref.ril → test/tests/assign.self.ref.ril renamed +0 -0
lib/std/lang/lower/tests/assign.sequential.rad → test/tests/assign.sequential.rad renamed +0 -0
lib/std/lang/lower/tests/assign.sequential.ril → test/tests/assign.sequential.ril renamed +0 -0
lib/std/arch/rv64/tests/assign.shadow.mutable.rad → test/tests/assign.shadow.mutable.rad renamed +0 -0
lib/std/lang/lower/tests/assign.use.intermediate.rad → test/tests/assign.use.intermediate.rad renamed +0 -0
lib/std/lang/lower/tests/assign.use.intermediate.ril → test/tests/assign.use.intermediate.ril renamed +0 -0
lib/std/lang/lower/tests/average.rad → test/tests/average.rad renamed +0 -0
lib/std/lang/lower/tests/average.ril → test/tests/average.ril renamed +0 -0
lib/std/lang/lower/tests/binop.arith.rad → test/tests/binop.arith.rad renamed +0 -0
lib/std/lang/lower/tests/binop.arith.ril → test/tests/binop.arith.ril renamed +0 -0
lib/std/arch/rv64/tests/binop.bitwise.rad → test/tests/binop.bitwise.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // Test `&` (bitwise AND).
3 4
    // `12 = 0b1100`, `10 = 0b1010`, result = `0b1000 = 8`.
4 5
    let a: i32 = 12 & 10;
5 6
    assert a == 8;
test/tests/binop.bitwise.ril added +56 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    and w32 %0 12 10;
4 +
    br.eq w32 %0 8 @assert.ok2 @assert.fail1;
5 +
  @assert.fail1
6 +
    unreachable;
7 +
  @assert.ok2
8 +
    or w32 %1 12 10;
9 +
    br.eq w32 %1 14 @assert.ok4 @assert.fail3;
10 +
  @assert.fail3
11 +
    unreachable;
12 +
  @assert.ok4
13 +
    xor w32 %2 12 10;
14 +
    br.eq w32 %2 6 @assert.ok6 @assert.fail5;
15 +
  @assert.fail5
16 +
    unreachable;
17 +
  @assert.ok6
18 +
    shl w32 %3 3 4;
19 +
    br.eq w32 %3 48 @assert.ok8 @assert.fail7;
20 +
  @assert.fail7
21 +
    unreachable;
22 +
  @assert.ok8
23 +
    sshr w32 %4 48 2;
24 +
    br.eq w32 %4 12 @assert.ok10 @assert.fail9;
25 +
  @assert.fail9
26 +
    unreachable;
27 +
  @assert.ok10
28 +
    sshr w32 %5 -16 2;
29 +
    br.eq w32 %5 -4 @assert.ok12 @assert.fail11;
30 +
  @assert.fail11
31 +
    unreachable;
32 +
  @assert.ok12
33 +
    not w32 %6 0;
34 +
    br.eq w32 %6 -1 @assert.ok14 @assert.fail13;
35 +
  @assert.fail13
36 +
    unreachable;
37 +
  @assert.ok14
38 +
    not w32 %7 1;
39 +
    br.eq w32 %7 -2 @assert.ok16 @assert.fail15;
40 +
  @assert.fail15
41 +
    unreachable;
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;
46 +
  @assert.fail17
47 +
    unreachable;
48 +
  @assert.ok18
49 +
    xor w32 %10 42 42;
50 +
    br.eq w32 %10 0 @assert.ok20 @assert.fail19;
51 +
  @assert.fail19
52 +
    unreachable;
53 +
  @assert.ok20
54 +
    ret 0;
55 +
}
56 +
lib/std/arch/rv64/tests/binop.cmp.rad → test/tests/binop.cmp.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let a: i32 = 5;
3 4
    let b: i32 = 5;
4 5
    let c: i32 = 6;
5 6
lib/std/lang/lower/tests/binop.logical.rad → test/tests/binop.logical.rad renamed +0 -0
lib/std/lang/lower/tests/binop.logical.ril → test/tests/binop.logical.ril renamed +0 -0
lib/std/lang/lower/tests/binop.shift.rad → test/tests/binop.shift.rad renamed +0 -0
lib/std/lang/lower/tests/binop.shift.ril → test/tests/binop.shift.ril renamed +0 -0
lib/std/lang/lower/tests/binop.unsigned.rad → test/tests/binop.unsigned.rad renamed +0 -0
lib/std/lang/lower/tests/binop.unsigned.ril → test/tests/binop.unsigned.ril renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.array.rad → test/tests/bool.comparison.array.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.nested.gen.rad → test/tests/bool.comparison.nested.gen.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test nested record equality.
2 3
3 4
record Point {
4 5
    x: i32,
5 6
    y: i32,
lib/std/arch/rv64/tests/bool.comparison.opt.rad → test/tests/bool.comparison.opt.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.record.gen.rad → test/tests/bool.comparison.record.gen.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
record Point {
3 4
    x: i32,
4 5
    y: i32,
5 6
}
lib/std/arch/rv64/tests/bool.comparison.record.rad → test/tests/bool.comparison.record.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.slice.gen.rad → test/tests/bool.comparison.slice.gen.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.slice.rad → test/tests/bool.comparison.slice.rad renamed +1 -0
1 +
//! returns: 0
1 2
fn memEq(a: *[u8], b: *[u8]) -> bool {
2 3
    if a.len != b.len {
3 4
        return false;
4 5
    }
5 6
    for i in 0..a.len {
lib/std/arch/rv64/tests/bool.comparison.slice.record.gen.rad → test/tests/bool.comparison.slice.record.gen.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.slice.union.gen.rad → test/tests/bool.comparison.slice.union.gen.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.union.ctor.rad → test/tests/bool.comparison.union.ctor.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test comparing a void union variable against a constructor literal.
2 3
3 4
union Op {
4 5
    Add,
5 6
    Sub,
lib/std/arch/rv64/tests/bool.comparison.union.gen.rad → test/tests/bool.comparison.union.gen.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
union Status {
3 4
    pending,
4 5
    running(u32),
5 6
    completed(bool),
lib/std/arch/rv64/tests/bool.comparison.union.record.gen.rad → test/tests/bool.comparison.union.record.gen.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.comparison.union.simple.gen.rad → test/tests/bool.comparison.union.simple.gen.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test equality on simple enum without payloads.
2 3
union Color {
3 4
    red,
4 5
    green,
5 6
    blue,
lib/std/arch/rv64/tests/bool.operators.complex.rad → test/tests/bool.operators.complex.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.operators.rad → test/tests/bool.operators.rad renamed +0 -0
lib/std/arch/rv64/tests/bool.short.circuit.rad → test/tests/bool.short.circuit.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test short-circuiting behavior of 'and' and 'or' operators.
2 3
fn modify(counter: *mut i32, ret: bool) -> bool {
3 4
    *counter += 1;
4 5
    return ret;
5 6
}
lib/std/arch/rv64/tests/bool.simple.rad → test/tests/bool.simple.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut a: bool = true;
4 5
    let mut b: bool = false;
5 6
lib/std/arch/rv64/tests/bool.values.rad → test/tests/bool.values.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Tests for boolean values assigned from `and`/`or` expressions.
2 3
3 4
@default fn main() -> i32 {
4 5
    let t: bool = true;
5 6
    let f: bool = false;
lib/std/lang/lower/tests/builtin.alignof.rad → test/tests/builtin.alignof.rad renamed +0 -0
lib/std/lang/lower/tests/builtin.alignof.ril → test/tests/builtin.alignof.ril renamed +0 -0
lib/std/arch/rv64/tests/builtin.size.align.rad → test/tests/builtin.size.align.rad renamed +1 -0
1 +
//! returns: 0
1 2
record Foo {
2 3
    x: u8,
3 4
    y: u32,
4 5
}
5 6
lib/std/lang/lower/tests/builtin.sizeof.rad → test/tests/builtin.sizeof.rad renamed +0 -0
lib/std/lang/lower/tests/builtin.sizeof.ril → test/tests/builtin.sizeof.ril renamed +0 -0
lib/std/arch/rv64/tests/builtin.sliceof.mut.rad → test/tests/builtin.sliceof.mut.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Test the @sliceOf builtin with mutable slice.
2 3
3 4
@default fn main() -> i32 {
4 5
    let mut arr: [i32; 4] = [10, 20, 30, 40];
5 6
lib/std/arch/rv64/tests/builtin.sliceof.rad → test/tests/builtin.sliceof.rad renamed +0 -0
lib/std/lang/lower/tests/byte.load.store.rad → test/tests/byte.load.store.rad renamed +0 -0
lib/std/lang/lower/tests/byte.load.store.ril → test/tests/byte.load.store.ril renamed +0 -0
lib/std/arch/rv64/tests/call.arg.clobber.rad → test/tests/call.arg.clobber.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test: call argument setup must not clobber source registers.
2 3
//!
3 4
//! With 6+ simultaneously live values, the register allocator assigns
4 5
//! some to argument registers (A0-A7). The call instruction setup must
5 6
//! use parallel move resolution to avoid overwriting sources.
lib/std/arch/rv64/tests/call.basic.rad → test/tests/call.basic.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Helper function defined first.
2 3
fn add(a: i32, b: i32) -> i32 {
3 4
    return a + b;
4 5
}
5 6
lib/std/arch/rv64/tests/call.clobber.rad → test/tests/call.clobber.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test that values live across function calls are not clobbered.
2 3
fn modify(counter: *mut i32, ret: bool) -> bool {
3 4
    *counter += 1;
4 5
    return ret;
5 6
}
lib/std/lang/lower/tests/call.tests.rad → test/tests/call.tests.rad renamed +0 -0
lib/std/lang/lower/tests/call.tests.ril → test/tests/call.tests.ril renamed +0 -0
lib/std/lang/lower/tests/cast.basic.rad → test/tests/cast.basic.rad renamed +0 -0
lib/std/lang/lower/tests/cast.basic.ril → test/tests/cast.basic.ril renamed +0 -0
lib/std/lang/lower/tests/cast.narrow.rad → test/tests/cast.narrow.rad renamed +0 -0
lib/std/lang/lower/tests/cast.narrow.ril → test/tests/cast.narrow.ril renamed +0 -0
lib/std/arch/rv64/tests/cast.same.size.rad → test/tests/cast.same.size.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // Test i8 -> u8 cast: -1 should become 255.
3 4
    let x: i8 = -1;
4 5
    let a: u8 = x as u8;
5 6
    assert a == 255;
test/tests/cast.same.size.ril added +51 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    br.eq w8 -1 255 @assert.ok2 @assert.fail1;
4 +
  @assert.fail1
5 +
    unreachable;
6 +
  @assert.ok2
7 +
    br.eq w8 255 -1 @assert.ok4 @assert.fail3;
8 +
  @assert.fail3
9 +
    unreachable;
10 +
  @assert.ok4
11 +
    br.eq w8 -128 128 @assert.ok6 @assert.fail5;
12 +
  @assert.fail5
13 +
    unreachable;
14 +
  @assert.ok6
15 +
    br.eq w8 128 -128 @assert.ok8 @assert.fail7;
16 +
  @assert.fail7
17 +
    unreachable;
18 +
  @assert.ok8
19 +
    br.eq w16 -1 65535 @assert.ok10 @assert.fail9;
20 +
  @assert.fail9
21 +
    unreachable;
22 +
  @assert.ok10
23 +
    br.eq w16 65535 -1 @assert.ok12 @assert.fail11;
24 +
  @assert.fail11
25 +
    unreachable;
26 +
  @assert.ok12
27 +
    eq w8 %0 -1 255;
28 +
    br.ne w32 %0 0 @assert.ok14 @assert.fail13;
29 +
  @assert.fail13
30 +
    unreachable;
31 +
  @assert.ok14
32 +
    eq w8 %1 255 -1;
33 +
    br.ne w32 %1 0 @assert.ok16 @assert.fail15;
34 +
  @assert.fail15
35 +
    unreachable;
36 +
  @assert.ok16
37 +
    ne w8 %2 -1 255;
38 +
    eq w8 %3 %2 0;
39 +
    br.ne w32 %3 0 @assert.ok18 @assert.fail17;
40 +
  @assert.fail17
41 +
    unreachable;
42 +
  @assert.ok18
43 +
    ne w8 %4 255 -1;
44 +
    eq w8 %5 %4 0;
45 +
    br.ne w32 %5 0 @assert.ok20 @assert.fail19;
46 +
  @assert.fail19
47 +
    unreachable;
48 +
  @assert.ok20
49 +
    ret 0;
50 +
}
51 +
lib/std/arch/rv64/tests/casting.numbers.rad → test/tests/casting.numbers.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test integer casting: zero-extension, sign-extension, truncation.
2 3
3 4
fn zeroExtension() -> bool {
4 5
    let x: u8 = 9;
5 6
    let mut y: i32 = 42424242;
lib/std/arch/rv64/tests/char.literal.rad → test/tests/char.literal.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test character literals including escaped chars.
2 3
@default fn main() -> i32 {
3 4
    assert 'a' == 97;
4 5
    assert '\'' == 39;
5 6
    assert '\\' == 92;
lib/std/lang/lower/tests/cmp.rel.rad → test/tests/cmp.rel.rad renamed +0 -0
lib/std/lang/lower/tests/cmp.rel.ril → test/tests/cmp.rel.ril renamed +0 -0
lib/std/lang/lower/tests/cmp.unsigned.rad → test/tests/cmp.unsigned.rad renamed +0 -0
lib/std/lang/lower/tests/cmp.unsigned.ril → test/tests/cmp.unsigned.ril renamed +0 -0
lib/std/lang/lower/tests/coercion.implicit.rad → test/tests/coercion.implicit.rad renamed +0 -0
lib/std/lang/lower/tests/coercion.implicit.ril → test/tests/coercion.implicit.ril renamed +0 -0
lib/std/arch/rv64/tests/compound.assign.field.rad → test/tests/compound.assign.field.rad renamed +1 -0
1 +
//! returns: 0
1 2
/// Test compound assignment on record fields.
2 3
record Point {
3 4
    x: i32,
4 5
    y: i32,
5 6
}
lib/std/arch/rv64/tests/compound.assign.rad → test/tests/compound.assign.rad renamed +1 -0
1 +
//! returns: 0
1 2
/// Test compound assignment operators (+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=).
2 3
@default fn main() -> i32 {
3 4
    let mut a: i32 = 10;
4 5
5 6
    // Test +=
test/tests/compound.assign.ril added +90 -0
1 +
fn w32 $main() {
2 +
  @entry0
3 +
    add w32 %0 10 5;
4 +
    br.eq w32 %0 15 @assert.ok2 @assert.fail1;
5 +
  @assert.fail1
6 +
    unreachable;
7 +
  @assert.ok2
8 +
    sub w32 %1 %0 3;
9 +
    br.eq w32 %1 12 @assert.ok4 @assert.fail3;
10 +
  @assert.fail3
11 +
    unreachable;
12 +
  @assert.ok4
13 +
    mul w32 %2 %1 2;
14 +
    br.eq w32 %2 24 @assert.ok6 @assert.fail5;
15 +
  @assert.fail5
16 +
    unreachable;
17 +
  @assert.ok6
18 +
    sdiv w32 %3 %2 4;
19 +
    br.eq w32 %3 6 @assert.ok8 @assert.fail7;
20 +
  @assert.fail7
21 +
    unreachable;
22 +
  @assert.ok8
23 +
    srem w32 %4 %3 4;
24 +
    br.eq w32 %4 2 @assert.ok10 @assert.fail9;
25 +
  @assert.fail9
26 +
    unreachable;
27 +
  @assert.ok10
28 +
    and w32 %5 255 15;
29 +
    br.eq w32 %5 15 @assert.ok12 @assert.fail11;
30 +
  @assert.fail11
31 +
    unreachable;
32 +
  @assert.ok12
33 +
    or w32 %6 %5 240;
34 +
    br.eq w32 %6 255 @assert.ok14 @assert.fail13;
35 +
  @assert.fail13
36 +
    unreachable;
37 +
  @assert.ok14
38 +
    xor w32 %7 %6 15;
39 +
    br.eq w32 %7 240 @assert.ok16 @assert.fail15;
40 +
  @assert.fail15
41 +
    unreachable;
42 +
  @assert.ok16
43 +
    shl w32 %8 1 4;
44 +
    br.eq w32 %8 16 @assert.ok18 @assert.fail17;
45 +
  @assert.fail17
46 +
    unreachable;
47 +
  @assert.ok18
48 +
    sshr w32 %9 %8 2;
49 +
    br.eq w32 %9 4 @assert.ok20 @assert.fail19;
50 +
  @assert.fail19
51 +
    unreachable;
52 +
  @assert.ok20
53 +
    reserve %10 12 4;
54 +
    store w32 10 %10 0;
55 +
    store w32 20 %10 4;
56 +
    store w32 30 %10 8;
57 +
    mul w64 %11 1 4;
58 +
    add w64 %12 %10 %11;
59 +
    sload w32 %13 %12 0;
60 +
    add w32 %14 %13 5;
61 +
    mul w64 %15 1 4;
62 +
    add w64 %16 %10 %15;
63 +
    store w32 %14 %16 0;
64 +
    mul w64 %17 1 4;
65 +
    add w64 %18 %10 %17;
66 +
    sload w32 %19 %18 0;
67 +
    br.eq w32 %19 25 @assert.ok22 @assert.fail21;
68 +
  @assert.fail21
69 +
    unreachable;
70 +
  @assert.ok22
71 +
    reserve %20 4 4;
72 +
    store w32 100 %20 0;
73 +
    sload w32 %21 %20 0;
74 +
    add w32 %22 %21 50;
75 +
    store w32 %22 %20 0;
76 +
    sload w32 %23 %20 0;
77 +
    br.eq w32 %23 150 @assert.ok24 @assert.fail23;
78 +
  @assert.fail23
79 +
    unreachable;
80 +
  @assert.ok24
81 +
    add w32 %24 1 2;
82 +
    mul w32 %25 %24 3;
83 +
    sub w32 %26 %25 1;
84 +
    br.eq w32 %26 8 @assert.ok26 @assert.fail25;
85 +
  @assert.fail25
86 +
    unreachable;
87 +
  @assert.ok26
88 +
    ret 0;
89 +
}
90 +
lib/std/lang/lower/tests/cond.assign.merge.basic.rad → test/tests/cond.assign.merge.basic.rad renamed +0 -0
lib/std/lang/lower/tests/cond.assign.merge.basic.ril → test/tests/cond.assign.merge.basic.ril renamed +0 -0
lib/std/lang/lower/tests/cond.assign.merge.rad → test/tests/cond.assign.merge.rad renamed +0 -0
lib/std/lang/lower/tests/cond.assign.merge.ril → test/tests/cond.assign.merge.ril renamed +0 -0
lib/std/arch/rv64/tests/cond.assign.rad → test/tests/cond.assign.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Tests for block parameters (phi nodes).
2 3
// Block parameters are generated when different branches assign
3 4
// different values to a variable that's used after the merge point.
4 5
5 6
@default fn main() -> i32 {
lib/std/lang/lower/tests/cond.elseif.rad → test/tests/cond.elseif.rad renamed +0 -0
lib/std/lang/lower/tests/cond.elseif.ril → test/tests/cond.elseif.ril renamed +0 -0
lib/std/arch/rv64/tests/cond.expr.aggregate.rad → test/tests/cond.expr.aggregate.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test conditional expression with aggregate types (tagged unions, optionals).
2 3
3 4
union Val {
4 5
    Reg(u32),
5 6
    Imm(i64),
lib/std/arch/rv64/tests/cond.expr.rad → test/tests/cond.expr.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Test conditional expression lowering (`thenExpr if cond else elseExpr`).
2 3
3 4
fn min(a: u32, b: u32) -> u32 {
4 5
    return b if b < a else a;
5 6
}
test/tests/cond.expr.ril added +181 -0
1 +
fn w32 $min(w32 %0, w32 %1) {
2 +
  @entry0
3 +
    br.ult w32 %1 %0 @cond#then1 @cond#else2;
4 +
  @cond#then1
5 +
    jmp @cond#merge3(%1);
6 +
  @cond#else2
7 +
    jmp @cond#merge3(%0);
8 +
  @cond#merge3(w32 %2)
9 +
    ret %2;
10 +
}
11 +
12 +
fn w32 $pick(w8 %0, w32 %1, w32 %2) {
13 +
  @entry0
14 +
    br.ne w32 %0 0 @cond#then1 @cond#else2;
15 +
  @cond#then1
16 +
    jmp @cond#merge3(%1);
17 +
  @cond#else2
18 +
    jmp @cond#merge3(%2);
19 +
  @cond#merge3(w32 %3)
20 +
    ret %3;
21 +
}
22 +
23 +
fn w8 $colorPick(w8 %0) {
24 +
  @entry0
25 +
    br.ne w32 %0 0 @cond#then1 @cond#else2;
26 +
  @cond#then1
27 +
    jmp @cond#merge3(0);
28 +
  @cond#else2
29 +
    jmp @cond#merge3(2);
30 +
  @cond#merge3(w8 %1)
31 +
    ret %1;
32 +
}
33 +
34 +
fn w32 $testScalar() {
35 +
  @entry0
36 +
    copy %0 1;
37 +
    br.ne w32 %0 0 @cond#then1 @cond#else2;
38 +
  @cond#then1
39 +
    jmp @cond#merge3(10);
40 +
  @cond#else2
41 +
    jmp @cond#merge3(20);
42 +
  @cond#merge3(w32 %1)
43 +
    br.eq w32 %1 10 @assert.ok5 @assert.fail4;
44 +
  @assert.fail4
45 +
    unreachable;
46 +
  @assert.ok5
47 +
    copy %2 0;
48 +
    br.ne w32 %2 0 @cond#then6 @cond#else7;
49 +
  @cond#then6
50 +
    jmp @cond#merge8(10);
51 +
  @cond#else7
52 +
    jmp @cond#merge8(20);
53 +
  @cond#merge8(w32 %3)
54 +
    br.eq w32 %3 20 @assert.ok10 @assert.fail9;
55 +
  @assert.fail9
56 +
    unreachable;
57 +
  @assert.ok10
58 +
    ret 0;
59 +
}
60 +
61 +
fn w32 $testMin() {
62 +
  @entry0
63 +
    call w32 %0 $min(5, 3);
64 +
    br.eq w32 %0 3 @assert.ok2 @assert.fail1;
65 +
  @assert.fail1
66 +
    unreachable;
67 +
  @assert.ok2
68 +
    call w32 %1 $min(3, 5);
69 +
    br.eq w32 %1 3 @assert.ok4 @assert.fail3;
70 +
  @assert.fail3
71 +
    unreachable;
72 +
  @assert.ok4
73 +
    call w32 %2 $min(4, 4);
74 +
    br.eq w32 %2 4 @assert.ok6 @assert.fail5;
75 +
  @assert.fail5
76 +
    unreachable;
77 +
  @assert.ok6
78 +
    ret 0;
79 +
}
80 +
81 +
fn w32 $testFnArg() {
82 +
  @entry0
83 +
    call w32 %0 $pick(1, 42, 99);
84 +
    br.eq w32 %0 42 @assert.ok2 @assert.fail1;
85 +
  @assert.fail1
86 +
    unreachable;
87 +
  @assert.ok2
88 +
    call w32 %1 $pick(0, 42, 99);
89 +
    br.eq w32 %1 99 @assert.ok4 @assert.fail3;
90 +
  @assert.fail3
91 +
    unreachable;
92 +
  @assert.ok4
93 +
    ret 0;
94 +
}
95 +
96 +
fn w32 $testEnum() {
97 +
  @entry0
98 +
    call w8 %0 $colorPick(1);
99 +
    br.eq w8 %0 0 @assert.ok2 @assert.fail1;
100 +
  @assert.fail1
101 +
    unreachable;
102 +
  @assert.ok2
103 +
    call w8 %1 $colorPick(0);
104 +
    br.eq w8 %1 2 @assert.ok4 @assert.fail3;
105 +
  @assert.fail3
106 +
    unreachable;
107 +
  @assert.ok4
108 +
    ret 0;
109 +
}
110 +
111 +
fn w32 $testNested() {
112 +
  @entry0
113 +
    copy %0 0;
114 +
    br.ne w32 %0 0 @cond#then1 @cond#else2;
115 +
  @cond#then1
116 +
    jmp @cond#merge3(0);
117 +
  @cond#else2
118 +
    copy %2 0;
119 +
    br.ne w32 %2 0 @cond#then4 @cond#else5;
120 +
  @cond#merge3(w32 %1)
121 +
    br.eq w32 %1 2 @assert.ok8 @assert.fail7;
122 +
  @cond#then4
123 +
    jmp @cond#merge6(1);
124 +
  @cond#else5
125 +
    jmp @cond#merge6(2);
126 +
  @cond#merge6(w32 %3)
127 +
    jmp @cond#merge3(%3);
128 +
  @assert.fail7
129 +
    unreachable;
130 +
  @assert.ok8
131 +
    copy %4 1;
132 +
    br.ne w32 %4 0 @cond#then9 @cond#else10;
133 +
  @cond#then9
134 +
    jmp @cond#merge11(0);
135 +
  @cond#else10
136 +
    copy %8 0;
137 +
    br.ne w32 %8 0 @cond#then12 @cond#else13;
138 +
  @cond#merge11(w32 %5)
139 +
    br.eq w32 %5 0 @assert.ok16 @assert.fail15;
140 +
  @cond#then12
141 +
    jmp @cond#merge14(1);
142 +
  @cond#else13
143 +
    jmp @cond#merge14(2);
144 +
  @cond#merge14(w32 %9)
145 +
    jmp @cond#merge11(%9);
146 +
  @assert.fail15
147 +
    unreachable;
148 +
  @assert.ok16
149 +
    ret 0;
150 +
}
151 +
152 +
fn w32 $main() {
153 +
  @entry0
154 +
    call w32 %0 $testScalar();
155 +
    br.ne w32 %0 0 @then1 @merge2;
156 +
  @then1
157 +
    ret %0;
158 +
  @merge2
159 +
    call w32 %1 $testMin();
160 +
    br.ne w32 %1 0 @then3 @merge4;
161 +
  @then3
162 +
    ret %1;
163 +
  @merge4
164 +
    call w32 %2 $testFnArg();
165 +
    br.ne w32 %2 0 @then5 @merge6;
166 +
  @then5
167 +
    ret %2;
168 +
  @merge6
169 +
    call w32 %3 $testEnum();
170 +
    br.ne w32 %3 0 @then7 @merge8;
171 +
  @then7
172 +
    ret %3;
173 +
  @merge8
174 +
    call w32 %4 $testNested();
175 +
    br.ne w32 %4 0 @then9 @merge10;
176 +
  @then9
177 +
    ret %4;
178 +
  @merge10
179 +
    ret 0;
180 +
}
181 +
lib/std/arch/rv64/tests/cond.for.else.break.rad → test/tests/cond.for.else.break.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut i: i32 = 0;
4 5
    let xs: [i32; 7] = [1, 2, 3, 4, 5, 6, 7];
5 6
lib/std/arch/rv64/tests/cond.for.indexed.rad → test/tests/cond.for.indexed.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> u32 {
3 4
    let arr: [u32; 3] = [10, 20, 30];
4 5
    let mut sum: u32 = 0;
5 6
lib/std/arch/rv64/tests/cond.for.rad → test/tests/cond.for.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut i: i32 = 0;
4 5
    let xs: [i32; 7] = [1, 2, 3, 4, 5, 6, 7];
5 6
lib/std/arch/rv64/tests/cond.for.range.indexed.rad → test/tests/cond.for.range.indexed.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut sum: i32 = 0;
4 5
5 6
    // Test range iteration with index.
lib/std/arch/rv64/tests/cond.for.range.rad → test/tests/cond.for.range.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let xs: [i32; 4] = [3, 4, 5, 6];
4 5
    let mut sum: i32 = 0;
5 6
lib/std/arch/rv64/tests/cond.for.unsigned.range.rad → test/tests/cond.for.unsigned.range.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // Unsigned range crossing signed boundary should iterate once.
3 4
    let start: u32 = 2147483647;
4 5
    let end: u32 = 2147483648;
5 6
    let mut count: i32 = 0;
lib/std/arch/rv64/tests/cond.forever.break.continue.rad → test/tests/cond.forever.break.continue.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 0;
3 4
4 5
    loop {
5 6
        if (i < 42) {
lib/std/arch/rv64/tests/cond.forever.break.rad → test/tests/cond.forever.break.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 0;
3 4
4 5
    loop {
5 6
        loop {
lib/std/arch/rv64/tests/cond.fused.rad → test/tests/cond.fused.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Tests for short-circuit boolean operators (`and`/`or`).
2 3
// These generate block parameters for short-circuit evaluation.
3 4
4 5
@default fn main() -> i32 {
5 6
    let t: bool = true;
lib/std/arch/rv64/tests/cond.if.case.rad → test/tests/cond.if.case.rad renamed +0 -0
lib/std/arch/rv64/tests/cond.if.else.min.rad → test/tests/cond.if.else.min.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 0;
3 4
4 5
    if (i == 1) {
5 6
        return (1) - 42;
lib/std/arch/rv64/tests/cond.if.else.rad → test/tests/cond.if.else.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 41;
3 4
4 5
    if (i == 42) {
5 6
        return (1) - 42;
lib/std/arch/rv64/tests/cond.if.elseif.rad → test/tests/cond.if.elseif.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 40;
3 4
4 5
    if (i == 42) {
5 6
        return (1) - 42;
lib/std/arch/rv64/tests/cond.if.noelse.rad → test/tests/cond.if.noelse.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut x: i32 = 10;
4 5
5 6
    if (x == 11) {
lib/std/arch/rv64/tests/cond.if.rad → test/tests/cond.if.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    // Basic `if` with `true`.
3 4
    let t: bool = true;
4 5
    if t {
5 6
        // Ignore.
lib/std/lang/lower/tests/cond.ifelse.rad → test/tests/cond.ifelse.rad renamed +0 -0
lib/std/lang/lower/tests/cond.ifelse.ril → test/tests/cond.ifelse.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.case.rad → test/tests/cond.iflet.case.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.case.ril → test/tests/cond.iflet.case.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.guard.rad → test/tests/cond.iflet.guard.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.guard.ril → test/tests/cond.iflet.guard.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.mut.rad → test/tests/cond.iflet.mut.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.mut.ril → test/tests/cond.iflet.mut.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.noelse.rad → test/tests/cond.iflet.noelse.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.noelse.ril → test/tests/cond.iflet.noelse.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.optional.rad → test/tests/cond.iflet.optional.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.optional.ril → test/tests/cond.iflet.optional.ril renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.optional.value.rad → test/tests/cond.iflet.optional.value.rad renamed +0 -0
lib/std/lang/lower/tests/cond.iflet.optional.value.ril → test/tests/cond.iflet.optional.value.ril renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.case.rad → test/tests/cond.letelse.case.rad renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.case.ril → test/tests/cond.letelse.case.ril renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.guard.rad → test/tests/cond.letelse.guard.rad renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.guard.ril → test/tests/cond.letelse.guard.ril renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.mut.rad → test/tests/cond.letelse.mut.rad renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.mut.ril → test/tests/cond.letelse.mut.ril renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.optional.rad → test/tests/cond.letelse.optional.rad renamed +0 -0
lib/std/lang/lower/tests/cond.letelse.optional.ril → test/tests/cond.letelse.optional.ril renamed +0 -0
lib/std/arch/rv64/tests/cond.match.fallthrough.rad → test/tests/cond.match.fallthrough.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Test that jump patching works to skip cases that were not matched.
2 3
@default fn main() -> i32 {
3 4
    let mut x: i32 = 1;
4 5
5 6
    match (x) {
lib/std/arch/rv64/tests/cond.match.guard.rad → test/tests/cond.match.guard.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
union OptionNum {
3 4
    Some(i32),
4 5
    Other(i32),
5 6
    None,
lib/std/arch/rv64/tests/cond.match.guard.regalloc.rad → test/tests/cond.match.guard.regalloc.rad renamed +1 -0
1 +
//! returns: 0
1 2
//! Match guard register allocation.
2 3
//! Tests that a guarded match case with multiple union variants does not
3 4
//! clobber registers live across out-of-order blocks. The guard in
4 5
//! `case Kind::Name(name) if name.len > 0` creates a block ordering where
5 6
//! the case body has a lower index than its predecessor (the guard block).
lib/std/lang/lower/tests/cond.nested.rad → test/tests/cond.nested.rad renamed +0 -0
lib/std/lang/lower/tests/cond.nested.ril → test/tests/cond.nested.ril renamed +0 -0
lib/std/lang/lower/tests/cond.simple.rad → test/tests/cond.simple.rad renamed +0 -0
lib/std/lang/lower/tests/cond.simple.ril → test/tests/cond.simple.ril renamed +0 -0
lib/std/arch/rv64/tests/cond.while.else.break.rad → test/tests/cond.while.else.break.rad renamed +1 -0
1 +
//! returns: 0
1 2
2 3
@default fn main() -> i32 {
3 4
    let mut i: i32 = 0;
4 5
5 6
    while (i < 100) {
lib/std/arch/rv64/tests/cond.while.rad → test/tests/cond.while.rad renamed +1 -0
1 +
//! returns: 0
1 2
@default fn main() -> i32 {
2 3
    let mut i: i32 = 0;
3 4
4 5
    while (i < 42) {
5 6
        i += 1;
lib/std/arch/rv64/tests/const.array.copy.mutate.rad → test/tests/const.array.copy.mutate.rad renamed +0 -0
lib/std/lang/lower/tests/const.array.ident.rad → test/tests/const.array.ident.rad renamed +0 -0
lib/std/lang/lower/tests/const.array.ident.ril → test/tests/const.array.ident.ril renamed +0 -0
lib/std/arch/rv64/tests/const.array.rad → test/tests/const.array.rad renamed +1 -0
1 +
//! returns: 0
1 2
// Test array constants.
2 3
3 4
const NUMBERS: [i32; 4] = [1, 2, 3, 4];
4 5
5 6
@default fn main() -> i32 {
lib/std/lang/lower/tests/const.array.record.ident.rad → test/tests/const.array.record.ident.rad renamed +0 -0

499 more files not shown.