@@ -4,6 +4,8 @@ use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcod
4
4
use llvm_sys:: core:: { LLVMGetOrdering , LLVMSetOrdering } ;
5
5
#[ llvm_versions( 3.9 ..=latest) ]
6
6
use llvm_sys:: core:: LLVMInstructionRemoveFromParent ;
7
+ #[ llvm_versions( 10.0 ..=latest) ]
8
+ use llvm_sys:: core:: { LLVMIsAAtomicRMWInst , LLVMIsAAtomicCmpXchgInst } ;
7
9
use llvm_sys:: LLVMOpcode ;
8
10
use llvm_sys:: prelude:: LLVMValueRef ;
9
11
@@ -113,6 +115,14 @@ impl<'ctx> InstructionValue<'ctx> {
113
115
fn is_a_alloca_inst ( self ) -> bool {
114
116
!unsafe { LLVMIsAAllocaInst ( self . as_value_ref ( ) ) } . is_null ( )
115
117
}
118
+ #[ llvm_versions( 10.0 ..=latest) ]
119
+ fn is_a_atomicrmw_inst ( self ) -> bool {
120
+ !unsafe { LLVMIsAAtomicRMWInst ( self . as_value_ref ( ) ) } . is_null ( )
121
+ }
122
+ #[ llvm_versions( 10.0 ..=latest) ]
123
+ fn is_a_cmpxchg_inst ( self ) -> bool {
124
+ !unsafe { LLVMIsAAtomicCmpXchgInst ( self . as_value_ref ( ) ) } . is_null ( )
125
+ }
116
126
117
127
pub ( crate ) fn new ( instruction_value : LLVMValueRef ) -> Self {
118
128
debug_assert ! ( !instruction_value. is_null( ) ) ;
@@ -203,25 +213,49 @@ impl<'ctx> InstructionValue<'ctx> {
203
213
204
214
// SubTypes: Only apply to memory access instructions
205
215
/// Returns whether or not a memory access instruction is volatile.
216
+ #[ llvm_versions( 3.6 ..=9.0 ) ]
206
217
pub fn get_volatile ( self ) -> Result < bool , & ' static str > {
207
218
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
208
- // does not export that functionality.
219
+ // does not export that functionality until 10.0 .
209
220
if !self . is_a_load_inst ( ) && !self . is_a_store_inst ( ) {
210
221
return Err ( "Value is not a load or store." ) ;
211
222
}
212
223
Ok ( unsafe { LLVMGetVolatile ( self . as_value_ref ( ) ) } == 1 )
213
224
}
214
225
226
+ // SubTypes: Only apply to memory access instructions
227
+ /// Returns whether or not a memory access instruction is volatile.
228
+ #[ llvm_versions( 10.0 ..=latest) ]
229
+ pub fn get_volatile ( self ) -> Result < bool , & ' static str > {
230
+ if !self . is_a_load_inst ( ) && !self . is_a_store_inst ( ) &&
231
+ !self . is_a_atomicrmw_inst ( ) && !self . is_a_cmpxchg_inst ( ) {
232
+ return Err ( "Value is not a load, store, atomicrmw or cmpxchg." ) ;
233
+ }
234
+ Ok ( unsafe { LLVMGetVolatile ( self . as_value_ref ( ) ) } == 1 )
235
+ }
236
+
215
237
// SubTypes: Only apply to memory access instructions
216
238
/// Sets whether or not a memory access instruction is volatile.
239
+ #[ llvm_versions( 3.6 ..=9.0 ) ]
217
240
pub fn set_volatile ( self , volatile : bool ) -> Result < ( ) , & ' static str > {
218
241
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
219
- // does not export that functionality.
242
+ // does not export that functionality until 10.0 .
220
243
if !self . is_a_load_inst ( ) && !self . is_a_store_inst ( ) {
221
244
return Err ( "Value is not a load or store." ) ;
222
245
}
223
246
Ok ( unsafe { LLVMSetVolatile ( self . as_value_ref ( ) , volatile as i32 ) } )
224
247
}
248
+
249
+ // SubTypes: Only apply to memory access instructions
250
+ /// Sets whether or not a memory access instruction is volatile.
251
+ #[ llvm_versions( 10.0 ..=latest) ]
252
+ pub fn set_volatile ( self , volatile : bool ) -> Result < ( ) , & ' static str > {
253
+ if !self . is_a_load_inst ( ) && !self . is_a_store_inst ( ) &&
254
+ !self . is_a_atomicrmw_inst ( ) && !self . is_a_cmpxchg_inst ( ) {
255
+ return Err ( "Value is not a load, store, atomicrmw or cmpxchg." ) ;
256
+ }
257
+ Ok ( unsafe { LLVMSetVolatile ( self . as_value_ref ( ) , volatile as i32 ) } )
258
+ }
225
259
226
260
// SubTypes: Only apply to memory access and alloca instructions
227
261
/// Returns alignment on a memory access instruction or alloca.
0 commit comments