| author | |
| committer | |
| log | 17e07ffc6381a1650b6bac5948b9f22d24411982 |
| tree | 3d72ff4335360dd314567cfaf822deec99a472dd |
| parent | 21f23814383ff8060a6b983c5ff9e47b5f1853ba |
Follow-up to https://codeberg.org/ziglang/zig/pulls/357113 files changed, 40 insertions(+), 10 deletions(-)
src/codegen/llvm.zig+9-4| ... | ... | @@ -2912,7 +2912,7 @@ pub const Object = struct { |
| 2912 | 2912 | |
| 2913 | 2913 | return switch (t.toIntern()) { |
| 2914 | 2914 | .u0_type => unreachable, // no runtime bits |
| 2915 | .u1_type => try o.intType(1, repr), | |
| 2915 | .u1_type, .bool_type => try o.intType(1, repr), | |
| 2916 | 2916 | .u8_type, .i8_type => try o.intType(8, repr), |
| 2917 | 2917 | .u16_type, .i16_type => try o.intType(16, repr), |
| 2918 | 2918 | .u29_type => try o.intType(29, repr), |
| ... | ... | @@ -2983,7 +2983,6 @@ pub const Object = struct { |
| 2983 | 2983 | // @foo = external global i8 |
| 2984 | 2984 | return .i8; |
| 2985 | 2985 | }, |
| 2986 | .bool_type => .i1, | |
| 2987 | 2986 | .anyerror_type => try o.errorIntType(repr), |
| 2988 | 2987 | .void_type => unreachable, // no runtime bits |
| 2989 | 2988 | .type_type => unreachable, // no runtime bits |
| ... | ... | @@ -3472,8 +3471,14 @@ pub const Object = struct { |
| 3472 | 3471 | .null => unreachable, // non-runtime value |
| 3473 | 3472 | .@"unreachable" => unreachable, // non-runtime value |
| 3474 | 3473 | |
| 3475 | .false => .false, | |
| 3476 | .true => .true, | |
| 3474 | .false => switch (repr) { | |
| 3475 | .as_value => .false, | |
| 3476 | .in_memory, .memory_access => try o.builder.intConst(.i8, 0), | |
| 3477 | }, | |
| 3478 | .true => switch (repr) { | |
| 3479 | .as_value => .true, | |
| 3480 | .in_memory, .memory_access => try o.builder.intConst(.i8, 1), | |
| 3481 | }, | |
| 3477 | 3482 | }, |
| 3478 | 3483 | .enum_literal => unreachable, // non-runtime value |
| 3479 | 3484 | .@"extern" => unreachable, // non-runtime value |
src/codegen/llvm/FuncGen.zig+11-6| ... | ... | @@ -2950,12 +2950,11 @@ fn airIsErr( |
| 2950 | 2950 | if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal; |
| 2951 | 2951 | |
| 2952 | 2952 | if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 2953 | const val: Builder.Constant = switch (cond) { | |
| 2953 | return switch (cond) { | |
| 2954 | 2954 | .eq => .true, // 0 == 0 |
| 2955 | 2955 | .ne => .false, // 0 != 0 |
| 2956 | 2956 | else => unreachable, |
| 2957 | 2957 | }; |
| 2958 | return val.toValue(); | |
| 2959 | 2958 | } |
| 2960 | 2959 | |
| 2961 | 2960 | if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu)); |
| ... | ... | @@ -6666,7 +6665,10 @@ fn load( |
| 6666 | 6665 | const llvm_value_ty = try o.lowerType(load_ty, .as_value); |
| 6667 | 6666 | |
| 6668 | 6667 | if (llvm_access_ty != llvm_value_ty) { |
| 6669 | assert(load_ty.isAbiInt(zcu)); | |
| 6668 | const signedness: std.lang.Signedness = switch (load_ty.toIntern()) { | |
| 6669 | .bool_type => .unsigned, | |
| 6670 | else => load_ty.intInfo(zcu).signedness, | |
| 6671 | }; | |
| 6670 | 6672 | // `load_ty` is an integer type with padding bits. In theory, we shouldn't need any special |
| 6671 | 6673 | // handling for these, as LLVM's documented semantics are a valid implementation of Zig's |
| 6672 | 6674 | // semantics. However: |
| ... | ... | @@ -6685,7 +6687,7 @@ fn load( |
| 6685 | 6687 | // implemented, but until then, do a normal trunc for packed types. |
| 6686 | 6688 | return fg.wip.cast(switch (load_ty.zigTypeTag(zcu)) { |
| 6687 | 6689 | .@"struct", .@"union" => .trunc, |
| 6688 | else => switch (load_ty.intInfo(zcu).signedness) { | |
| 6690 | else => switch (signedness) { | |
| 6689 | 6691 | .unsigned => .@"trunc nuw", |
| 6690 | 6692 | .signed => .@"trunc nsw", |
| 6691 | 6693 | }, |
| ... | ... | @@ -6740,10 +6742,13 @@ fn store( |
| 6740 | 6742 | const llvm_value_ty = try o.lowerType(elem_ty, .as_value); |
| 6741 | 6743 | |
| 6742 | 6744 | if (llvm_access_ty != llvm_value_ty) { |
| 6743 | assert(elem_ty.isAbiInt(zcu)); | |
| 6745 | const signedness: std.lang.Signedness = switch (elem_ty.toIntern()) { | |
| 6746 | .bool_type => .unsigned, | |
| 6747 | else => elem_ty.intInfo(zcu).signedness, | |
| 6748 | }; | |
| 6744 | 6749 | // `elem_ty` is an integer type with padding bits, so we need to handle it specially---see |
| 6745 | 6750 | // the corresponding comment in `FuncGen.load` for more details. |
| 6746 | const extended = try fg.wip.cast(switch (elem_ty.intInfo(zcu).signedness) { | |
| 6751 | const extended = try fg.wip.cast(switch (signedness) { | |
| 6747 | 6752 | .unsigned => .zext, |
| 6748 | 6753 | .signed => .sext, |
| 6749 | 6754 | }, elem, llvm_access_ty, ""); |
test/llvm_ir.zig+20| ... | ... | @@ -116,6 +116,26 @@ pub fn addCases(cases: *tests.LlvmIrContext) void { |
| 116 | 116 | "null_pointer_is_valid", |
| 117 | 117 | "store i16 42, ptr", |
| 118 | 118 | }, .{}); |
| 119 | ||
| 120 | cases.addMatches("load and store bool", | |
| 121 | \\export fn foo(a: *bool, b: *align(2) bool) void { | |
| 122 | \\ const tmp = a.*; | |
| 123 | \\ a.* = b.*; | |
| 124 | \\ b.* = tmp; | |
| 125 | \\} | |
| 126 | , &.{ | |
| 127 | // TODO: this should all be one multiline string literal, but `-femit-llvm-ir` is currently | |
| 128 | // emitting CRLF on Windows, which is a pain to handle here. In future that option will emit | |
| 129 | // unoptimized LLVM IR emitted directly from Zig, so that bug will go away. | |
| 130 | " %3 = load i8, ptr %0, align 1", | |
| 131 | " %4 = trunc nuw i8 %3 to i1", | |
| 132 | " %5 = load i8, ptr %1, align 2", | |
| 133 | " %6 = trunc nuw i8 %5 to i1", | |
| 134 | " %7 = zext i1 %6 to i8", | |
| 135 | " store i8 %7, ptr %0, align 1", | |
| 136 | " %8 = zext i1 %4 to i8", | |
| 137 | " store i8 %8, ptr %1, align 2", | |
| 138 | }, .{ .strip = true }); | |
| 119 | 139 | } |
| 120 | 140 | |
| 121 | 141 | const std = @import("std"); |