Commit 687370237f

Matthew Lugg <mlugg@mlugg.co.uk>
2025-07-22 10:50:34
llvm: fix switch loop on larger than pointer integer
1 parent f34b478
Changed files (2)
src
codegen
test
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(
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);
+}