diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index a570dd5ec0..c60b857fd9 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -6050,10 +6050,10 @@ pub const FuncGen = struct { const target_blocks = dispatch_info.case_blocks[0..target_blocks_len]; // Make sure to cast the index to a usize so it's not treated as negative! - const table_index = try self.wip.cast( - .zext, + const table_index = try self.wip.conv( + .unsigned, try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""), - try o.lowerType(pt, Type.usize), + try o.lowerType(pt, .usize), "", ); const target_ptr_ptr = try self.wip.gep( diff --git a/test/behavior/switch_loop.zig b/test/behavior/switch_loop.zig index 98605692be..35cc857b62 100644 --- a/test/behavior/switch_loop.zig +++ b/test/behavior/switch_loop.zig @@ -226,3 +226,28 @@ test "unanalyzed continue with operand" { true => {}, } } + +test "switch loop on larger than pointer integer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + + var entry: @Type(.{ .int = .{ + .signedness = .unsigned, + .bits = @bitSizeOf(usize) + 1, + } }) = undefined; + entry = 0; + loop: switch (entry) { + 0 => { + entry += 1; + continue :loop 1; + }, + 1 => |x| { + entry += 1; + continue :loop x + 1; + }, + 2 => entry += 1, + else => unreachable, + } + try expect(entry == 3); +}