diff --git a/src/codegen.zig b/src/codegen.zig index bc50f36041..e8dd661684 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -854,6 +854,14 @@ pub fn generateSymbol( } return Result{ .appended = {} }; }, + .str_lit => { + const str_lit = typed_value.val.castTag(.str_lit).?.data; + const mod = bin_file.options.module.?; + const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; + try code.ensureUnusedCapacity(str_lit.len); + code.appendSliceAssumeCapacity(bytes); + return Result{ .appended = {} }; + }, else => unreachable, }, else => |t| { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 670efa6d0c..cccc0ff85c 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3882,6 +3882,32 @@ pub const DeclGen = struct { @intCast(c_uint, llvm_elems.len), ); }, + .str_lit => { + // Note, sentinel is not stored + const str_lit = tv.val.castTag(.str_lit).?.data; + const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; + const vector_len = @intCast(usize, tv.ty.arrayLen()); + assert(vector_len == bytes.len); + + const elem_ty = tv.ty.elemType(); + const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); + defer dg.gpa.free(llvm_elems); + for (llvm_elems) |*elem, i| { + var byte_payload: Value.Payload.U64 = .{ + .base = .{ .tag = .int_u64 }, + .data = bytes[i], + }; + + elem.* = try dg.lowerValue(.{ + .ty = elem_ty, + .val = Value.initPayload(&byte_payload.base), + }); + } + return llvm.constVector( + llvm_elems.ptr, + @intCast(c_uint, llvm_elems.len), + ); + }, else => unreachable, }, diff --git a/test/behavior.zig b/test/behavior.zig index ebd1e1afb7..9e01526d1d 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -161,6 +161,7 @@ test { _ = @import("behavior/int_div.zig"); _ = @import("behavior/inttoptr.zig"); _ = @import("behavior/ir_block_deps.zig"); + _ = @import("behavior/lower_strlit_to_vector.zig"); _ = @import("behavior/math.zig"); _ = @import("behavior/maximum_minimum.zig"); _ = @import("behavior/member_func.zig"); diff --git a/test/behavior/lower_strlit_to_vector.zig b/test/behavior/lower_strlit_to_vector.zig new file mode 100644 index 0000000000..4ca4cf716e --- /dev/null +++ b/test/behavior/lower_strlit_to_vector.zig @@ -0,0 +1,18 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +test "strlit to vector" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + 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_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + + const strlit = "0123456789abcdef0123456789ABCDEF"; + const vec_from_strlit: @Vector(32, u8) = strlit.*; + const arr_from_vec = @as([32]u8, vec_from_strlit); + for (strlit) |c, i| + try std.testing.expect(c == arr_from_vec[i]); + try std.testing.expectEqualSlices(u8, strlit, &arr_from_vec); +}