From a52e47230718c6e38dfd84ac0571a597ecd9719f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 14 May 2021 08:31:22 +0200 Subject: [PATCH] stage1: Widen non byte-sized atomic loads/stores Checking if the size is a power of two is not enough, should also check if it's a multiple of 8. Closes #7976 --- src/stage1/codegen.cpp | 6 +++--- test/stage1/behavior/atomics.zig | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 015a64f68a..d70b2d498c 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -5485,8 +5485,8 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool } static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) { - // If the operand type of an atomic operation is not a power of two sized - // we need to widen it before using it and then truncate the result. + // If the operand type of an atomic operation is not byte sized we need to + // widen it before using it and then truncate the result. ir_assert(instruction->value->type->id == ZigTypeIdPointer, instruction); ZigType *operand_type = instruction->value->type->data.pointer.child_type; @@ -5498,7 +5498,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) { bool is_signed = operand_type->data.integral.is_signed; ir_assert(bit_count != 0, instruction); - if (bit_count == 1 || !is_power_of_2(bit_count)) { + if (!is_power_of_2(bit_count) || bit_count % 8) { return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8)); } else { return nullptr; diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig index 74a161b6fc..f965f53b05 100644 --- a/test/stage1/behavior/atomics.zig +++ b/test/stage1/behavior/atomics.zig @@ -199,7 +199,7 @@ fn testAtomicRmwInt() !void { test "atomics with different types" { try testAtomicsWithType(bool, true, false); - inline for (.{ u1, i5, u15 }) |T| { + inline for (.{ u1, i4, u5, i15, u24 }) |T| { var x: T = 0; try testAtomicsWithType(T, 0, 1); }