Skip to content

Commit

Permalink
Check that the instruction has an alignment to be queried or set.
Browse files Browse the repository at this point in the history
  • Loading branch information
nlewycky committed Aug 28, 2019
1 parent 95555f2 commit 3464374
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
20 changes: 16 additions & 4 deletions src/values/instruction_value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use either::{Either, Either::{Left, Right}};
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate};
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};
#[llvm_versions(3.9..=latest)]
use llvm_sys::core::LLVMInstructionRemoveFromParent;
use llvm_sys::LLVMOpcode;
Expand Down Expand Up @@ -200,9 +200,15 @@ impl InstructionValue {

// SubTypes: Only apply to memory access and alloca instructions
/// Returns alignment on a memory access instruction or alloca.
pub fn get_alignment(&self) -> u32 {
pub fn get_alignment(&self) -> Result<u32, &'static str> {
let value_ref = self.as_value_ref();
unsafe {
LLVMGetAlignment(self.as_value_ref())
if LLVMIsAAllocaInst(value_ref).is_null() &&
LLVMIsALoadInst(value_ref).is_null() &&
LLVMIsAStoreInst(value_ref).is_null() {
return Err("Value is not an alloca, load or store.");
}
Ok(LLVMGetAlignment(value_ref))
}
}

Expand All @@ -212,8 +218,14 @@ impl InstructionValue {
if !alignment.is_power_of_two() && alignment != 0 {
return Err("Alignment is not a power of 2!");
}
let value_ref = self.as_value_ref();
unsafe {
Ok(LLVMSetAlignment(self.as_value_ref(), alignment))
if LLVMIsAAllocaInst(value_ref).is_null() &&
LLVMIsALoadInst(value_ref).is_null() &&
LLVMIsAStoreInst(value_ref).is_null() {
return Err("Value is not an alloca, load or store.");
}
Ok(LLVMSetAlignment(value_ref, alignment))
}
}

Expand Down
21 changes: 13 additions & 8 deletions tests/all/test_instruction_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ fn test_mem_instructions() {
let f32_val = f32_type.const_float(::std::f64::consts::PI);

let store_instruction = builder.build_store(arg1, f32_val);
let load_instruction = builder.build_load(arg1, "").as_instruction_value().unwrap();
let load = builder.build_load(arg1, "");
let load_instruction = load.as_instruction_value().unwrap();

assert_eq!(store_instruction.get_volatile(), false);
assert_eq!(load_instruction.get_volatile(), false);
Expand All @@ -289,17 +290,21 @@ fn test_mem_instructions() {
assert_eq!(store_instruction.get_volatile(), false);
assert_eq!(load_instruction.get_volatile(), false);

assert_eq!(store_instruction.get_alignment(), 0);
assert_eq!(load_instruction.get_alignment(), 0);
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
assert_eq!(load_instruction.get_alignment().unwrap(), 0);
assert!(store_instruction.set_alignment(16).is_ok());
assert!(load_instruction.set_alignment(16).is_ok());
assert_eq!(store_instruction.get_alignment(), 16);
assert_eq!(load_instruction.get_alignment(), 16);
assert_eq!(store_instruction.get_alignment().unwrap(), 16);
assert_eq!(load_instruction.get_alignment().unwrap(), 16);
assert!(store_instruction.set_alignment(0).is_ok());
assert!(load_instruction.set_alignment(0).is_ok());
assert_eq!(store_instruction.get_alignment(), 0);
assert_eq!(load_instruction.get_alignment(), 0);
assert_eq!(store_instruction.get_alignment().unwrap(), 0);
assert_eq!(load_instruction.get_alignment().unwrap(), 0);

assert!(store_instruction.set_alignment(14).is_err());
assert_eq!(store_instruction.get_alignment(), 0);
assert_eq!(store_instruction.get_alignment().unwrap(), 0);

let fadd_instruction = builder.build_float_add(load.into_float_value(), f32_val, "").as_instruction_value().unwrap();
assert!(fadd_instruction.get_alignment().is_err());
assert!(fadd_instruction.set_alignment(16).is_err());
}

0 comments on commit 3464374

Please sign in to comment.