From a270c6f8c82bc81eecf37cc06a326e46ed44fb8b Mon Sep 17 00:00:00 2001 From: David Rubin Date: Sat, 25 May 2024 22:52:26 -0700 Subject: [PATCH] riscv: implement optional logic --- src/arch/riscv64/CodeGen.zig | 278 ++++++++++++++---- src/arch/riscv64/abi.zig | 1 + src/arch/riscv64/bits.zig | 2 +- test/behavior/align.zig | 1 - test/behavior/basic.zig | 2 - test/behavior/cast.zig | 15 - test/behavior/error.zig | 1 - test/behavior/eval.zig | 1 - test/behavior/fn.zig | 3 - test/behavior/generics.zig | 1 - test/behavior/if.zig | 1 - test/behavior/null.zig | 3 - test/behavior/optional.zig | 5 - test/behavior/pointers.zig | 2 - test/behavior/ptrfromint.zig | 1 - test/behavior/sizeof_and_typeof.zig | 1 - test/behavior/slice.zig | 1 - test/behavior/struct.zig | 3 - .../struct_contains_null_ptr_itself.zig | 1 - test/behavior/this.zig | 1 - test/behavior/type.zig | 1 - test/behavior/union.zig | 1 - test/behavior/void.zig | 1 - 23 files changed, 222 insertions(+), 105 deletions(-) diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index cca02cb1a0..8636654e63 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -1545,6 +1545,58 @@ fn splitType(func: *Func, ty: Type) ![2]Type { return func.fail("TODO implement splitType for {}", .{ty.fmt(zcu)}); } +/// Truncates the value in the register in place. +/// Clobbers any remaining bits. +fn truncateRegister(func: *Func, ty: Type, reg: Register) !void { + const mod = func.bin_file.comp.module.?; + const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ + .signedness = .unsigned, + .bits = @intCast(ty.bitSize(mod)), + }; + const shift = math.cast(u6, 64 - int_info.bits % 64) orelse return; + switch (int_info.signedness) { + .signed => { + _ = try func.addInst(.{ + .tag = .slli, + .ops = .rri, + .data = .{ + .i_type = .{ + .rd = reg, + .rs1 = reg, + .imm12 = Immediate.s(shift), + }, + }, + }); + _ = try func.addInst(.{ + .tag = .srai, + .ops = .rri, + .data = .{ + .i_type = .{ + .rd = reg, + .rs1 = reg, + .imm12 = Immediate.s(shift), + }, + }, + }); + }, + .unsigned => { + const mask = ~@as(u64, 0) >> shift; + const tmp_reg = try func.copyToTmpRegister(Type.usize, .{ .immediate = mask }); + _ = try func.addInst(.{ + .tag = .@"and", + .ops = .rrr, + .data = .{ + .r_type = .{ + .rd = reg, + .rs1 = reg, + .rs2 = tmp_reg, + }, + }, + }); + }, + } +} + fn symbolIndex(func: *Func) !u32 { const zcu = func.bin_file.comp.module.?; const decl_index = zcu.funcOwnerDeclIndex(func.func_index); @@ -2868,8 +2920,25 @@ fn airShr(func: *Func, inst: Air.Inst.Index) !void { } fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void { + const zcu = func.bin_file.comp.module.?; const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else return func.fail("TODO implement .optional_payload for {}", .{func.target.cpu.arch}); + const result: MCValue = result: { + const pl_ty = func.typeOfIndex(inst); + if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none; + + const opt_mcv = try func.resolveInst(ty_op.operand); + if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) { + switch (opt_mcv) { + .register => |pl_reg| try func.truncateRegister(pl_ty, pl_reg), + else => {}, + } + break :result opt_mcv; + } + + const pl_mcv = try func.allocRegOrMem(inst, true); + try func.genCopy(pl_ty, pl_mcv, opt_mcv); + break :result pl_mcv; + }; return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -3022,16 +3091,40 @@ fn airSaveErrReturnTraceIndex(func: *Func, inst: Air.Inst.Index) !void { } fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void { + const zcu = func.bin_file.comp.module.?; const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { - const zcu = func.bin_file.comp.module.?; - const optional_ty = func.typeOfIndex(inst); + const result: MCValue = result: { + const pl_ty = func.typeOf(ty_op.operand); + if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 1 }; - // Optional with a zero-bit payload type is just a boolean true - if (optional_ty.abiSize(zcu) == 1) - break :result MCValue{ .immediate = 1 }; + const opt_ty = func.typeOfIndex(inst); + const pl_mcv = try func.resolveInst(ty_op.operand); + const same_repr = opt_ty.optionalReprIsPayload(zcu); + if (same_repr and func.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv; - return func.fail("TODO implement wrap optional for {}", .{func.target.cpu.arch}); + const pl_lock: ?RegisterLock = switch (pl_mcv) { + .register => |reg| func.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (pl_lock) |lock| func.register_manager.unlockReg(lock); + + const opt_mcv = try func.allocRegOrMem(inst, true); + try func.genCopy(pl_ty, opt_mcv, pl_mcv); + + if (!same_repr) { + const pl_abi_size: i32 = @intCast(pl_ty.abiSize(zcu)); + switch (opt_mcv) { + .load_frame => |frame_addr| try func.genSetMem( + .{ .frame = frame_addr.index }, + frame_addr.off + pl_abi_size, + Type.u8, + .{ .immediate = 1 }, + ), + .register => return func.fail("TODO: airWrapOption opt_mcv register", .{}), + else => unreachable, + } + } + break :result opt_mcv; }; return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } @@ -4435,72 +4528,141 @@ fn condBr(func: *Func, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { }); } +fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue { + const zcu = func.bin_file.comp.module.?; + const pl_ty = opt_ty.optionalChild(zcu); + + const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(zcu)) + .{ .off = 0, .ty = if (pl_ty.isSlice(zcu)) pl_ty.slicePtrFieldType(zcu) else pl_ty } + else + .{ .off = @intCast(pl_ty.abiSize(zcu)), .ty = Type.bool }; + + const return_mcv = try func.allocRegOrMem(inst, true); + assert(return_mcv == .register); // should not be larger 8 bytes + const return_reg = return_mcv.register; + + switch (opt_mcv) { + .none, + .unreach, + .dead, + .undef, + .immediate, + .register_pair, + .register_offset, + .lea_frame, + .lea_symbol, + .reserved_frame, + .air_ref, + => return func.fail("TODO: hmm {}", .{opt_mcv}), + + .register => |opt_reg| { + if (some_info.off == 0) { + _ = try func.addInst(.{ + .tag = .pseudo, + .ops = .pseudo_compare, + .data = .{ + .compare = .{ + .op = .eq, + .rd = return_reg, + .rs1 = opt_reg, + .rs2 = try func.copyToTmpRegister( + some_info.ty, + .{ .immediate = 0 }, + ), + .size = .byte, + }, + }, + }); + return return_mcv; + } + assert(some_info.ty.ip_index == .bool_type); + const opt_abi_size: u32 = @intCast(opt_ty.abiSize(zcu)); + _ = opt_abi_size; + return func.fail("TODO: isNull some_info.off != 0 register", .{}); + }, + + .load_frame => { + const opt_reg = try func.copyToTmpRegister( + some_info.ty, + opt_mcv.address().offset(some_info.off).deref(), + ); + const opt_reg_lock = func.register_manager.lockRegAssumeUnused(opt_reg); + defer func.register_manager.unlockReg(opt_reg_lock); + + _ = try func.addInst(.{ + .tag = .pseudo, + .ops = .pseudo_compare, + .data = .{ + .compare = .{ + .op = .eq, + .rd = return_reg, + .rs1 = opt_reg, + .rs2 = try func.copyToTmpRegister( + some_info.ty, + .{ .immediate = 0 }, + ), + .size = .byte, + }, + }, + }); + return return_mcv; + }, + + else => return func.fail("TODO: isNull {}", .{opt_mcv}), + } +} + fn airIsNull(func: *Func, inst: Air.Inst.Index) !void { const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { - const operand = try func.resolveInst(un_op); - break :result try func.isNull(operand); - }; + const operand = try func.resolveInst(un_op); + const ty = func.typeOf(un_op); + const result = try func.isNull(inst, ty, operand); return func.finishAir(inst, result, .{ un_op, .none, .none }); } fn airIsNullPtr(func: *Func, inst: Air.Inst.Index) !void { const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { - const operand_ptr = try func.resolveInst(un_op); - const operand: MCValue = blk: { - if (func.reuseOperand(inst, un_op, 0, operand_ptr)) { - // The MCValue that holds the pointer can be re-used as the value. - break :blk operand_ptr; - } else { - break :blk try func.allocRegOrMem(inst, true); - } - }; - try func.load(operand, operand_ptr, func.typeOf(un_op)); - break :result try func.isNull(operand); - }; - return func.finishAir(inst, result, .{ un_op, .none, .none }); -} + const operand = try func.resolveInst(un_op); + _ = operand; // autofix + const ty = func.typeOf(un_op); + _ = ty; // autofix -fn isNull(func: *Func, operand: MCValue) !MCValue { - _ = operand; - // Here you can specialize this instruction if it makes sense to, otherwise the default - // will call isNonNull and invert the result. - return func.fail("TODO call isNonNull and invert the result", .{}); + if (true) return func.fail("TODO: airIsNullPtr", .{}); + + return func.finishAir(inst, .unreach, .{ un_op, .none, .none }); } fn airIsNonNull(func: *Func, inst: Air.Inst.Index) !void { const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { - const operand = try func.resolveInst(un_op); - break :result try func.isNonNull(operand); - }; - return func.finishAir(inst, result, .{ un_op, .none, .none }); -} + const operand = try func.resolveInst(un_op); + const ty = func.typeOf(un_op); + const result = try func.isNull(inst, ty, operand); + assert(result == .register); -fn isNonNull(func: *Func, operand: MCValue) !MCValue { - _ = operand; - // Here you can specialize this instruction if it makes sense to, otherwise the default - // will call isNull and invert the result. - return func.fail("TODO call isNull and invert the result", .{}); + _ = try func.addInst(.{ + .tag = .pseudo, + .ops = .pseudo_not, + .data = .{ + .rr = .{ + .rd = result.register, + .rs = result.register, + }, + }, + }); + + return func.finishAir(inst, result, .{ un_op, .none, .none }); } fn airIsNonNullPtr(func: *Func, inst: Air.Inst.Index) !void { const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; - const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: { - const operand_ptr = try func.resolveInst(un_op); - const operand: MCValue = blk: { - if (func.reuseOperand(inst, un_op, 0, operand_ptr)) { - // The MCValue that holds the pointer can be re-used as the value. - break :blk operand_ptr; - } else { - break :blk try func.allocRegOrMem(inst, true); - } - }; - try func.load(operand, operand_ptr, func.typeOf(un_op)); - break :result try func.isNonNull(operand); - }; - return func.finishAir(inst, result, .{ un_op, .none, .none }); + const operand = try func.resolveInst(un_op); + _ = operand; // autofix + const ty = func.typeOf(un_op); + _ = ty; // autofix + + if (true) return func.fail("TODO: airIsNonNullPtr", .{}); + + return func.finishAir(inst, .unreach, .{ un_op, .none, .none }); } fn airIsErr(func: *Func, inst: Air.Inst.Index) !void { @@ -5110,7 +5272,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void { dst_mcv, try func.resolveInst(src_ref), ), - else => unreachable, + else => return func.fail("genCopy register_pair src: {}", .{src_mcv}), }; defer if (src_info) |info| { diff --git a/src/arch/riscv64/abi.zig b/src/arch/riscv64/abi.zig index b8254b68a5..a5b54f0a1b 100644 --- a/src/arch/riscv64/abi.zig +++ b/src/arch/riscv64/abi.zig @@ -125,6 +125,7 @@ pub fn classifySystem(ty: Type, zcu: *Module) [8]SystemClass { return result; } result[0] = .integer; + if (ty.optionalChild(zcu).abiSize(zcu) == 0) return result; result[1] = .integer; return result; }, diff --git a/src/arch/riscv64/bits.zig b/src/arch/riscv64/bits.zig index 034fe49450..a18f445816 100644 --- a/src/arch/riscv64/bits.zig +++ b/src/arch/riscv64/bits.zig @@ -230,7 +230,7 @@ pub const Register = enum(u8) { return @as(u8, reg.id()); } - pub fn bitSize(reg: Register, zcu: Module) u32 { + pub fn bitSize(reg: Register, zcu: *const Module) u32 { const features = zcu.getTarget().cpu.features; return switch (@intFromEnum(reg)) { diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 674d375438..bbb786af78 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -603,7 +603,6 @@ test "comptime alloc alignment" { } test "@alignCast null" { - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index 7c0c6cc4ab..0262b59bde 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -483,7 +483,6 @@ fn testStructInFn() !void { test "fn call returning scalar optional in equality expression" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try expect(getNull() == null); } @@ -494,7 +493,6 @@ fn getNull() ?*i32 { test "global variable assignment with optional unwrapping with var initialized to undefined" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { var data: i32 = 1234; diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 2a141b3eda..53616a82ce 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -186,7 +186,6 @@ fn expectIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void { test "implicitly cast indirect pointer to maybe-indirect pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const Self = @This(); @@ -247,7 +246,6 @@ test "coerce undefined to optional" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try expect(MakeType(void).getNull() == null); try expect(MakeType(void).getNonNull() != null); @@ -1184,7 +1182,6 @@ test "implicit ptr to *anyopaque" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var a: u32 = 1; const ptr: *align(@alignOf(u32)) anyopaque = &a; @@ -1198,7 +1195,6 @@ test "implicit ptr to *anyopaque" { test "return null from fn () anyerror!?&T" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const a = returnNullFromOptionalTypeErrorRef(); const b = returnNullLitFromOptionalTypeErrorRef(); @@ -1289,7 +1285,6 @@ test "implicit cast from *T to ?*anyopaque" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var a: u8 = 1; incrementVoidPtrValue(&a); @@ -1361,7 +1356,6 @@ test "assignment to optional pointer result loc" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; _ = &foo; @@ -1437,7 +1431,6 @@ test "peer type resolution: unreachable, null, slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn doTheTest(num: usize, word: []const u8) !void { @@ -1478,7 +1471,6 @@ test "cast compatible optional types" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var a: ?[:0]const u8 = null; _ = &a; @@ -1591,7 +1583,6 @@ test "bitcast packed struct with u0" { test "optional pointer coerced to optional allowzero pointer" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var p: ?*u32 = undefined; var q: ?*allowzero u32 = undefined; @@ -1608,8 +1599,6 @@ test "optional slice coerced to allowzero many pointer" { } test "optional slice passed as parameter coerced to allowzero many pointer" { - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - const ns = struct { const Color = struct { r: u8, @@ -1832,7 +1821,6 @@ test "peer type resolution: error union and optional of same type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const E = error{Foo}; var a: E!*u8 = error.Foo; @@ -1878,7 +1866,6 @@ test "peer type resolution: three-way resolution combines error set and optional if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const E = error{Foo}; var a: E = error.Foo; @@ -2104,7 +2091,6 @@ test "peer type resolution: tuple pointer and optional slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // Miscompilation on Intel's OpenCL CPU runtime. if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky @@ -2389,7 +2375,6 @@ test "cast builtins can wrap result in error union and optional" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const MyEnum = enum(u32) { _ }; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 4e7fe949f1..2863c5db6c 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -124,7 +124,6 @@ test "debug info for optional error set" { test "implicit cast to optional to error union to return result loc" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn entry() !void { diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 7b01c8d25f..492b204842 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -1548,7 +1548,6 @@ test "non-optional and optional array elements concatenated" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const array = [1]u8{'A'} ++ [1]?u8{null}; var index: usize = 0; diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 1c7adc38e8..73ef9bdbfe 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -104,7 +104,6 @@ test "inline function call that calls optional function pointer, return pointer if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { field: u32, @@ -259,7 +258,6 @@ test "implicit cast fn call result to optional in field result" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn entry() !void { @@ -473,7 +471,6 @@ test "method call with optional and error union first param" { test "method call with optional pointer first param" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { x: i32 = 1234, diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index 6cbb2f0786..46c400750c 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -444,7 +444,6 @@ test "generic function passed as comptime argument" { test "return type of generic function is function pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn b(comptime T: type) ?*const fn () error{}!T { diff --git a/test/behavior/if.zig b/test/behavior/if.zig index 8cb923dd43..ef0862bb70 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -139,7 +139,6 @@ test "if-else expression with runtime condition result location is inferred opti if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const A = struct { b: u64, c: u64 }; var d: bool = true; diff --git a/test/behavior/null.zig b/test/behavior/null.zig index 323f47c896..ebc390c36a 100644 --- a/test/behavior/null.zig +++ b/test/behavior/null.zig @@ -85,7 +85,6 @@ fn testTestNullRuntime(x: ?i32) !void { test "optional void" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try optionalVoidImpl(); try comptime optionalVoidImpl(); @@ -109,7 +108,6 @@ const Empty = struct {}; test "optional struct{}" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; _ = try optionalEmptyStructImpl(); _ = try comptime optionalEmptyStructImpl(); @@ -135,7 +133,6 @@ test "null with default unwrap" { test "optional pointer to 0 bit type null value at runtime" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const EmptyStruct = struct {}; var x: ?*EmptyStruct = null; diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig index ad90d5fd0a..9282184c3e 100644 --- a/test/behavior/optional.zig +++ b/test/behavior/optional.zig @@ -29,7 +29,6 @@ pub const EmptyStruct = struct {}; test "optional pointer to size zero struct" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var e = EmptyStruct{}; const o: ?*EmptyStruct = &e; @@ -60,7 +59,6 @@ fn testNullPtrsEql() !void { test "optional with zero-bit type" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { @@ -241,7 +239,6 @@ test "compare optionals with modified payloads" { test "unwrap function call with optional pointer return value" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn entry() !void { @@ -373,7 +370,6 @@ test "0-bit child type coerced to optional return ptr result location" { test "0-bit child type coerced to optional" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -638,7 +634,6 @@ test "result location initialization of optional with OPV payload" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; const S = struct { diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index 891ae311dd..cbd3033e7d 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -174,7 +174,6 @@ test "implicit cast error unions with non-optional to optional pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -222,7 +221,6 @@ test "assign null directly to C pointer and test null equality" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var x: [*c]i32 = null; _ = &x; diff --git a/test/behavior/ptrfromint.zig b/test/behavior/ptrfromint.zig index 0ff54c9416..89706be891 100644 --- a/test/behavior/ptrfromint.zig +++ b/test/behavior/ptrfromint.zig @@ -34,7 +34,6 @@ test "@ptrFromInt creates null pointer" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const ptr = @as(?*u32, @ptrFromInt(0)); try expectEqual(@as(?*u32, null), ptr); diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index 11d74c43d9..5d78acb241 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -328,7 +328,6 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" { if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const T = struct { next: @TypeOf(null, @as(*const @This(), undefined)), diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 606f6db9a3..2375977a4e 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -246,7 +246,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { test "C pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; var len: u32 = 10; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 44911378db..e27adafa79 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1873,8 +1873,6 @@ test "initializer takes a pointer to a variable inside its struct" { } test "circular dependency through pointer field of a struct" { - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - const S = struct { const StructInner = extern struct { outer: StructOuter = std.mem.zeroes(StructOuter), @@ -2151,7 +2149,6 @@ test "initiate global variable with runtime value" { test "struct containing optional pointer to array of @This()" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { x: ?*const [1]@This(), diff --git a/test/behavior/struct_contains_null_ptr_itself.zig b/test/behavior/struct_contains_null_ptr_itself.zig index d3dacc50cd..d0cb3ef443 100644 --- a/test/behavior/struct_contains_null_ptr_itself.zig +++ b/test/behavior/struct_contains_null_ptr_itself.zig @@ -5,7 +5,6 @@ const builtin = @import("builtin"); test "struct contains null pointer which contains original struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var x: ?*NodeLineComment = null; _ = &x; diff --git a/test/behavior/this.zig b/test/behavior/this.zig index fadb21023e..3f8fe13316 100644 --- a/test/behavior/this.zig +++ b/test/behavior/this.zig @@ -50,7 +50,6 @@ test "this used as optional function parameter" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var global: State = undefined; global.enter = prev; diff --git a/test/behavior/type.zig b/test/behavior/type.zig index c00d3de417..1a36f576f1 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -260,7 +260,6 @@ test "Type.Struct" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const A = @Type(@typeInfo(struct { x: u8, y: u32 })); const infoA = @typeInfo(A).Struct; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 73bfe4a7cb..c720d5c908 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -2145,7 +2145,6 @@ test "pass register-sized field as non-register-sized union" { test "circular dependency through pointer field of a union" { if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const S = struct { const UnionInner = extern struct { diff --git a/test/behavior/void.zig b/test/behavior/void.zig index 5c4215b870..26d7a4e4c7 100644 --- a/test/behavior/void.zig +++ b/test/behavior/void.zig @@ -37,7 +37,6 @@ test "void optional" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; var x: ?void = {}; _ = &x;