authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-14 08:31:22+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-14 15:16:24-04:00
loga52e47230718c6e38dfd84ac0571a597ecd9719f
tree6821a00836849ad69933c57123a3f365b3fe07b4
parent2d4d4baa42590803cff8581add325ea3f102ac2a

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

2 files changed, 4 insertions(+), 4 deletions(-)

src/stage1/codegen.cpp+3-3
...@@ -5485,8 +5485,8 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool...@@ -5485,8 +5485,8 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool
5485}5485}
54865486
5487static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {5487static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
5488 // If the operand type of an atomic operation is not a power of two sized5488 // If the operand type of an atomic operation is not byte sized we need to
5489 // we need to widen it before using it and then truncate the result.5489 // widen it before using it and then truncate the result.
54905490
5491 ir_assert(instruction->value->type->id == ZigTypeIdPointer, instruction);5491 ir_assert(instruction->value->type->id == ZigTypeIdPointer, instruction);
5492 ZigType *operand_type = instruction->value->type->data.pointer.child_type;5492 ZigType *operand_type = instruction->value->type->data.pointer.child_type;
...@@ -5498,7 +5498,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {...@@ -5498,7 +5498,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
5498 bool is_signed = operand_type->data.integral.is_signed;5498 bool is_signed = operand_type->data.integral.is_signed;
54995499
5500 ir_assert(bit_count != 0, instruction);5500 ir_assert(bit_count != 0, instruction);
5501 if (bit_count == 1 || !is_power_of_2(bit_count)) {5501 if (!is_power_of_2(bit_count) || bit_count % 8) {
5502 return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8));5502 return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8));
5503 } else {5503 } else {
5504 return nullptr;5504 return nullptr;
test/stage1/behavior/atomics.zig+1-1
...@@ -199,7 +199,7 @@ fn testAtomicRmwInt() !void {...@@ -199,7 +199,7 @@ fn testAtomicRmwInt() !void {
199199
200test "atomics with different types" {200test "atomics with different types" {
201 try testAtomicsWithType(bool, true, false);201 try testAtomicsWithType(bool, true, false);
202 inline for (.{ u1, i5, u15 }) |T| {202 inline for (.{ u1, i4, u5, i15, u24 }) |T| {
203 var x: T = 0;203 var x: T = 0;
204 try testAtomicsWithType(T, 0, 1);204 try testAtomicsWithType(T, 0, 1);
205 }205 }