Skip to content

Commit 5a34a76

Browse files
committed
Apparently, LLVM{Get,Set}Ordering were first added to the LLVM C API in 3.8.
1 parent 76f2b92 commit 5a34a76

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

Diff for: src/values/instruction_value.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use either::{Either, Either::{Left, Right}};
2-
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetOrdering, LLVMSetOrdering, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate, LLVMIsAAllocaInst, LLVMIsALoadInst, LLVMIsAStoreInst};
2+
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate, LLVMIsAAllocaInst, LLVMIsALoadInst, LLVMIsAStoreInst};
3+
#[llvm_versions(3.8..=latest)]
4+
use llvm_sys::core::{LLVMGetOrdering, LLVMSetOrdering};
35
#[llvm_versions(3.9..=latest)]
46
use llvm_sys::core::LLVMInstructionRemoveFromParent;
57
use llvm_sys::LLVMOpcode;
@@ -237,6 +239,7 @@ impl InstructionValue {
237239

238240
// SubTypes: Only apply to memory access instructions
239241
/// Returns atomic ordering on a memory access instruction.
242+
#[llvm_versions(3.8..=latest)]
240243
pub fn get_atomic_ordering(&self) -> Result<AtomicOrdering, &'static str> {
241244
if !self.is_a_load_inst() && !self.is_a_store_inst() {
242245
return Err("Value is not a load or store.");
@@ -246,6 +249,7 @@ impl InstructionValue {
246249

247250
// SubTypes: Only apply to memory access instructions
248251
/// Sets atomic ordering on a memory access instruction.
252+
#[llvm_versions(3.8..=latest)]
249253
pub fn set_atomic_ordering(&self, ordering: AtomicOrdering) -> Result<(), &'static str> {
250254
// Although fence and atomicrmw both have an ordering, the LLVM C API
251255
// does not support them. The cmpxchg instruction has two orderings and

Diff for: tests/all/test_instruction_values.rs

+36-4
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,42 @@ fn test_mem_instructions() {
304304
assert!(store_instruction.set_alignment(14).is_err());
305305
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
306306

307+
let fadd_instruction = builder.build_float_add(load.into_float_value(), f32_val, "").as_instruction_value().unwrap();
308+
assert!(fadd_instruction.get_volatile().is_err());
309+
assert!(fadd_instruction.set_volatile(false).is_err());
310+
assert!(fadd_instruction.get_alignment().is_err());
311+
assert!(fadd_instruction.set_alignment(16).is_err());
312+
}
313+
314+
#[llvm_versions(3.8..=latest)]
315+
#[test]
316+
fn test_atomic_ordering_mem_instructions() {
317+
let context = Context::create();
318+
let module = context.create_module("testing");
319+
let builder = context.create_builder();
320+
321+
let void_type = context.void_type();
322+
let f32_type = context.f32_type();
323+
let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic);
324+
let fn_type = void_type.fn_type(&[f32_ptr_type.into(), f32_type.into()], false);
325+
326+
let function = module.add_function("mem_inst", fn_type, None);
327+
let basic_block = context.append_basic_block(&function, "entry");
328+
329+
builder.position_at_end(&basic_block);
330+
331+
let arg1 = function.get_first_param().unwrap().into_pointer_value();
332+
let arg2 = function.get_nth_param(1).unwrap().into_float_value();
333+
334+
assert!(arg1.get_first_use().is_none());
335+
assert!(arg2.get_first_use().is_none());
336+
337+
let f32_val = f32_type.const_float(::std::f64::consts::PI);
338+
339+
let store_instruction = builder.build_store(arg1, f32_val);
340+
let load = builder.build_load(arg1, "");
341+
let load_instruction = load.as_instruction_value().unwrap();
342+
307343
assert_eq!(store_instruction.get_atomic_ordering().unwrap(), AtomicOrdering::NotAtomic);
308344
assert_eq!(load_instruction.get_atomic_ordering().unwrap(), AtomicOrdering::NotAtomic);
309345
assert!(store_instruction.set_atomic_ordering(AtomicOrdering::Monotonic).is_ok());
@@ -317,10 +353,6 @@ fn test_mem_instructions() {
317353
assert!(load_instruction.set_atomic_ordering(AtomicOrdering::Release).is_err());
318354

319355
let fadd_instruction = builder.build_float_add(load.into_float_value(), f32_val, "").as_instruction_value().unwrap();
320-
assert!(fadd_instruction.get_volatile().is_err());
321-
assert!(fadd_instruction.set_volatile(false).is_err());
322-
assert!(fadd_instruction.get_alignment().is_err());
323-
assert!(fadd_instruction.set_alignment(16).is_err());
324356
assert!(fadd_instruction.get_atomic_ordering().is_err());
325357
assert!(fadd_instruction.set_atomic_ordering(AtomicOrdering::NotAtomic).is_err());
326358
}

0 commit comments

Comments
 (0)