From b8741c96dcfe631616e857384f4378832f4b70c1 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Tue, 14 Dec 2021 18:23:04 +0800 Subject: [PATCH 1/4] Use enum instead of symbol for `Atomic` primitives --- spec/compiler/codegen/primitives_spec.cr | 55 ++++++++++++++++ src/atomic.cr | 40 ++++++++++-- src/compiler/crystal/codegen/primitives.cr | 75 +++++++++++++--------- src/llvm/enums.cr | 24 ------- src/llvm/lib_llvm.cr | 4 +- src/llvm/lib_llvm_ext.cr | 4 +- 6 files changed, 138 insertions(+), 64 deletions(-) diff --git a/spec/compiler/codegen/primitives_spec.cr b/spec/compiler/codegen/primitives_spec.cr index aa44a293bd15..a69ed06c47a6 100644 --- a/spec/compiler/codegen/primitives_spec.cr +++ b/spec/compiler/codegen/primitives_spec.cr @@ -310,6 +310,61 @@ describe "Code gen: primitives" do {% end %} end + describe "atomicrmw" do + it "codegens atomicrmw with enums" do + run(<<-CR).to_i.should eq(3) + enum RMWBinOp + Add = 1 + end + + enum Ordering + SequentiallyConsistent = 7 + end + + @[Primitive(:atomicrmw)] + def atomicrmw(op : RMWBinOp, ptr : Int32*, val : Int32, ordering : Ordering, singlethread : Bool) : Int32 + end + + x = 1 + atomicrmw(:add, pointerof(x), 2, :sequentially_consistent, false) + x + CR + end + + it "codegens atomicrmw with enums" do + run(<<-CR).to_i.should eq(3) + enum RMWBinOp + Add = 1 + end + + enum Ordering + SequentiallyConsistent = 7 + end + + @[Primitive(:atomicrmw)] + def atomicrmw(op : RMWBinOp, ptr : Int32*, val : Int32, ordering : Ordering, singlethread : Bool) : Int32 + end + + x = 1 + atomicrmw(RMWBinOp::Add, pointerof(x), 2, Ordering::SequentiallyConsistent, false) + x + CR + end + + # TODO: remove after 1.3.0 + it "codegens atomicrmw with symbols" do + run(<<-CR).to_i.should eq(3) + @[Primitive(:atomicrmw)] + def atomicrmw(op : Symbol, ptr : Int32*, val : Int32, ordering : Symbol, singlethread : Bool) : Int32 + end + + x = 1 + atomicrmw(:add, pointerof(x), 2, :sequentially_consistent, false) + x + CR + end + end + it "allows @[Primitive] on method that has body" do run(%( module Moo diff --git a/src/atomic.cr b/src/atomic.cr index e93d9eb5e9dc..9fa4d92eaa6b 100644 --- a/src/atomic.cr +++ b/src/atomic.cr @@ -197,28 +197,58 @@ struct Atomic(T) @value end + # :nodoc: + # this enum should match `LLVMAtomicOrdering`'s definition + enum Ordering + NotAtomic = 0 + Unordered = 1 + Monotonic = 2 + Acquire = 4 + Release = 5 + AcquireRelease = 6 + SequentiallyConsistent = 7 + end + + # :nodoc: + # this enum should match `LLVMAtomicRMWBinOp`'s definition + enum RMWBinOp + Xchg + Add + Sub + And + Nand + Or + Xor + Max + Min + Umax + Umin + Fadd + Fsub + end + # :nodoc: module Ops # Defines methods that directly map to LLVM instructions related to atomic operations. @[Primitive(:cmpxchg)] - def self.cmpxchg(ptr : T*, cmp : T, new : T, success_ordering : Symbol, failure_ordering : Symbol) : {T, Bool} forall T + def self.cmpxchg(ptr : T*, cmp : T, new : T, success_ordering : Ordering, failure_ordering : Ordering) : {T, Bool} forall T end @[Primitive(:atomicrmw)] - def self.atomicrmw(op : Symbol, ptr : T*, val : T, ordering : Symbol, singlethread : Bool) : T forall T + def self.atomicrmw(op : RMWBinOp, ptr : T*, val : T, ordering : Ordering, singlethread : Bool) : T forall T end @[Primitive(:fence)] - def self.fence(ordering : Symbol, singlethread : Bool) : Nil + def self.fence(ordering : Ordering, singlethread : Bool) : Nil end @[Primitive(:load_atomic)] - def self.load(ptr : T*, ordering : Symbol, volatile : Bool) : T forall T + def self.load(ptr : T*, ordering : Ordering, volatile : Bool) : T forall T end @[Primitive(:store_atomic)] - def self.store(ptr : T*, value : T, ordering : Symbol, volatile : Bool) : Nil forall T + def self.store(ptr : T*, value : T, ordering : Ordering, volatile : Bool) : Nil forall T end end end diff --git a/src/compiler/crystal/codegen/primitives.cr b/src/compiler/crystal/codegen/primitives.cr index cae276f36e1f..62008eebc48d 100644 --- a/src/compiler/crystal/codegen/primitives.cr +++ b/src/compiler/crystal/codegen/primitives.cr @@ -1133,10 +1133,11 @@ class Crystal::CodeGenVisitor def codegen_primitive_cmpxchg(call, node, target_def, call_args) call = check_atomic_call(call, target_def) - success_ordering = atomic_ordering_from_symbol_literal(call.args[-2]) - failure_ordering = atomic_ordering_from_symbol_literal(call.args[-1]) + ptr, cmp, new, success_ordering, failure_ordering = call_args + + success_ordering = atomic_ordering_get_const(call.args[-2], success_ordering) + failure_ordering = atomic_ordering_get_const(call.args[-1], failure_ordering) - ptr, cmp, new, _, _ = call_args value = builder.cmpxchg(ptr, cmp, new, success_ordering, failure_ordering) value_ptr = alloca llvm_type(node.type) store extract_value(value, 0), gep(value_ptr, 0, 0) @@ -1146,17 +1147,20 @@ class Crystal::CodeGenVisitor def codegen_primitive_atomicrmw(call, node, target_def, call_args) call = check_atomic_call(call, target_def) - op = atomicrwm_bin_op_from_symbol_literal(call.args[0]) - ordering = atomic_ordering_from_symbol_literal(call.args[-2]) + op, ptr, val, ordering, _ = call_args + + op = atomicrwm_bin_op_get_const(call.args[0], op) + ordering = atomic_ordering_get_const(call.args[-2], ordering) singlethread = bool_from_bool_literal(call.args[-1]) - _, ptr, val, _, _ = call_args builder.atomicrmw(op, ptr, val, ordering, singlethread) end def codegen_primitive_fence(call, node, target_def, call_args) call = check_atomic_call(call, target_def) - ordering = atomic_ordering_from_symbol_literal(call.args[0]) + ordering, _ = call_args + + ordering = atomic_ordering_get_const(call.args[0], ordering) singlethread = bool_from_bool_literal(call.args[1]) builder.fence(ordering, singlethread) @@ -1165,10 +1169,10 @@ class Crystal::CodeGenVisitor def codegen_primitive_load_atomic(call, node, target_def, call_args) call = check_atomic_call(call, target_def) - ordering = atomic_ordering_from_symbol_literal(call.args[-2]) - volatile = bool_from_bool_literal(call.args[-1]) + ptr, ordering, _ = call_args - ptr, _, _ = call_args + ordering = atomic_ordering_get_const(call.args[-2], ordering) + volatile = bool_from_bool_literal(call.args[-1]) inst = builder.load(ptr) inst.ordering = ordering @@ -1179,10 +1183,10 @@ class Crystal::CodeGenVisitor def codegen_primitive_store_atomic(call, node, target_def, call_args) call = check_atomic_call(call, target_def) - ordering = atomic_ordering_from_symbol_literal(call.args[-2]) - volatile = bool_from_bool_literal(call.args[-1]) + ptr, value, ordering, _ = call_args - ptr, value, _, _ = call_args + ordering = atomic_ordering_get_const(call.args[-2], ordering) + volatile = bool_from_bool_literal(call.args[-1]) inst = builder.store(value, ptr) inst.ordering = ordering @@ -1217,30 +1221,39 @@ class Crystal::CodeGenVisitor end end - def atomic_ordering_from_symbol_literal(node) - unless node.is_a?(SymbolLiteral) - node.raise "BUG: expected symbol literal" - end + def atomic_ordering_get_const(node, llvm_arg) + node.raise "atomic ordering must be a constant" unless llvm_arg.constant? - ordering = LLVM::AtomicOrdering.parse?(node.value) - unless ordering - node.raise "unknown atomic ordering: #{node.value}" + if node.type.implements?(@program.enum) && llvm_arg.type.kind.integer? && llvm_arg.type.int_width == 32 + # any `Int32` enum will do, it is up to `Atomic::Ops` to use appropriate + # parameter restrictions so that things don't go bad + Atomic::Ordering.new(llvm_arg.const_int_get_sext_value.to_i32!) + elsif node.is_a?(SymbolLiteral) + # TODO: remove after 1.3.0 + op = Atomic::Ordering.parse?(node.value) + unless op + node.raise "unknown atomic ordering: #{node.value}" + end + op + else + node.raise "BUG: unknown atomic ordering: #{node}" end - - ordering end - def atomicrwm_bin_op_from_symbol_literal(node) - unless node.is_a?(SymbolLiteral) - node.raise "BUG: expected symbol literal" - end + def atomicrwm_bin_op_get_const(node, llvm_arg) + node.raise "atomic rwm bin op must be a constant" unless llvm_arg.constant? - op = LLVM::AtomicRMWBinOp.parse?(node.value) - unless op - node.raise "unknown atomic rwm bin op: #{node.value}" + if node.type.implements?(@program.enum) && llvm_arg.type.kind.integer? && llvm_arg.type.int_width == 32 + Atomic::RMWBinOp.new(llvm_arg.const_int_get_sext_value.to_i32!) + elsif node.is_a?(SymbolLiteral) + op = Atomic::RMWBinOp.parse?(node.value) + unless op + node.raise "unknown atomic rwm bin op: #{node.value}" + end + op + else + node.raise "BUG: unknown atomic rwm bin op: #{node}" end - - op end def bool_from_bool_literal(node) diff --git a/src/llvm/enums.cr b/src/llvm/enums.cr index 63e1c818c0e1..90d211be0452 100644 --- a/src/llvm/enums.cr +++ b/src/llvm/enums.cr @@ -361,30 +361,6 @@ module LLVM HiUser = 0xff end - enum AtomicOrdering - NotAtomic = 0 - Unordered = 1 - Monotonic = 2 - Acquire = 4 - Release = 5 - AcquireRelease = 6 - SequentiallyConsistent = 7 - end - - enum AtomicRMWBinOp - Xchg - Add - Sub - And - Nand - Or - Xor - Max - Min - UMax - UMin - end - enum DIFlags : UInt32 Zero = 0 Private = 1 diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr index f633a9cf8277..7cd41a1d9a46 100644 --- a/src/llvm/lib_llvm.cr +++ b/src/llvm/lib_llvm.cr @@ -98,7 +98,7 @@ lib LibLLVM fun build_and = LLVMBuildAnd(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_array_malloc = LLVMBuildArrayMalloc(builder : BuilderRef, type : TypeRef, val : ValueRef, name : UInt8*) : ValueRef fun build_ashr = LLVMBuildAShr(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef - fun build_atomicrmw = LLVMBuildAtomicRMW(builder : BuilderRef, op : LLVM::AtomicRMWBinOp, ptr : ValueRef, val : ValueRef, ordering : LLVM::AtomicOrdering, singlethread : Int32) : ValueRef + fun build_atomicrmw = LLVMBuildAtomicRMW(builder : BuilderRef, op : Atomic::RMWBinOp, ptr : ValueRef, val : ValueRef, ordering : Atomic::Ordering, singlethread : Int32) : ValueRef fun build_bit_cast = LLVMBuildBitCast(builder : BuilderRef, value : ValueRef, type : TypeRef, name : UInt8*) : ValueRef fun build_br = LLVMBuildBr(builder : BuilderRef, block : BasicBlockRef) : ValueRef {% if LibLLVM::IS_LT_110 %} @@ -114,7 +114,7 @@ lib LibLLVM fun build_fadd = LLVMBuildFAdd(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fcmp = LLVMBuildFCmp(builder : BuilderRef, op : LLVM::RealPredicate, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fdiv = LLVMBuildFDiv(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef - fun build_fence = LLVMBuildFence(builder : BuilderRef, ordering : LLVM::AtomicOrdering, singlethread : UInt32, name : UInt8*) : ValueRef + fun build_fence = LLVMBuildFence(builder : BuilderRef, ordering : Atomic::Ordering, singlethread : UInt32, name : UInt8*) : ValueRef fun build_fmul = LLVMBuildFMul(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fp2si = LLVMBuildFPToSI(builder : BuilderRef, val : ValueRef, dest_ty : TypeRef, name : UInt8*) : ValueRef fun build_fp2ui = LLVMBuildFPToUI(builder : BuilderRef, val : ValueRef, dest_ty : TypeRef, name : UInt8*) : ValueRef diff --git a/src/llvm/lib_llvm_ext.cr b/src/llvm/lib_llvm_ext.cr index f52bb3c0f146..16be9c225683 100644 --- a/src/llvm/lib_llvm_ext.cr +++ b/src/llvm/lib_llvm_ext.cr @@ -117,8 +117,8 @@ lib LibLLVMExt fun set_current_debug_location = LLVMExtSetCurrentDebugLocation(LibLLVM::BuilderRef, Int, Int, LibLLVM::MetadataRef, LibLLVM::MetadataRef) - fun build_cmpxchg = LLVMExtBuildCmpxchg(builder : LibLLVM::BuilderRef, pointer : LibLLVM::ValueRef, cmp : LibLLVM::ValueRef, new : LibLLVM::ValueRef, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering) : LibLLVM::ValueRef - fun set_ordering = LLVMExtSetOrdering(value : LibLLVM::ValueRef, ordering : LLVM::AtomicOrdering) + fun build_cmpxchg = LLVMExtBuildCmpxchg(builder : LibLLVM::BuilderRef, pointer : LibLLVM::ValueRef, cmp : LibLLVM::ValueRef, new : LibLLVM::ValueRef, success_ordering : Atomic::Ordering, failure_ordering : Atomic::Ordering) : LibLLVM::ValueRef + fun set_ordering = LLVMExtSetOrdering(value : LibLLVM::ValueRef, ordering : Atomic::Ordering) fun build_catch_pad = LLVMExtBuildCatchPad(builder : LibLLVM::BuilderRef, parent_pad : LibLLVM::ValueRef, From 0b0202518374ea74a9d8f48a706d53ae769e3499 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Thu, 16 Dec 2021 19:51:39 +0800 Subject: [PATCH 2/4] keep enums in `LLVM` --- src/atomic.cr | 42 ++++------------------ src/compiler/crystal/codegen/primitives.cr | 8 ++--- src/llvm/enums.cr | 2 ++ src/llvm/enums/atomic.cr | 27 ++++++++++++++ src/llvm/lib_llvm.cr | 4 +-- src/llvm/lib_llvm_ext.cr | 4 +-- 6 files changed, 44 insertions(+), 43 deletions(-) create mode 100644 src/llvm/enums/atomic.cr diff --git a/src/atomic.cr b/src/atomic.cr index 9fa4d92eaa6b..99d2febaf941 100644 --- a/src/atomic.cr +++ b/src/atomic.cr @@ -1,3 +1,5 @@ +require "llvm/enums/atomic" + # A value that may be updated atomically. # # Only primitive integer types, reference types or nilable reference types @@ -197,58 +199,28 @@ struct Atomic(T) @value end - # :nodoc: - # this enum should match `LLVMAtomicOrdering`'s definition - enum Ordering - NotAtomic = 0 - Unordered = 1 - Monotonic = 2 - Acquire = 4 - Release = 5 - AcquireRelease = 6 - SequentiallyConsistent = 7 - end - - # :nodoc: - # this enum should match `LLVMAtomicRMWBinOp`'s definition - enum RMWBinOp - Xchg - Add - Sub - And - Nand - Or - Xor - Max - Min - Umax - Umin - Fadd - Fsub - end - # :nodoc: module Ops # Defines methods that directly map to LLVM instructions related to atomic operations. @[Primitive(:cmpxchg)] - def self.cmpxchg(ptr : T*, cmp : T, new : T, success_ordering : Ordering, failure_ordering : Ordering) : {T, Bool} forall T + def self.cmpxchg(ptr : T*, cmp : T, new : T, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering) : {T, Bool} forall T end @[Primitive(:atomicrmw)] - def self.atomicrmw(op : RMWBinOp, ptr : T*, val : T, ordering : Ordering, singlethread : Bool) : T forall T + def self.atomicrmw(op : LLVM::AtomicRMWBinOp, ptr : T*, val : T, ordering : LLVM::AtomicOrdering, singlethread : Bool) : T forall T end @[Primitive(:fence)] - def self.fence(ordering : Ordering, singlethread : Bool) : Nil + def self.fence(ordering : LLVM::AtomicOrdering, singlethread : Bool) : Nil end @[Primitive(:load_atomic)] - def self.load(ptr : T*, ordering : Ordering, volatile : Bool) : T forall T + def self.load(ptr : T*, ordering : LLVM::AtomicOrdering, volatile : Bool) : T forall T end @[Primitive(:store_atomic)] - def self.store(ptr : T*, value : T, ordering : Ordering, volatile : Bool) : Nil forall T + def self.store(ptr : T*, value : T, ordering : LLVM::AtomicOrdering, volatile : Bool) : Nil forall T end end end diff --git a/src/compiler/crystal/codegen/primitives.cr b/src/compiler/crystal/codegen/primitives.cr index 62008eebc48d..e15ec9e7cb6d 100644 --- a/src/compiler/crystal/codegen/primitives.cr +++ b/src/compiler/crystal/codegen/primitives.cr @@ -1227,10 +1227,10 @@ class Crystal::CodeGenVisitor if node.type.implements?(@program.enum) && llvm_arg.type.kind.integer? && llvm_arg.type.int_width == 32 # any `Int32` enum will do, it is up to `Atomic::Ops` to use appropriate # parameter restrictions so that things don't go bad - Atomic::Ordering.new(llvm_arg.const_int_get_sext_value.to_i32!) + LLVM::AtomicOrdering.new(llvm_arg.const_int_get_sext_value.to_i32!) elsif node.is_a?(SymbolLiteral) # TODO: remove after 1.3.0 - op = Atomic::Ordering.parse?(node.value) + op = LLVM::AtomicOrdering.parse?(node.value) unless op node.raise "unknown atomic ordering: #{node.value}" end @@ -1244,9 +1244,9 @@ class Crystal::CodeGenVisitor node.raise "atomic rwm bin op must be a constant" unless llvm_arg.constant? if node.type.implements?(@program.enum) && llvm_arg.type.kind.integer? && llvm_arg.type.int_width == 32 - Atomic::RMWBinOp.new(llvm_arg.const_int_get_sext_value.to_i32!) + LLVM::AtomicRMWBinOp.new(llvm_arg.const_int_get_sext_value.to_i32!) elsif node.is_a?(SymbolLiteral) - op = Atomic::RMWBinOp.parse?(node.value) + op = LLVM::AtomicRMWBinOp.parse?(node.value) unless op node.raise "unknown atomic rwm bin op: #{node.value}" end diff --git a/src/llvm/enums.cr b/src/llvm/enums.cr index 90d211be0452..2cc3fdb5733d 100644 --- a/src/llvm/enums.cr +++ b/src/llvm/enums.cr @@ -467,3 +467,5 @@ module LLVM end end end + +require "./enums/*" diff --git a/src/llvm/enums/atomic.cr b/src/llvm/enums/atomic.cr new file mode 100644 index 000000000000..03a690d01d90 --- /dev/null +++ b/src/llvm/enums/atomic.cr @@ -0,0 +1,27 @@ +module LLVM + enum AtomicOrdering + NotAtomic = 0 + Unordered = 1 + Monotonic = 2 + Acquire = 4 + Release = 5 + AcquireRelease = 6 + SequentiallyConsistent = 7 + end + + enum AtomicRMWBinOp + Xchg + Add + Sub + And + Nand + Or + Xor + Max + Min + Umax + Umin + Fadd + Fsub + end +end diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr index 7cd41a1d9a46..f633a9cf8277 100644 --- a/src/llvm/lib_llvm.cr +++ b/src/llvm/lib_llvm.cr @@ -98,7 +98,7 @@ lib LibLLVM fun build_and = LLVMBuildAnd(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_array_malloc = LLVMBuildArrayMalloc(builder : BuilderRef, type : TypeRef, val : ValueRef, name : UInt8*) : ValueRef fun build_ashr = LLVMBuildAShr(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef - fun build_atomicrmw = LLVMBuildAtomicRMW(builder : BuilderRef, op : Atomic::RMWBinOp, ptr : ValueRef, val : ValueRef, ordering : Atomic::Ordering, singlethread : Int32) : ValueRef + fun build_atomicrmw = LLVMBuildAtomicRMW(builder : BuilderRef, op : LLVM::AtomicRMWBinOp, ptr : ValueRef, val : ValueRef, ordering : LLVM::AtomicOrdering, singlethread : Int32) : ValueRef fun build_bit_cast = LLVMBuildBitCast(builder : BuilderRef, value : ValueRef, type : TypeRef, name : UInt8*) : ValueRef fun build_br = LLVMBuildBr(builder : BuilderRef, block : BasicBlockRef) : ValueRef {% if LibLLVM::IS_LT_110 %} @@ -114,7 +114,7 @@ lib LibLLVM fun build_fadd = LLVMBuildFAdd(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fcmp = LLVMBuildFCmp(builder : BuilderRef, op : LLVM::RealPredicate, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fdiv = LLVMBuildFDiv(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef - fun build_fence = LLVMBuildFence(builder : BuilderRef, ordering : Atomic::Ordering, singlethread : UInt32, name : UInt8*) : ValueRef + fun build_fence = LLVMBuildFence(builder : BuilderRef, ordering : LLVM::AtomicOrdering, singlethread : UInt32, name : UInt8*) : ValueRef fun build_fmul = LLVMBuildFMul(builder : BuilderRef, lhs : ValueRef, rhs : ValueRef, name : UInt8*) : ValueRef fun build_fp2si = LLVMBuildFPToSI(builder : BuilderRef, val : ValueRef, dest_ty : TypeRef, name : UInt8*) : ValueRef fun build_fp2ui = LLVMBuildFPToUI(builder : BuilderRef, val : ValueRef, dest_ty : TypeRef, name : UInt8*) : ValueRef diff --git a/src/llvm/lib_llvm_ext.cr b/src/llvm/lib_llvm_ext.cr index 16be9c225683..f52bb3c0f146 100644 --- a/src/llvm/lib_llvm_ext.cr +++ b/src/llvm/lib_llvm_ext.cr @@ -117,8 +117,8 @@ lib LibLLVMExt fun set_current_debug_location = LLVMExtSetCurrentDebugLocation(LibLLVM::BuilderRef, Int, Int, LibLLVM::MetadataRef, LibLLVM::MetadataRef) - fun build_cmpxchg = LLVMExtBuildCmpxchg(builder : LibLLVM::BuilderRef, pointer : LibLLVM::ValueRef, cmp : LibLLVM::ValueRef, new : LibLLVM::ValueRef, success_ordering : Atomic::Ordering, failure_ordering : Atomic::Ordering) : LibLLVM::ValueRef - fun set_ordering = LLVMExtSetOrdering(value : LibLLVM::ValueRef, ordering : Atomic::Ordering) + fun build_cmpxchg = LLVMExtBuildCmpxchg(builder : LibLLVM::BuilderRef, pointer : LibLLVM::ValueRef, cmp : LibLLVM::ValueRef, new : LibLLVM::ValueRef, success_ordering : LLVM::AtomicOrdering, failure_ordering : LLVM::AtomicOrdering) : LibLLVM::ValueRef + fun set_ordering = LLVMExtSetOrdering(value : LibLLVM::ValueRef, ordering : LLVM::AtomicOrdering) fun build_catch_pad = LLVMExtBuildCatchPad(builder : LibLLVM::BuilderRef, parent_pad : LibLLVM::ValueRef, From a789c5492a68d75c9669c0cc3ca93cf17aecdc77 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Thu, 24 Mar 2022 21:33:29 +0800 Subject: [PATCH 3/4] fixup --- spec/compiler/codegen/primitives_spec.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/compiler/codegen/primitives_spec.cr b/spec/compiler/codegen/primitives_spec.cr index a69ed06c47a6..81fb00bef733 100644 --- a/spec/compiler/codegen/primitives_spec.cr +++ b/spec/compiler/codegen/primitives_spec.cr @@ -351,7 +351,7 @@ describe "Code gen: primitives" do CR end - # TODO: remove after 1.3.0 + # TODO: remove after 1.5.0 it "codegens atomicrmw with symbols" do run(<<-CR).to_i.should eq(3) @[Primitive(:atomicrmw)] From fb66e44a356cd9a52c4a5070571a22251af6c328 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Tue, 3 May 2022 21:19:26 +0800 Subject: [PATCH 4/4] fixup --- spec/compiler/codegen/primitives_spec.cr | 2 +- src/compiler/crystal/codegen/primitives.cr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/compiler/codegen/primitives_spec.cr b/spec/compiler/codegen/primitives_spec.cr index 81fb00bef733..442228eabfa7 100644 --- a/spec/compiler/codegen/primitives_spec.cr +++ b/spec/compiler/codegen/primitives_spec.cr @@ -351,7 +351,7 @@ describe "Code gen: primitives" do CR end - # TODO: remove after 1.5.0 + # TODO: remove once support for 1.4 is dropped it "codegens atomicrmw with symbols" do run(<<-CR).to_i.should eq(3) @[Primitive(:atomicrmw)] diff --git a/src/compiler/crystal/codegen/primitives.cr b/src/compiler/crystal/codegen/primitives.cr index c3ad169d7516..6c726734d54e 100644 --- a/src/compiler/crystal/codegen/primitives.cr +++ b/src/compiler/crystal/codegen/primitives.cr @@ -1258,7 +1258,7 @@ class Crystal::CodeGenVisitor # parameter restrictions so that things don't go bad LLVM::AtomicOrdering.new(llvm_arg.const_int_get_sext_value.to_i32!) elsif node.is_a?(SymbolLiteral) - # TODO: remove after 1.3.0 + # TODO: remove once support for 1.4 is dropped op = LLVM::AtomicOrdering.parse?(node.value) unless op node.raise "unknown atomic ordering: #{node.value}"