authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 16:46:12+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-03-11 16:48:18+02:00
log9262f065f50db3ea72454b6c1b9b66fd911aa6ba
tree79ccf2cc6b2f06fd87545ebc252c8403bd82357c
parentec906a97712b329694e8f2e1a35b50b75d052642
signaturelock-open Commit is signed but in an unrecognized format.

Move abi size checking to codegen


4 files changed, 84 insertions(+), 71 deletions(-)

lib/std/atomic/int.zig+5-8
...@@ -1,6 +1,3 @@...@@ -1,6 +1,3 @@
1const builtin = @import("builtin");
2const AtomicOrder = builtin.AtomicOrder;
3
4/// Thread-safe, lock-free integer1/// Thread-safe, lock-free integer
5pub fn Int(comptime T: type) type {2pub fn Int(comptime T: type) type {
6 return struct {3 return struct {
...@@ -14,16 +11,16 @@ pub fn Int(comptime T: type) type {...@@ -14,16 +11,16 @@ pub fn Int(comptime T: type) type {
1411
15 /// Returns previous value12 /// Returns previous value
16 pub fn incr(self: *Self) T {13 pub fn incr(self: *Self) T {
17 return @atomicRmw(T, &self.unprotected_value, builtin.AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);14 return @atomicRmw(T, &self.unprotected_value, .Add, 1, .SeqCst);
18 }15 }
1916
20 /// Returns previous value17 /// Returns previous value
21 pub fn decr(self: *Self) T {18 pub fn decr(self: *Self) T {
22 return @atomicRmw(T, &self.unprotected_value, builtin.AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);19 return @atomicRmw(T, &self.unprotected_value, .Sub, 1, .SeqCst);
23 }20 }
2421
25 pub fn get(self: *Self) T {22 pub fn get(self: *Self) T {
26 return @atomicLoad(T, &self.unprotected_value, AtomicOrder.SeqCst);23 return @atomicLoad(T, &self.unprotected_value, .SeqCst);
27 }24 }
2825
29 pub fn set(self: *Self, new_value: T) void {26 pub fn set(self: *Self, new_value: T) void {
...@@ -31,11 +28,11 @@ pub fn Int(comptime T: type) type {...@@ -31,11 +28,11 @@ pub fn Int(comptime T: type) type {
31 }28 }
3229
33 pub fn xchg(self: *Self, new_value: T) T {30 pub fn xchg(self: *Self, new_value: T) T {
34 return @atomicRmw(T, &self.unprotected_value, builtin.AtomicRmwOp.Xchg, new_value, AtomicOrder.SeqCst);31 return @atomicRmw(T, &self.unprotected_value, .Xchg, new_value, .SeqCst);
35 }32 }
3633
37 pub fn fetchAdd(self: *Self, op: T) T {34 pub fn fetchAdd(self: *Self, op: T) T {
38 return @atomicRmw(T, &self.unprotected_value, builtin.AtomicRmwOp.Add, op, AtomicOrder.SeqCst);35 return @atomicRmw(T, &self.unprotected_value, .Add, op, .SeqCst);
39 }36 }
40 };37 };
41}38}
src/all_types.hpp-8
...@@ -3567,8 +3567,6 @@ struct IrInstGenCmpxchg {...@@ -3567,8 +3567,6 @@ 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;
3572 bool is_weak;3570 bool is_weak;
3573};3571};
35743572
...@@ -4201,8 +4199,6 @@ struct IrInstGenAtomicRmw {...@@ -4201,8 +4199,6 @@ struct IrInstGenAtomicRmw {
42014199
4202 IrInstGen *ptr;4200 IrInstGen *ptr;
4203 IrInstGen *operand;4201 IrInstGen *operand;
4204 // non null if operand needs widening and truncating
4205 ZigType *actual_type;
4206 AtomicRmwOp op;4202 AtomicRmwOp op;
4207 AtomicOrder ordering;4203 AtomicOrder ordering;
4208};4204};
...@@ -4219,8 +4215,6 @@ struct IrInstGenAtomicLoad {...@@ -4219,8 +4215,6 @@ struct IrInstGenAtomicLoad {
4219 IrInstGen base;4215 IrInstGen base;
42204216
4221 IrInstGen *ptr;4217 IrInstGen *ptr;
4222 // non null if operand needs widening and truncating
4223 ZigType *actual_type;
4224 AtomicOrder ordering;4218 AtomicOrder ordering;
4225};4219};
42264220
...@@ -4238,8 +4232,6 @@ struct IrInstGenAtomicStore {...@@ -4238,8 +4232,6 @@ struct IrInstGenAtomicStore {
42384232
4239 IrInstGen *ptr;4233 IrInstGen *ptr;
4240 IrInstGen *value;4234 IrInstGen *value;
4241 // non null if operand needs widening and truncating
4242 ZigType *actual_type;
4243 AtomicOrder ordering;4235 AtomicOrder ordering;
4244};4236};
42454237
src/codegen.cpp+47-14
...@@ -5219,18 +5219,48 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool...@@ -5219,18 +5219,48 @@ static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool
5219 zig_unreachable();5219 zig_unreachable();
5220}5220}
52215221
5222static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
5223 // If the operand type of an atomic operation is not a power of two sized
5224 // we need to widen it before using it and then truncate the result.
5225
5226 ir_assert(instruction->value->type->id == ZigTypeIdPointer, instruction);
5227 ZigType *operand_type = instruction->value->type->data.pointer.child_type;
5228 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {
5229 if (operand_type->id == ZigTypeIdEnum) {
5230 operand_type = operand_type->data.enumeration.tag_int_type;
5231 }
5232 auto bit_count = operand_type->data.integral.bit_count;
5233 bool is_signed = operand_type->data.integral.is_signed;
5234
5235 ir_assert(bit_count != 0, instruction);
5236 if (bit_count == 1 || !is_power_of_2(bit_count)) {
5237 return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8));
5238 } else {
5239 return nullptr;
5240 }
5241 } else if (operand_type->id == ZigTypeIdFloat) {
5242 return nullptr;
5243 } else if (operand_type->id == ZigTypeIdBool) {
5244 return g->builtin_types.entry_u8->llvm_type;
5245 } else {
5246 ir_assert(get_codegen_ptr_type_bail(g, operand_type) != nullptr, instruction);
5247 return nullptr;
5248 }
5249}
5250
5222static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, IrInstGenCmpxchg *instruction) {5251static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, IrInstGenCmpxchg *instruction) {
5223 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr);5252 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr);
5224 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);5253 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);
5225 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);5254 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);
52265255
5227 ZigType *operand_type = instruction->new_value->value->type;5256 ZigType *operand_type = instruction->new_value->value->type;
5228 if (instruction->actual_type != nullptr) {5257 LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr);
5258 if (actual_abi_type != nullptr) {
5229 // operand needs widening and truncating5259 // operand needs widening and truncating
5230 ptr_val = LLVMBuildBitCast(g->builder, ptr_val,5260 ptr_val = LLVMBuildBitCast(g->builder, ptr_val,
5231 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");5261 LLVMPointerType(actual_abi_type, 0), "");
5232 cmp_val = LLVMBuildZExt(g->builder, cmp_val, get_llvm_type(g, instruction->actual_type), "");5262 cmp_val = LLVMBuildZExt(g->builder, cmp_val, actual_abi_type, "");
5233 new_val = LLVMBuildZExt(g->builder, new_val, get_llvm_type(g, instruction->actual_type), "");5263 new_val = LLVMBuildZExt(g->builder, new_val, actual_abi_type, "");
5234 }5264 }
52355265
5236 LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order);5266 LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order);
...@@ -5245,7 +5275,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5245,7 +5275,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
52455275
5246 if (!handle_is_ptr(g, optional_type)) {5276 if (!handle_is_ptr(g, optional_type)) {
5247 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");5277 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
5248 if (instruction->actual_type != nullptr) {5278 if (actual_abi_type != nullptr) {
5249 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");5279 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
5250 }5280 }
5251 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");5281 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
...@@ -5262,7 +5292,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5262,7 +5292,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
5262 ir_assert(type_has_bits(g, child_type), &instruction->base);5292 ir_assert(type_has_bits(g, child_type), &instruction->base);
52635293
5264 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");5294 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
5265 if (instruction->actual_type != nullptr) {5295 if (actual_abi_type != nullptr) {
5266 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");5296 payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
5267 }5297 }
5268 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");5298 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
...@@ -5842,11 +5872,12 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable...@@ -5842,11 +5872,12 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
5842 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5872 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
5843 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);5873 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
58445874
5845 if (instruction->actual_type != nullptr) {5875 LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr);
5876 if (actual_abi_type != nullptr) {
5846 // operand needs widening and truncating5877 // operand needs widening and truncating
5847 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,5878 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,
5848 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");5879 LLVMPointerType(actual_abi_type, 0), "");
5849 LLVMValueRef casted_operand = LLVMBuildZExt(g->builder, operand, get_llvm_type(g, instruction->actual_type), "");5880 LLVMValueRef casted_operand = LLVMBuildZExt(g->builder, operand, actual_abi_type, "");
5850 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,5881 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,
5851 g->is_single_threaded);5882 g->is_single_threaded);
5852 return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");5883 return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
...@@ -5872,10 +5903,11 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl...@@ -5872,10 +5903,11 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl
5872 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5903 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
58735904
5874 ZigType *operand_type = instruction->ptr->value->type->data.pointer.child_type;5905 ZigType *operand_type = instruction->ptr->value->type->data.pointer.child_type;
5875 if (instruction->actual_type != nullptr) {5906 LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr);
5907 if (actual_abi_type != nullptr) {
5876 // operand needs widening and truncating5908 // operand needs widening and truncating
5877 ptr = LLVMBuildBitCast(g->builder, ptr,5909 ptr = LLVMBuildBitCast(g->builder, ptr,
5878 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");5910 LLVMPointerType(actual_abi_type, 0), "");
5879 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");5911 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
5880 LLVMSetOrdering(load_inst, ordering);5912 LLVMSetOrdering(load_inst, ordering);
5881 return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), "");5913 return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), "");
...@@ -5892,11 +5924,12 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab...@@ -5892,11 +5924,12 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab
5892 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);5924 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
5893 LLVMValueRef value = ir_llvm_value(g, instruction->value);5925 LLVMValueRef value = ir_llvm_value(g, instruction->value);
58945926
5895 if (instruction->actual_type != nullptr) {5927 LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr);
5928 if (actual_abi_type != nullptr) {
5896 // operand needs widening5929 // operand needs widening
5897 ptr = LLVMBuildBitCast(g->builder, ptr,5930 ptr = LLVMBuildBitCast(g->builder, ptr,
5898 LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), "");5931 LLVMPointerType(actual_abi_type, 0), "");
5899 value = LLVMBuildZExt(g->builder, value, get_llvm_type(g, instruction->actual_type), "");5932 value = LLVMBuildZExt(g->builder, value, actual_abi_type, "");
5900 }5933 }
5901 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);5934 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);
5902 LLVMSetOrdering(store_inst, ordering);5935 LLVMSetOrdering(store_inst, ordering);
src/ir.cpp+32-41
...@@ -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, ZigType **actual_type);230static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op);
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, ZigType *actual_type)3409 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc)
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,7 +3418,6 @@ static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instructio...@@ -3418,7 +3418,6 @@ 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;
34223421
3423 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);3422 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
3424 ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block);3423 ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block);
...@@ -4555,7 +4554,7 @@ static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNo...@@ -4555,7 +4554,7 @@ static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNo
4555}4554}
45564555
4557static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,4556static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
4558 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type, ZigType *actual_type)4557 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type)
4559{4558{
4560 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);4559 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);
4561 instruction->base.value->type = operand_type;4560 instruction->base.value->type = operand_type;
...@@ -4563,7 +4562,6 @@ static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,...@@ -4563,7 +4562,6 @@ static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
4563 instruction->op = op;4562 instruction->op = op;
4564 instruction->operand = operand;4563 instruction->operand = operand;
4565 instruction->ordering = ordering;4564 instruction->ordering = ordering;
4566 instruction->actual_type = actual_type;
45674565
4568 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4566 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
4569 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);4567 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);
...@@ -4587,14 +4585,13 @@ static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstN...@@ -4587,14 +4585,13 @@ static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstN
4587}4585}
45884586
4589static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,4587static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,
4590 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type, ZigType *actual_type)4588 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type)
4591{4589{
4592 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,4590 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,
4593 source_instr->scope, source_instr->source_node);4591 source_instr->scope, source_instr->source_node);
4594 instruction->base.value->type = operand_type;4592 instruction->base.value->type = operand_type;
4595 instruction->ptr = ptr;4593 instruction->ptr = ptr;
4596 instruction->ordering = ordering;4594 instruction->ordering = ordering;
4597 instruction->actual_type = actual_type;
45984595
4599 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4596 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
46004597
...@@ -4619,14 +4616,13 @@ static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, Ast...@@ -4619,14 +4616,13 @@ static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, Ast
4619}4616}
46204617
4621static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,4618static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,
4622 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering, ZigType *actual_type)4619 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering)
4623{4620{
4624 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,4621 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,
4625 source_instr->scope, source_instr->source_node);4622 source_instr->scope, source_instr->source_node);
4626 instruction->ptr = ptr;4623 instruction->ptr = ptr;
4627 instruction->value = value;4624 instruction->value = value;
4628 instruction->ordering = ordering;4625 instruction->ordering = ordering;
4629 instruction->actual_type = actual_type;
46304626
4631 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);4627 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block);
4632 ir_ref_inst_gen(value, ira->new_irb.current_basic_block);4628 ir_ref_inst_gen(value, ira->new_irb.current_basic_block);
...@@ -25125,8 +25121,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb...@@ -25125,8 +25121,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb
25125}25121}
2512625122
25127static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) {25123static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) {
25128 ZigType *actual_type;25124 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child);
25129 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child, &actual_type);
25130 if (type_is_invalid(operand_type))25125 if (type_is_invalid(operand_type))
25131 return ira->codegen->invalid_inst_gen;25126 return ira->codegen->invalid_inst_gen;
2513225127
...@@ -25203,29 +25198,34 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch...@@ -25203,29 +25198,34 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch
2520325198
25204 // special case zero bit types25199 // special case zero bit types
25205 if (type_has_one_possible_value(ira->codegen, operand_type) == OnePossibleValueYes) {25200 if (type_has_one_possible_value(ira->codegen, operand_type) == OnePossibleValueYes) {
25206 ZigValue *val = ira->codegen->pass1_arena->allocate<ZigValue>(1);25201 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type);
25207 val->special = ConstValSpecialStatic;25202 set_optional_value_to_null(result->value);
25208 val->type = result_type;25203 return result;
25209 set_optional_value_to_null(val);
25210 return ir_const_move(ira, &instruction->base.base, val);
25211 }25204 }
2521225205
25213 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar &&25206 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
25214 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) {25207 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) {
25215 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, casted_ptr, nullptr);25208 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
25216 ZigValue *op1_val = ir_resolve_const(ira, result, UndefBad);25209 if (ptr_val == nullptr)
25210 return ira->codegen->invalid_inst_gen;
25211
25212 ZigValue *op1_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.base.source_node);
25213 if (op1_val == nullptr)
25214 return ira->codegen->invalid_inst_gen;
25215
25217 ZigValue *op2_val = ir_resolve_const(ira, casted_cmp_value, UndefBad);25216 ZigValue *op2_val = ir_resolve_const(ira, casted_cmp_value, UndefBad);
25217 if (op2_val == nullptr)
25218 return ira->codegen->invalid_inst_gen;
25219
25218 bool eql = const_values_equal(ira->codegen, op1_val, op2_val);25220 bool eql = const_values_equal(ira->codegen, op1_val, op2_val);
25219 ZigValue *val = ira->codegen->pass1_arena->allocate<ZigValue>(1);25221 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type);
25220 val->special = ConstValSpecialStatic;
25221 val->type = result_type;
25222 if (eql) {25222 if (eql) {
25223 ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, casted_new_value, false);25223 ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, casted_new_value, false);
25224 set_optional_value_to_null(val);25224 set_optional_value_to_null(result->value);
25225 } else {25225 } else {
25226 set_optional_payload(val, op1_val);25226 set_optional_payload(result->value, op1_val);
25227 }25227 }
25228 return ir_const_move(ira, &instruction->base.base, val);25228 return result;
25229 }25229 }
2523025230
25231 IrInstGen *result_loc;25231 IrInstGen *result_loc;
...@@ -25241,7 +25241,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch...@@ -25241,7 +25241,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch
2524125241
25242 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type,25242 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type,
25243 casted_ptr, casted_cmp_value, casted_new_value,25243 casted_ptr, casted_cmp_value, casted_new_value,
25244 success_order, failure_order, instruction->is_weak, result_loc, actual_type);25244 success_order, failure_order, instruction->is_weak, result_loc);
25245}25245}
2524625246
25247static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) {25247static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) {
...@@ -28333,12 +28333,11 @@ static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagTy...@@ -28333,12 +28333,11 @@ static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagTy
28333 }28333 }
28334}28334}
2833528335
28336static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, ZigType **actual_type) {28336static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {
28337 ZigType *operand_type = ir_resolve_type(ira, op);28337 ZigType *operand_type = ir_resolve_type(ira, op);
28338 if (type_is_invalid(operand_type))28338 if (type_is_invalid(operand_type))
28339 return ira->codegen->builtin_types.entry_invalid;28339 return ira->codegen->builtin_types.entry_invalid;
2834028340
28341 *actual_type = nullptr;
28342 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {28341 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) {
28343 ZigType *int_type;28342 ZigType *int_type;
28344 if (operand_type->id == ZigTypeIdEnum) {28343 if (operand_type->id == ZigTypeIdEnum) {
...@@ -28355,10 +28354,6 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi...@@ -28355,10 +28354,6 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi
28355 max_atomic_bits, bit_count));28354 max_atomic_bits, bit_count));
28356 return ira->codegen->builtin_types.entry_invalid;28355 return ira->codegen->builtin_types.entry_invalid;
28357 }28356 }
28358
28359 if (bit_count == 1 || !is_power_of_2(bit_count)) {
28360 *actual_type = get_int_type(ira->codegen, int_type->data.integral.is_signed, int_type->abi_size * 8);
28361 }
28362 } else if (operand_type->id == ZigTypeIdFloat) {28357 } else if (operand_type->id == ZigTypeIdFloat) {
28363 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);28358 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
28364 if (operand_type->data.floating.bit_count > max_atomic_bits) {28359 if (operand_type->data.floating.bit_count > max_atomic_bits) {
...@@ -28369,7 +28364,6 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi...@@ -28369,7 +28364,6 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi
28369 }28364 }
28370 } else if (operand_type->id == ZigTypeIdBool) {28365 } else if (operand_type->id == ZigTypeIdBool) {
28371 // will be treated as u828366 // will be treated as u8
28372 *actual_type = ira->codegen->builtin_types.entry_u8;
28373 } else {28367 } else {
28374 Error err;28368 Error err;
28375 ZigType *operand_ptr_type;28369 ZigType *operand_ptr_type;
...@@ -28387,8 +28381,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi...@@ -28387,8 +28381,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op, Zi
28387}28381}
2838828382
28389static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) {28383static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) {
28390 ZigType *actual_type;28384 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);
28391 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28392 if (type_is_invalid(operand_type))28385 if (type_is_invalid(operand_type))
28393 return ira->codegen->invalid_inst_gen;28386 return ira->codegen->invalid_inst_gen;
2839428387
...@@ -28451,12 +28444,11 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto...@@ -28451,12 +28444,11 @@ static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAto
28451 }28444 }
2845228445
28453 return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op,28446 return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op,
28454 ordering, operand_type, actual_type);28447 ordering, operand_type);
28455}28448}
2845628449
28457static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) {28450static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) {
28458 ZigType *actual_type;28451 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);
28459 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28460 if (type_is_invalid(operand_type))28452 if (type_is_invalid(operand_type))
28461 return ira->codegen->invalid_inst_gen;28453 return ira->codegen->invalid_inst_gen;
2846228454
...@@ -28486,12 +28478,11 @@ static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAt...@@ -28486,12 +28478,11 @@ static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAt
28486 return result;28478 return result;
28487 }28479 }
2848828480
28489 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type, actual_type);28481 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type);
28490}28482}
2849128483
28492static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) {28484static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) {
28493 ZigType *actual_type;28485 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);
28494 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child, &actual_type);
28495 if (type_is_invalid(operand_type))28486 if (type_is_invalid(operand_type))
28496 return ira->codegen->invalid_inst_gen;28487 return ira->codegen->invalid_inst_gen;
2849728488
...@@ -28535,7 +28526,7 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA...@@ -28535,7 +28526,7 @@ static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcA
28535 return result;28526 return result;
28536 }28527 }
2853728528
28538 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering, actual_type);28529 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering);
28539}28530}
2854028531
28541static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) {28532static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) {