aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-10-05 23:05:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-10-05 23:05:14 -0700
commite16ddad49f1b3e4ce10ce8fb653e48f24a9d4837 (patch)
tree131a0873355fecce3c1abac1d0f42b8cab27d515 /src/codegen/llvm.zig
parentcb616cb7972bb2f38ea4527c7ec0ae3cc0d64c7c (diff)
downloadzig-e16ddad49f1b3e4ce10ce8fb653e48f24a9d4837.tar.gz
zig-e16ddad49f1b3e4ce10ce8fb653e48f24a9d4837.zip
stage2: enum fixes
* Sema: fix a missing copy on enum tag values * LLVM backend: fix lowering of enum constant values for enums with specified tag values. * Value: fix enumToInt for `enum_numbered` cases. The float widening behavior tests which rely on compiler-rt symbols are now passing.
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 00df4346d2..ceaca07a49 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -889,9 +889,9 @@ pub const DeclGen = struct {
.Int => {
var bigint_space: Value.BigIntSpace = undefined;
const bigint = tv.val.toBigInt(&bigint_space);
-
- const llvm_type = try self.llvmType(tv.ty);
- if (bigint.eqZero()) return llvm_type.constNull();
+ const target = self.module.getTarget();
+ const int_info = tv.ty.intInfo(target);
+ const llvm_type = self.context.intType(int_info.bits);
const unsigned_val = if (bigint.limbs.len == 1)
llvm_type.constInt(bigint.limbs[0], .False)
@@ -903,15 +903,24 @@ pub const DeclGen = struct {
return unsigned_val;
},
.Enum => {
- const llvm_type = try self.llvmType(tv.ty);
- const uint: u64 = uint: {
- if (tv.val.castTag(.enum_field_index)) |payload| {
- break :uint payload.data;
- }
- break :uint tv.val.toUnsignedInt();
- };
- const llvm_int = llvm_type.constInt(uint, .False);
- return llvm_int;
+ var int_buffer: Value.Payload.U64 = undefined;
+ const int_val = tv.enumToInt(&int_buffer);
+
+ var bigint_space: Value.BigIntSpace = undefined;
+ const bigint = int_val.toBigInt(&bigint_space);
+
+ const target = self.module.getTarget();
+ const int_info = tv.ty.intInfo(target);
+ const llvm_type = self.context.intType(int_info.bits);
+
+ const unsigned_val = if (bigint.limbs.len == 1)
+ llvm_type.constInt(bigint.limbs[0], .False)
+ else
+ llvm_type.constIntOfArbitraryPrecision(@intCast(c_uint, bigint.limbs.len), bigint.limbs.ptr);
+ if (!bigint.positive) {
+ return llvm.constNeg(unsigned_val);
+ }
+ return unsigned_val;
},
.Float => {
const llvm_ty = try self.llvmType(tv.ty);