Skip to content

Commit 3464374

Browse files
committed
Check that the instruction has an alignment to be queried or set.
1 parent 95555f2 commit 3464374

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

src/values/instruction_value.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use either::{Either, Either::{Left, Right}};
2-
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate};
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};
33
#[llvm_versions(3.9..=latest)]
44
use llvm_sys::core::LLVMInstructionRemoveFromParent;
55
use llvm_sys::LLVMOpcode;
@@ -200,9 +200,15 @@ impl InstructionValue {
200200

201201
// SubTypes: Only apply to memory access and alloca instructions
202202
/// Returns alignment on a memory access instruction or alloca.
203-
pub fn get_alignment(&self) -> u32 {
203+
pub fn get_alignment(&self) -> Result<u32, &'static str> {
204+
let value_ref = self.as_value_ref();
204205
unsafe {
205-
LLVMGetAlignment(self.as_value_ref())
206+
if LLVMIsAAllocaInst(value_ref).is_null() &&
207+
LLVMIsALoadInst(value_ref).is_null() &&
208+
LLVMIsAStoreInst(value_ref).is_null() {
209+
return Err("Value is not an alloca, load or store.");
210+
}
211+
Ok(LLVMGetAlignment(value_ref))
206212
}
207213
}
208214

@@ -212,8 +218,14 @@ impl InstructionValue {
212218
if !alignment.is_power_of_two() && alignment != 0 {
213219
return Err("Alignment is not a power of 2!");
214220
}
221+
let value_ref = self.as_value_ref();
215222
unsafe {
216-
Ok(LLVMSetAlignment(self.as_value_ref(), alignment))
223+
if LLVMIsAAllocaInst(value_ref).is_null() &&
224+
LLVMIsALoadInst(value_ref).is_null() &&
225+
LLVMIsAStoreInst(value_ref).is_null() {
226+
return Err("Value is not an alloca, load or store.");
227+
}
228+
Ok(LLVMSetAlignment(value_ref, alignment))
217229
}
218230
}
219231

tests/all/test_instruction_values.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ fn test_mem_instructions() {
276276
let f32_val = f32_type.const_float(::std::f64::consts::PI);
277277

278278
let store_instruction = builder.build_store(arg1, f32_val);
279-
let load_instruction = builder.build_load(arg1, "").as_instruction_value().unwrap();
279+
let load = builder.build_load(arg1, "");
280+
let load_instruction = load.as_instruction_value().unwrap();
280281

281282
assert_eq!(store_instruction.get_volatile(), false);
282283
assert_eq!(load_instruction.get_volatile(), false);
@@ -289,17 +290,21 @@ fn test_mem_instructions() {
289290
assert_eq!(store_instruction.get_volatile(), false);
290291
assert_eq!(load_instruction.get_volatile(), false);
291292

292-
assert_eq!(store_instruction.get_alignment(), 0);
293-
assert_eq!(load_instruction.get_alignment(), 0);
293+
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
294+
assert_eq!(load_instruction.get_alignment().unwrap(), 0);
294295
assert!(store_instruction.set_alignment(16).is_ok());
295296
assert!(load_instruction.set_alignment(16).is_ok());
296-
assert_eq!(store_instruction.get_alignment(), 16);
297-
assert_eq!(load_instruction.get_alignment(), 16);
297+
assert_eq!(store_instruction.get_alignment().unwrap(), 16);
298+
assert_eq!(load_instruction.get_alignment().unwrap(), 16);
298299
assert!(store_instruction.set_alignment(0).is_ok());
299300
assert!(load_instruction.set_alignment(0).is_ok());
300-
assert_eq!(store_instruction.get_alignment(), 0);
301-
assert_eq!(load_instruction.get_alignment(), 0);
301+
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
302+
assert_eq!(load_instruction.get_alignment().unwrap(), 0);
302303

303304
assert!(store_instruction.set_alignment(14).is_err());
304-
assert_eq!(store_instruction.get_alignment(), 0);
305+
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
306+
307+
let fadd_instruction = builder.build_float_add(load.into_float_value(), f32_val, "").as_instruction_value().unwrap();
308+
assert!(fadd_instruction.get_alignment().is_err());
309+
assert!(fadd_instruction.set_alignment(16).is_err());
305310
}

0 commit comments

Comments
 (0)