authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 10:29:15+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 10:29:15+02:00
log64e60d8ae2c06689a2e0533eb43a1c6a8ff01259
treed0def260a4fe64767bc66dd869a63ad58970ebf8
parent21809c33001cc53c8fb3b56b25264e8d9076bed9
signaturelock-open Commit is signed but in an unrecognized format.

special case atomic operations on zero bit types


2 files changed, 50 insertions(+), 14 deletions(-)

src/ir.cpp+31-6
...@@ -25199,12 +25199,22 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch...@@ -25199,12 +25199,22 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch
25199 return ira->codegen->invalid_inst_gen;25199 return ira->codegen->invalid_inst_gen;
25200 }25200 }
2520125201
25202 ZigType *result_type = get_optional_type(ira->codegen, operand_type);
25203
25204 // special case zero bit types
25205 if (type_has_one_possible_value(ira->codegen, operand_type) == OnePossibleValueYes) {
25206 ZigValue *val = ira->codegen->pass1_arena->allocate<ZigValue>(1);
25207 val->special = ConstValSpecialStatic;
25208 val->type = result_type;
25209 set_optional_value_to_null(val);
25210 return ir_const_move(ira, &instruction->base.base, val);
25211 }
25212
25202 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar &&25213 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
25203 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) {25214 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) {
25204 zig_panic("TODO compile-time execution of cmpxchg");25215 zig_panic("TODO compile-time execution of cmpxchg");
25205 }25216 }
2520625217
25207 ZigType *result_type = get_optional_type(ira->codegen, operand_type);
25208 IrInstGen *result_loc;25218 IrInstGen *result_loc;
25209 if (handle_is_ptr(ira->codegen, result_type)) {25219 if (handle_is_ptr(ira->codegen, result_type)) {
25210 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,25220 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
...@@ -28317,18 +28327,23 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi...@@ -28317,18 +28327,23 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi
2831728327
28318 *actual_type = nullptr;28328 *actual_type = nullptr;
28319 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {28329 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {
28330 ZigType *int_type;
28320 if (operand_type->id == ZigTypeIdEnum) {28331 if (operand_type->id == ZigTypeIdEnum) {
28321 operand_type = operand_type->data.enumeration.tag_int_type;28332 int_type = operand_type->data.enumeration.tag_int_type;
28333 } else {
28334 int_type = operand_type;
28322 }28335 }
28336 auto bit_count = int_type->data.integral.bit_count;
28337 bool is_signed = int_type->data.integral.is_signed;
28323 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);28338 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
28324 if (operand_type->data.integral.bit_count > max_atomic_bits) {28339
28340 if (bit_count > max_atomic_bits) {
28325 ir_add_error(ira, &op->base,28341 ir_add_error(ira, &op->base,
28326 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type",28342 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type",
28327 max_atomic_bits, operand_type->data.integral.bit_count));28343 max_atomic_bits, bit_count));
28328 return ira->codegen->builtin_types.entry_invalid;28344 return ira->codegen->builtin_types.entry_invalid;
28329 }28345 }
28330 auto bit_count = operand_type->data.integral.bit_count;28346
28331 bool is_signed = operand_type->data.integral.is_signed;
28332 if (bit_count < 2 || !is_power_of_2(bit_count)) {28347 if (bit_count < 2 || !is_power_of_2(bit_count)) {
28333 if (bit_count < 8) {28348 if (bit_count < 8) {
28334 *actual_type = get_int_type(ira->codegen, is_signed, 8);28349 *actual_type = get_int_type(ira->codegen, is_signed, 8);
...@@ -28423,6 +28438,11 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto...@@ -28423,6 +28438,11 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto
28423 return ira->codegen->invalid_inst_gen;28438 return ira->codegen->invalid_inst_gen;
28424 }28439 }
2842528440
28441 // special case zero bit types
28442 if (type_has_one_possible_value(ira->codegen, operand_type) == OnePossibleValueYes) {
28443 return ir_const_move(ira, &instruction->base.base, get_the_one_possible_value(ira->codegen, operand_type));
28444 }
28445
28426 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar)28446 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar)
28427 {28447 {
28428 ir_add_error(ira, &instruction->base.base,28448 ir_add_error(ira, &instruction->base.base,
...@@ -28504,6 +28524,11 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA...@@ -28504,6 +28524,11 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA
28504 return ira->codegen->invalid_inst_gen;28524 return ira->codegen->invalid_inst_gen;
28505 }28525 }
2850628526
28527 // special case zero bit types
28528 if (type_has_one_possible_value(ira->codegen, operand_type) == OnePossibleValueYes) {
28529 return ir_const_void(ira, &instruction->base.base);
28530 }
28531
28507 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) {28532 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) {
28508 IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false);28533 IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false);
28509 result->value->type = ira->codegen->builtin_types.entry_void;28534 result->value->type = ira->codegen->builtin_types.entry_void;
test/stage1/behavior/atomics.zig+19-8
...@@ -162,12 +162,23 @@ fn testAtomicRmwFloat() void {...@@ -162,12 +162,23 @@ fn testAtomicRmwFloat() void {
162 expect(x == 4);162 expect(x == 4);
163}163}
164164
165test "atomics with bool" {165test "atomics with different types" {
166 var x = false;166 // testAtomicsWithType(bool, true, false);
167 @atomicStore(bool, &x, true, .SeqCst);167 // inline for (.{ u1, i5, u33 }) |T| {
168 expect(x == true);168 // var x: T = 0;
169 expect(@atomicLoad(bool, &x, .SeqCst) == true);169 // testAtomicsWithType(T, 0, 1);
170 expect(@atomicRmw(bool, &x, .Xchg, false, .SeqCst) == true);170 // }
171 expect(@cmpxchgStrong(bool, &x, false, true, .SeqCst, .SeqCst) == null);171 testAtomicsWithType(u0, 0, 0);
172 expect(@cmpxchgStrong(bool, &x, false, true, .SeqCst, .SeqCst).? == true);172 testAtomicsWithType(i0, 0, 0);
173}
174
175fn testAtomicsWithType(comptime T: type, a: T, b: T) void {
176 var x: T = b;
177 @atomicStore(T, &x, a, .SeqCst);
178 expect(x == a);
179 expect(@atomicLoad(T, &x, .SeqCst) == a);
180 expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);
181 expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);
182 if (@sizeOf(T) != 0)
183 expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);
173}184}