authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 09:24:53+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 09:24:53+02:00
log21809c33001cc53c8fb3b56b25264e8d9076bed9
treef02e1e919af56b1e3616ee01f02651910b5a3a4c
parentee5b00a8b90ef375d0cd4432d31e3a4ed0b6f632
signaturelock-open Commit is signed but in an unrecognized format.

support non power of two integers in atomic ops


3 files changed, 73 insertions(+), 67 deletions(-)

src/all_types.hpp+8
...@@ -3567,6 +3567,8 @@ struct IrInstGenCmpxchg {...@@ -3567,6 +3567,8 @@ struct IrInstGenCmpxchg {
3567 IrInstGen *cmp_value;3567 IrInstGen *cmp_value;
3568 IrInstGen *new_value;3568 IrInstGen *new_value;
3569 IrInstGen *result_loc;3569 IrInstGen *result_loc;
3570 // non null if operand needs widening and truncating
3571 ZigType *actual_type;
3570 bool is_weak;3572 bool is_weak;
3571};3573};
35723574
...@@ -4199,6 +4201,8 @@ struct IrInstGenAtomicRmw {...@@ -4199,6 +4201,8 @@ struct IrInstGenAtomicRmw {
41994201
4200 IrInstGen *ptr;4202 IrInstGen *ptr;
4201 IrInstGen *operand;4203 IrInstGen *operand;
4204 // non null if operand needs widening and truncating
4205 ZigType *actual_type;
4202 AtomicRmwOp op;4206 AtomicRmwOp op;
4203 AtomicOrder ordering;4207 AtomicOrder ordering;
4204};4208};
...@@ -4215,6 +4219,8 @@ struct IrInstGenAtomicLoad {...@@ -4215,6 +4219,8 @@ struct IrInstGenAtomicLoad {
4215 IrInstGen base;4219 IrInstGen base;
42164220
4217 IrInstGen *ptr;4221 IrInstGen *ptr;
4222 // non null if operand needs widening and truncating
4223 ZigType *actual_type;
4218 AtomicOrder ordering;4224 AtomicOrder ordering;
4219};4225};
42204226
...@@ -4232,6 +4238,8 @@ struct IrInstGenAtomicStore {...@@ -4232,6 +4238,8 @@ struct IrInstGenAtomicStore {
42324238
4233 IrInstGen *ptr;4239 IrInstGen *ptr;
4234 IrInstGen *value;4240 IrInstGen *value;
4241 // non null if operand needs widening and truncating
4242 ZigType *actual_type;
4235 AtomicOrder ordering;4243 AtomicOrder ordering;
4236};4244};
42374245
src/codegen.cpp+22-23
...@@ -5225,12 +5225,12 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5225,12 +5225,12 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
5225 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);5225 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);
52265226
5227 ZigType *operand_type = instruction->new_value->value->type;5227 ZigType *operand_type = instruction->new_value->value->type;
5228 if (operand_type->id == ZigTypeIdBool) {5228 if (instruction->actual_type != nullptr) {
5229 // treat bool as u85229 // operand needs widening and truncating
5230 ptr_val = LLVMBuildBitCast(g->builder, ptr_val,5230 ptr_val = LLVMBuildBitCast(g->builder, ptr_val,
5231 LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");5231 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");
5232 cmp_val = LLVMConstZExt(cmp_val, g->builtin_types.entry_u8->llvm_type);5232 cmp_val = LLVMConstZExt(cmp_val, get_llvm_type(g, instruction->actual_type));
5233 new_val = LLVMConstZExt(new_val, g->builtin_types.entry_u8->llvm_type);5233 new_val = LLVMConstZExt(new_val, get_llvm_type(g, instruction->actual_type));
5234 }5234 }
52355235
5236 LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order);5236 LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order);
...@@ -5245,8 +5245,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5245,8 +5245,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
52455245
5246 if (!handle_is_ptr(g, optional_type)) {5246 if (!handle_is_ptr(g, optional_type)) {
5247 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");5247 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
5248 if (operand_type->id == ZigTypeIdBool) {5248 if (instruction->actual_type != nullptr) {
5249 payload_val = LLVMBuildTrunc(g->builder, payload_val, g->builtin_types.entry_bool->llvm_type, "");5249 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
5250 }5250 }
5251 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");5251 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
5252 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");5252 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
...@@ -5262,8 +5262,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5262,8 +5262,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
5262 ir_assert(type_has_bits(g, child_type), &instruction->base);5262 ir_assert(type_has_bits(g, child_type), &instruction->base);
52635263
5264 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");5264 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
5265 if (operand_type->id == ZigTypeIdBool) {5265 if (instruction->actual_type != nullptr) {
5266 payload_val = LLVMBuildTrunc(g->builder, payload_val, g->builtin_types.entry_bool->llvm_type, "");5266 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
5267 }5267 }
5268 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");5268 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
5269 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);5269 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
...@@ -5842,14 +5842,14 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable...@@ -5842,14 +5842,14 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
5842 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5842 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
5843 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);5843 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
58445844
5845 if (operand_type->id == ZigTypeIdBool) {5845 if (instruction->actual_type != nullptr) {
5846 // treat bool as u85846 // operand needs widening and truncating
5847 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,5847 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,
5848 LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");5848 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");
5849 LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_u8->llvm_type, "");5849 LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, get_llvm_type(g, instruction->actual_type), "");
5850 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,5850 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,
5851 g->is_single_threaded);5851 g->is_single_threaded);
5852 return LLVMBuildTrunc(g->builder, uncasted_result, g->builtin_types.entry_bool->llvm_type, "");5852 return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
5853 }5853 }
58545854
5855 if (get_codegen_ptr_type_bail(g, operand_type) == nullptr) {5855 if (get_codegen_ptr_type_bail(g, operand_type) == nullptr) {
...@@ -5872,13 +5872,13 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl...@@ -5872,13 +5872,13 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl
5872 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5872 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
58735873
5874 ZigType *operand_type = instruction->ptr->value->type->data.pointer.child_type;5874 ZigType *operand_type = instruction->ptr->value->type->data.pointer.child_type;
5875 if (operand_type->id == ZigTypeIdBool) {5875 if (instruction->actual_type != nullptr) {
5876 // treat bool as u85876 // operand needs widening and truncating
5877 ptr = LLVMBuildBitCast(g->builder, ptr,5877 ptr = LLVMBuildBitCast(g->builder, ptr,
5878 LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");5878 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");
5879 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");5879 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
5880 LLVMSetOrdering(load_inst, ordering);5880 LLVMSetOrdering(load_inst, ordering);
5881 return LLVMBuildTrunc(g->builder, load_inst, g->builtin_types.entry_bool->llvm_type, "");5881 return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), "");
5882 }5882 }
5883 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");5883 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
5884 LLVMSetOrdering(load_inst, ordering);5884 LLVMSetOrdering(load_inst, ordering);
...@@ -5892,12 +5892,11 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab...@@ -5892,12 +5892,11 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab
5892 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5892 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
5893 LLVMValueRef value = ir_llvm_value(g, instruction->value);5893 LLVMValueRef value = ir_llvm_value(g, instruction->value);
58945894
5895 ZigType *operand_type = instruction->value->value->type;5895 if (instruction->actual_type != nullptr) {
5896 if (operand_type->id == ZigTypeIdBool) {5896 // operand needs widening and truncating
5897 // treat bool as u8
5898 ptr = LLVMBuildBitCast(g->builder, ptr,5897 ptr = LLVMBuildBitCast(g->builder, ptr,
5899 LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");5898 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");
5900 value = LLVMConstZExt(value, g->builtin_types.entry_u8->llvm_type);5899 value = LLVMConstZExt(value, get_llvm_type(g, instruction->actual_type));
5901 }5900 }
5902 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);5901 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);
5903 LLVMSetOrdering(store_inst, ordering);5902 LLVMSetOrdering(store_inst, ordering);
src/ir.cpp+43-44
...@@ -227,7 +227,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name...@@ -227,7 +227,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name
227static void ir_assert(bool ok, IrInst* source_instruction);227static void ir_assert(bool ok, IrInst* source_instruction);
228static void ir_assert_gen(bool ok, IrInstGen *source_instruction);228static void ir_assert_gen(bool ok, IrInstGen *source_instruction);
229static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var);229static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var);
230static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op);230static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, ZigType **actual_type);
231static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc);231static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc);
232static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc);232static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc);
233static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);233static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
...@@ -3406,7 +3406,7 @@ static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode...@@ -3406,7 +3406,7 @@ static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode
34063406
3407static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,3407static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
3408 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value,3408 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value,
3409 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc)3409 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc, ZigType *actual_type)
3410{3410{
3411 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb,3411 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb,
3412 source_instruction->scope, source_instruction->source_node);3412 source_instruction->scope, source_instruction->source_node);
...@@ -3418,6 +3418,7 @@ static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instructio...@@ -3418,6 +3418,7 @@ static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instructio
3418 instruction->failure_order = failure_order;3418 instruction->failure_order = failure_order;
3419 instruction->is_weak = is_weak;3419 instruction->is_weak = is_weak;
3420 instruction->result_loc = result_loc;3420 instruction->result_loc = result_loc;
3421 instruction->actual_type = actual_type;
34213422
3422 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);3423 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
3423 ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block);3424 ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block);
...@@ -4554,7 +4555,7 @@ static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNo...@@ -4554,7 +4555,7 @@ static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNo
4554}4555}
45554556
4556static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,4557static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
4557 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type)4558 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type, ZigType *actual_type)
4558{4559{
4559 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);4560 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);
4560 instruction->base.value->type = operand_type;4561 instruction->base.value->type = operand_type;
...@@ -4562,6 +4563,7 @@ static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,...@@ -4562,6 +4563,7 @@ static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
4562 instruction->op = op;4563 instruction->op = op;
4563 instruction->operand = operand;4564 instruction->operand = operand;
4564 instruction->ordering = ordering;4565 instruction->ordering = ordering;
4566 instruction->actual_type = actual_type;
45654567
4566 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4568 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
4567 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);4569 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);
...@@ -4585,13 +4587,14 @@ static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstN...@@ -4585,13 +4587,14 @@ static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstN
4585}4587}
45864588
4587static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,4589static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,
4588 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type)4590 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type, ZigType *actual_type)
4589{4591{
4590 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,4592 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,
4591 source_instr->scope, source_instr->source_node);4593 source_instr->scope, source_instr->source_node);
4592 instruction->base.value->type = operand_type;4594 instruction->base.value->type = operand_type;
4593 instruction->ptr = ptr;4595 instruction->ptr = ptr;
4594 instruction->ordering = ordering;4596 instruction->ordering = ordering;
4597 instruction->actual_type = actual_type;
45954598
4596 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4599 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
45974600
...@@ -4616,13 +4619,14 @@ static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, Ast...@@ -4616,13 +4619,14 @@ static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, Ast
4616}4619}
46174620
4618static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,4621static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,
4619 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering)4622 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering, ZigType *actual_type)
4620{4623{
4621 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,4624 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,
4622 source_instr->scope, source_instr->source_node);4625 source_instr->scope, source_instr->source_node);
4623 instruction->ptr = ptr;4626 instruction->ptr = ptr;
4624 instruction->value = value;4627 instruction->value = value;
4625 instruction->ordering = ordering;4628 instruction->ordering = ordering;
4629 instruction->actual_type = actual_type;
46264630
4627 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4631 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
4628 ir_ref_inst_gen(value, ira->new_irb.current_basic_block);4632 ir_ref_inst_gen(value, ira->new_irb.current_basic_block);
...@@ -25121,7 +25125,8 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb...@@ -25121,7 +25125,8 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb
25121}25125}
2512225126
25123static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) {25127static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) {
25124 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child);25128 ZigType *actual_type;
25129 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child, &actual_type);
25125 if (type_is_invalid(operand_type))25130 if (type_is_invalid(operand_type))
25126 return ira->codegen->invalid_inst_gen;25131 return ira->codegen->invalid_inst_gen;
2512725132
...@@ -25213,7 +25218,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch...@@ -25213,7 +25218,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch
2521325218
25214 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type,25219 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type,
25215 casted_ptr, casted_cmp_value, casted_new_value,25220 casted_ptr, casted_cmp_value, casted_new_value,
25216 success_order, failure_order, instruction->is_weak, result_loc);25221 success_order, failure_order, instruction->is_weak, result_loc, actual_type);
25217}25222}
2521825223
25219static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) {25224static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) {
...@@ -28305,17 +28310,15 @@ static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagTy...@@ -28305,17 +28310,15 @@ static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagTy
28305 }28310 }
28306}28311}
2830728312
28308static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {28313static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, ZigType **actual_type) {
28309 ZigType *operand_type = ir_resolve_type(ira, op);28314 ZigType *operand_type = ir_resolve_type(ira, op);
28310 if (type_is_invalid(operand_type))28315 if (type_is_invalid(operand_type))
28311 return ira->codegen->builtin_types.entry_invalid;28316 return ira->codegen->builtin_types.entry_invalid;
2831228317
28313 if (operand_type->id == ZigTypeIdInt) {28318 *actual_type = nullptr;
28314 if (operand_type->data.integral.bit_count < 8) {28319 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {
28315 ir_add_error(ira, &op->base,28320 if (operand_type->id == ZigTypeIdEnum) {
28316 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type",28321 operand_type = operand_type->data.enumeration.tag_int_type;
28317 operand_type->data.integral.bit_count));
28318 return ira->codegen->builtin_types.entry_invalid;
28319 }28322 }
28320 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);28323 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
28321 if (operand_type->data.integral.bit_count > max_atomic_bits) {28324 if (operand_type->data.integral.bit_count > max_atomic_bits) {
...@@ -28324,30 +28327,22 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {...@@ -28324,30 +28327,22 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {
28324 max_atomic_bits, operand_type->data.integral.bit_count));28327 max_atomic_bits, operand_type->data.integral.bit_count));
28325 return ira->codegen->builtin_types.entry_invalid;28328 return ira->codegen->builtin_types.entry_invalid;
28326 }28329 }
28327 if (!is_power_of_2(operand_type->data.integral.bit_count)) {28330 auto bit_count = operand_type->data.integral.bit_count;
28328 ir_add_error(ira, &op->base,28331 bool is_signed = operand_type->data.integral.is_signed;
28329 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));28332 if (bit_count < 2 || !is_power_of_2(bit_count)) {
28330 return ira->codegen->builtin_types.entry_invalid;28333 if (bit_count < 8) {
28331 }28334 *actual_type = get_int_type(ira->codegen, is_signed, 8);
28332 } else if (operand_type->id == ZigTypeIdEnum) {28335 } else if (bit_count < 16) {
28333 ZigType *int_type = operand_type->data.enumeration.tag_int_type;28336 *actual_type = get_int_type(ira->codegen, is_signed, 16);
28334 if (int_type->data.integral.bit_count < 8) {28337 } else if (bit_count < 32) {
28335 ir_add_error(ira, &op->base,28338 *actual_type = get_int_type(ira->codegen, is_signed, 32);
28336 buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type",28339 } else if (bit_count < 64) {
28337 int_type->data.integral.bit_count));28340 *actual_type = get_int_type(ira->codegen, is_signed, 64);
28338 return ira->codegen->builtin_types.entry_invalid;28341 } else if (bit_count < 128) {
28339 }28342 *actual_type = get_int_type(ira->codegen, is_signed, 128);
28340 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);28343 } else {
28341 if (int_type->data.integral.bit_count > max_atomic_bits) {28344 zig_unreachable();
28342 ir_add_error(ira, &op->base,28345 }
28343 buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type",
28344 max_atomic_bits, int_type->data.integral.bit_count));
28345 return ira->codegen->builtin_types.entry_invalid;
28346 }
28347 if (!is_power_of_2(int_type->data.integral.bit_count)) {
28348 ir_add_error(ira, &op->base,
28349 buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count));
28350 return ira->codegen->builtin_types.entry_invalid;
28351 }28346 }
28352 } else if (operand_type->id == ZigTypeIdFloat) {28347 } else if (operand_type->id == ZigTypeIdFloat) {
28353 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);28348 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
...@@ -28359,6 +28354,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {...@@ -28359,6 +28354,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {
28359 }28354 }
28360 } else if (operand_type->id == ZigTypeIdBool) {28355 } else if (operand_type->id == ZigTypeIdBool) {
28361 // will be treated as u828356 // will be treated as u8
28357 *actual_type = ira->codegen->builtin_types.entry_u8;
28362 } else {28358 } else {
28363 Error err;28359 Error err;
28364 ZigType *operand_ptr_type;28360 ZigType *operand_ptr_type;
...@@ -28376,7 +28372,8 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {...@@ -28376,7 +28372,8 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {
28376}28372}
2837728373
28378static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) {28374static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) {
28379 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);28375 ZigType *actual_type;
28376 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28380 if (type_is_invalid(operand_type))28377 if (type_is_invalid(operand_type))
28381 return ira->codegen->invalid_inst_gen;28378 return ira->codegen->invalid_inst_gen;
2838228379
...@@ -28434,11 +28431,12 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto...@@ -28434,11 +28431,12 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto
28434 }28431 }
2843528432
28436 return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op,28433 return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op,
28437 ordering, operand_type);28434 ordering, operand_type, actual_type);
28438}28435}
2843928436
28440static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) {28437static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) {
28441 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);28438 ZigType *actual_type;
28439 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28442 if (type_is_invalid(operand_type))28440 if (type_is_invalid(operand_type))
28443 return ira->codegen->invalid_inst_gen;28441 return ira->codegen->invalid_inst_gen;
2844428442
...@@ -28468,11 +28466,12 @@ static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAt...@@ -28468,11 +28466,12 @@ static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAt
28468 return result;28466 return result;
28469 }28467 }
2847028468
28471 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type);28469 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type, actual_type);
28472}28470}
2847328471
28474static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) {28472static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) {
28475 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);28473 ZigType *actual_type;
28474 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28476 if (type_is_invalid(operand_type))28475 if (type_is_invalid(operand_type))
28477 return ira->codegen->invalid_inst_gen;28476 return ira->codegen->invalid_inst_gen;
2847828477
...@@ -28511,7 +28510,7 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA...@@ -28511,7 +28510,7 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA
28511 return result;28510 return result;
28512 }28511 }
2851328512
28514 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering);28513 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering, actual_type);
28515}28514}
2851628515
28517static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) {28516static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) {