llvm_lib/core/values/constants/
expressions.rs

1//! Functions in this group operate on constants expressions.
2//!
3//! This module provides a set of functions and methods for operating on constants expressions
4//! within the LLVM framework.
5//!
6//! The functions in this module allow for various operations and manipulations of constant
7//! values, such as obtaining the alignment or size of a type, performing arithmetic
8//! operations, and creating constant expressions. These operations are essential for
9//! low-level programming tasks that require precise control over memory layout and
10//! arithmetic behavior.
11//!
12//! The module includes:
13//!
14//! - **Opcode Retrieval**: Functions to get the opcode of a constant expression.
15//! - **Type Information**: Functions to obtain the alignment and size of a type.
16//! - **Arithmetic Operations**: Functions to perform negation, addition, subtraction, multiplication, and other arithmetic operations on constant values, with support for `NSW` (No Signed Wrap) and `NUW` (No Unsigned Wrap) flags.
17//! - **Logical Operations**: Functions to perform logical NOT and XOR operations on constant values.
18//! - **Comparison Operations**: Functions to perform integer and floating-point comparisons on constant values.
19//! - **Bitwise Operations**: Functions to perform bitwise operations such as left shift and bit-cast on constant values.
20//! - **Pointer Operations**: Functions to convert between pointers and integers, and to perform address space casts.
21//! - **Vector Operations**: Functions to extract and insert elements in vector constants, and to create shuffle vector operations.
22//! - **Block Addressing**: Functions to obtain the address of a basic block in a function.
23//!
24//! These functions wrap the corresponding LLVM core library functions, providing a safe and idiomatic Rust interface for interacting with LLVM constants.
25
26use super::ValueRef;
27use crate::basic_block::BasicBlockRef;
28use crate::core::types::TypeRef;
29use crate::core::Opcode;
30use crate::{CUint, GetRef};
31use llvm_sys::core;
32
33/// Get the opcode for a constant value.
34///
35/// # Details
36///
37/// Retrieves the opcode of a constant expression.
38///
39/// This function wraps the `LLVMGetConstOpcode` function from the LLVM core library, which returns
40/// the opcode (operation code) for a constant expression. The opcode indicates the specific
41/// operation that the constant expression represents, such as addition, multiplication, etc.
42///
43/// # Returns
44///
45/// Returns an `Opcode` enum value that represents the opcode of the constant expression. The
46/// `Opcode` enum provides a Rust-friendly abstraction over the raw opcode value returned by
47/// LLVM.
48#[must_use]
49pub fn get_const_opcode(val: &ValueRef) -> Opcode {
50    unsafe { Opcode::from(core::LLVMGetConstOpcode(val.get_ref())) }
51}
52
53/// Obtain the alignment of the specified type.
54///
55/// # Details
56///
57/// Creates a new constant integer value representing the alignment, in bytes, of a given type.
58///
59/// This function wraps the `LLVMAlignOf` function from the LLVM core library, which returns the alignment
60/// of the provided type in bytes as a constant integer value. Alignment is the byte boundary
61/// that the type must adhere to in memory, and understanding it is important for certain
62/// low-level operations.
63///
64/// # Arguments
65///
66/// * `ty` - A reference to the `TypeRef` representing the type whose alignment is being queried.
67///
68/// # Returns
69///
70/// Returns a new constant integer value representing the alignment of the specified type in bytes.
71#[must_use]
72pub fn align_of(ty: &TypeRef) -> ValueRef {
73    unsafe { ValueRef(core::LLVMAlignOf(ty.get_ref())) }
74}
75
76/// Obtain the size of the specified type.
77///
78/// # Details
79///
80/// Creates a new constant integer value representing the size, in bytes, of a given type.
81///
82/// This function wraps the `LLVMSizeOf` function from the LLVM core library, which returns the size
83/// of the provided type in bytes as a constant integer value. This can be useful for operations
84/// that require knowledge of the memory footprint of a particular type.
85///
86/// # Arguments
87///
88/// * `ty` - A reference to the [`TypeRef`] representing the type whose size is being queried.
89///
90/// # Returns
91///
92/// Returns a new constant integer value representing the size of the specified type in bytes.
93#[must_use]
94pub fn size_of(ty: &TypeRef) -> ValueRef {
95    unsafe { ValueRef(core::LLVMSizeOf(ty.get_ref())) }
96}
97
98/// Create a negation operation on a constant value.
99///
100/// # Details
101///
102/// Creates a new constant integer value representing the arithmetic negation
103/// of the original value.
104///
105/// This function wraps the `LLVMConstNeg` function from the LLVM core library, which
106/// computes the negation of the given constant value [`ValueRef`].
107///
108/// # Returns
109///
110/// Returns a new constant integer value representing the result of the negation
111/// operation [`ValueRef`].
112#[must_use]
113pub fn const_neg(val: &ValueRef) -> ValueRef {
114    unsafe { ValueRef(core::LLVMConstNeg(val.get_ref())) }
115}
116
117/// Create a `NSW` negation operation on a constant value.
118///
119/// # Details
120///
121/// Creates a new constant integer value representing the arithmetic negation
122/// of the original value with the `nsw` (No Signed Wrap) flag set.
123///
124/// The `nsw` flag indicates that signed overflow is not allowed, and if it occurs,
125/// the program's behavior will be undefined. This allows LLVM to optimize the code
126/// under the assumption that overflow does not happen.
127///
128/// # Returns
129///
130/// Returns a new constant integer value representing the result of the negation
131/// operation [`ValueRef`] with the `nsw` flag set.
132#[must_use]
133pub fn const_nsw_neg(val: &ValueRef) -> ValueRef {
134    unsafe { ValueRef(core::LLVMConstNSWNeg(val.get_ref())) }
135}
136
137/// Create a logical NOT operation on a constant value.
138///
139/// # Details
140///
141/// Creates a new constant integer value representing the bitwise negation (NOT) of the original value.
142///
143/// This function wraps the `LLVMConstNot` function from the LLVM core library, which computes the bitwise
144/// complement of the given constant integer value (`~ValueRef`). The result is a new constant where each
145/// bit of the original value is inverted (i.e., `0` becomes `1` and `1` becomes `0`).
146///
147/// # Returns
148///
149/// Returns a new constant integer value representing the result of the bitwise NOT operation (`~ValueRef`).
150#[must_use]
151pub fn const_not(val: &ValueRef) -> ValueRef {
152    unsafe { ValueRef(core::LLVMConstNot(val.get_ref())) }
153}
154
155/// Create an addition operation on two constant values.
156///
157/// # Details
158///
159/// Creates a new constant integer value representing the addition of two constant integer values.
160///
161/// This function wraps the `LLVMConstAdd` function from the LLVM core library, which performs the addition
162/// of two constant integer values and returns the result as a new constant value.
163///
164/// # Arguments
165///
166/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
167/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
168///
169/// # Returns
170///
171/// Returns a new constant integer value representing the sum of `lhs` and `rhs`.
172#[must_use]
173pub fn const_add(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
174    unsafe { ValueRef(core::LLVMConstAdd(lhs.get_ref(), rhs.get_ref())) }
175}
176
177/// Create a NSW (No Signed Wrap) addition operation on two constant values.
178///
179/// # Details
180///
181/// Creates a new constant integer value representing the addition of two constant integer values,
182/// with the `nsw` (No Signed Wrap) flag set.
183///
184/// This function wraps the `LLVMConstNSWAdd` function from the LLVM core library, which performs the addition
185/// of two constant integer values and returns the result as a new constant value. The `nsw` flag
186/// indicates that signed overflow is not allowed, and if it occurs, the program's behavior will be undefined.
187/// This allows LLVM to optimize the code under the assumption that overflow does not happen.
188///
189/// # Arguments
190///
191/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
192/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
193///
194/// # Returns
195///
196/// Returns a new constant integer value representing the sum of `lhs` and `rhs` with the `nsw` flag set.
197#[must_use]
198pub fn const_nsw_add(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
199    unsafe { ValueRef(core::LLVMConstNSWAdd(lhs.get_ref(), rhs.get_ref())) }
200}
201
202/// Create a NUW (No Unsigned Wrap) addition operation on two constant values.
203///
204/// # Details
205///
206/// Creates a new constant integer value representing the addition of two constant integer values,
207/// with the `nuw` (No Unsigned Wrap) flag set.
208///
209/// This function wraps the `LLVMConstNUWAdd` function from the LLVM core library, which performs the addition
210/// of two constant integer values and returns the result as a new constant value. The `nuw` flag
211/// indicates that unsigned overflow is not allowed, and if it occurs, the program's behavior will be undefined.
212/// This allows LLVM to optimize the code under the assumption that overflow does not happen.
213///
214/// # Arguments
215///
216/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
217/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
218///
219/// # Returns
220///
221/// Returns a new constant integer value representing the sum of `lhs` and `rhs` with the `nuw` flag set.
222#[must_use]
223pub fn const_nuw_add(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
224    unsafe { ValueRef(core::LLVMConstNUWAdd(lhs.get_ref(), rhs.get_ref())) }
225}
226
227/// Create a subtraction operation on two constant values.
228///
229/// # Details
230///
231/// Creates a new constant integer value representing the subtraction of two constant integer values.
232///
233/// This function wraps the `LLVMConstSub` function from the LLVM core library, which performs the subtraction
234/// of the right-hand side (RHS) constant integer value from the left-hand side (LHS) constant integer value
235/// and returns the result as a new constant value.
236///
237/// # Arguments
238///
239/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
240/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
241///
242/// # Returns
243///
244/// Returns a new constant integer value representing the result of subtracting `rhs` from `lhs`.
245#[must_use]
246pub fn const_sub(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
247    unsafe { ValueRef(core::LLVMConstSub(lhs.get_ref(), rhs.get_ref())) }
248}
249
250/// Create a NSW (No Signed Wrap) subtraction operation on two constant values.
251///
252/// # Details
253///
254/// Creates a new constant integer value representing the subtraction of two constant integer values,
255/// with the `nsw` (No Signed Wrap) flag set.
256///
257/// This function wraps the `LLVMConstNSWSub` function from the LLVM core library, which performs the subtraction
258/// of the right-hand side (RHS) constant integer value from the left-hand side (LHS) constant integer value
259/// and returns the result as a new constant value. The `nsw` flag indicates that signed overflow is not allowed,
260/// and if it occurs, the program's behavior will be undefined. This allows LLVM to optimize the code under the
261/// assumption that overflow does not happen during the subtraction.
262///
263/// # Arguments
264///
265/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
266/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
267///
268/// # Returns
269///
270/// Returns a new constant integer value representing the result of subtracting `rhs` from `lhs` with the `nsw` flag set.
271#[must_use]
272pub fn const_nsw_sub(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
273    unsafe { ValueRef(core::LLVMConstNSWSub(lhs.0, rhs.0)) }
274}
275
276/// Create a NUW (No Unsigned Wrap) subtraction operation on two constant values.
277///
278/// # Details
279///
280/// Creates a new constant integer value representing the subtraction of two constant integer values,
281/// with the `nuw` (No Unsigned Wrap) flag set.
282///
283/// This function wraps the `LLVMConstNUWSub` function from the LLVM core library, which performs the subtraction
284/// of the right-hand side (RHS) constant integer value from the left-hand side (LHS) constant integer value
285/// and returns the result as a new constant value. The `nuw` flag indicates that unsigned overflow is not allowed,
286/// and if it occurs, the program's behavior will be undefined. This allows LLVM to optimize the code under the
287/// assumption that overflow does not happen during the subtraction.
288///
289/// # Arguments
290///
291/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
292/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
293///
294/// # Returns
295///
296/// Returns a new constant integer value representing the result of subtracting `rhs` from `lhs` with the `nuw` flag set.
297#[must_use]
298pub fn const_nuw_sub(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
299    unsafe { ValueRef(core::LLVMConstNUWSub(lhs.0, rhs.0)) }
300}
301
302/// Create a multiplication operation on two constant values.
303///
304/// # Details
305///
306/// Creates a new constant integer value representing the multiplication of two constant integer values.
307///
308/// This function wraps the `LLVMConstMul` function from the LLVM core library, which performs the multiplication
309/// of two constant integer values and returns the result as a new constant value.
310///
311/// # Arguments
312///
313/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
314/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
315///
316/// # Returns
317///
318/// Returns a new constant integer value representing the product of `lhs` and `rhs`.
319#[must_use]
320pub fn const_mul(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
321    unsafe { ValueRef(core::LLVMConstMul(lhs.0, rhs.0)) }
322}
323
324/// Create a NSW (No Signed Wrap) multiplication operation on two constant values.
325///
326/// # Details
327///
328/// Creates a new constant integer value representing the multiplication of two constant integer values,
329/// with the `nsw` (No Signed Wrap) flag set.
330///
331/// This function wraps the `LLVMConstNSWMul` function from the LLVM core library, which performs the multiplication
332/// of two constant integer values and returns the result as a new constant value. The `nsw` flag indicates that
333/// signed overflow is not allowed, and if it occurs, the program's behavior will be undefined. This allows LLVM
334/// to optimize the code under the assumption that overflow does not happen during the multiplication.
335///
336/// # Arguments
337///
338/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
339/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
340///
341/// # Returns
342///
343/// Returns a new constant integer value representing the product of `lhs` and `rhs` with the `nsw` flag set.
344#[must_use]
345pub fn const_nsw_mul(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
346    unsafe { ValueRef(core::LLVMConstNSWMul(lhs.0, rhs.0)) }
347}
348
349/// Create a NUW (No Unsigned Wrap) multiplication operation on two constant values.
350///
351/// # Details
352///
353/// Creates a new constant integer value representing the multiplication of two constant integer values,
354/// with the `nuw` (No Unsigned Wrap) flag set.
355///
356/// This function wraps the `LLVMConstNUWMul` function from the LLVM core library, which performs the multiplication
357/// of two constant integer values and returns the result as a new constant value. The `nuw` flag indicates that
358/// unsigned overflow is not allowed, and if it occurs, the program's behavior will be undefined. This allows LLVM
359/// to optimize the code under the assumption that overflow does not happen during the multiplication.
360///
361/// # Arguments
362///
363/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
364/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
365///
366/// # Returns
367///
368/// Returns a new constant integer value representing the product of `lhs` and `rhs` with the `nuw` flag set.
369#[must_use]
370pub fn const_nuw_mul(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
371    unsafe { ValueRef(core::LLVMConstNUWMul(lhs.0, rhs.0)) }
372}
373
374/// Create a logical XOR operation on two constant values.
375///
376/// # Details
377///
378/// Creates a new constant integer value representing the bitwise XOR (exclusive OR) of two constant integer values.
379///
380/// This function wraps the `LLVMConstXor` function from the LLVM core library, which performs the bitwise XOR operation
381/// between two constant integer values and returns the result as a new constant value. The XOR operation compares
382/// each corresponding bit of the two values, setting the resulting bit to `1` if the bits differ, and to `0` if
383/// they are the same.
384///
385/// # Arguments
386///
387/// * `lhs` - A reference to the left-hand side (LHS) constant integer value.
388/// * `rhs` - A reference to the right-hand side (RHS) constant integer value.
389///
390/// # Returns
391///
392/// Returns a new constant integer value representing the result of the bitwise XOR operation between `lhs` and `rhs`.
393#[must_use]
394pub fn const_xor(lhs: &ValueRef, rhs: &ValueRef) -> ValueRef {
395    unsafe { ValueRef(core::LLVMConstXor(lhs.0, rhs.0)) }
396}
397
398/// Create a GEP (`GetElementPtr`) operation on a constant value.
399///
400/// # Details
401///
402/// Creates a constant `GetElementPtr` (GEP) instruction with an explicit type.
403///
404/// This function wraps the `LLVMConstGEP2` function from the LLVM core library. It generates a constant
405/// `GEP` instruction, which calculates the address of a sub-element of an aggregate data structure (such as
406/// arrays or structs) at compile time. The `GEP` is calculated using the base pointer `constant_val` and the
407/// specified `constant_indices`.
408///
409/// # Parameters
410///
411/// - `ty`: A reference to the type of the base pointer (`constant_val`). This specifies the type of the data structure from which the `GEP` is calculated.
412/// - `constant_val`: A reference to the base value from which the GEP is calculated. This is typically a pointer to an aggregate data structure.
413/// - `constant_indices`: A slice of references to constant values that represent the indices used in the GEP calculation.
414///
415/// # Returns
416///
417/// Returns an instance of `ValueRef`, which encapsulates the result of the `GEP` calculation. The result is a constant
418/// value determined at compile time, representing the address of the sub-element within the aggregate data structure.
419#[must_use]
420pub fn const_gep2(
421    ty: &TypeRef,
422    constant_val: &ValueRef,
423    constant_indices: &[ValueRef],
424) -> ValueRef {
425    let constant_indices_ptr = crate::to_mut_ptr!(constant_indices);
426    unsafe {
427        ValueRef(core::LLVMConstGEP2(
428            ty.get_ref(),
429            constant_val.0,
430            constant_indices_ptr,
431            *CUint::from(constant_indices.len()),
432        ))
433    }
434}
435
436/// Create an in-bounds GEP (`GetElementPtr`) operation on a constant value.
437///
438/// # Details
439///
440/// Creates a constant in-bounds `GetElementPtr` (GEP) instruction with an explicit type.
441///
442/// This function wraps the `LLVMConstInBoundsGEP2` function from the LLVM core library. It generates a constant
443/// in-bounds `GEP` instruction, which calculates the address of a sub-element of an aggregate data structure (such as
444/// arrays or structs) at compile time. The in-bounds `GEP` ensures that the resulting address is within the bounds
445/// of the allocated object, allowing for more aggressive optimizations.
446///
447/// # Parameters
448///
449/// - `ty`: A reference to the type of the base pointer (`constant_val`). This specifies the type of the data structure from which the `GEP` is calculated.
450/// - `constant_val`: A reference to the base value from which the `GEP` is calculated. This is typically a pointer to an aggregate data structure.
451/// - `constant_indices`: A slice of references to constant values that represent the indices used in the `GEP` calculation.
452///
453/// # Returns
454///
455/// Returns an instance of [`ValueRef`], which encapsulates the result of the in-bounds `GEP` calculation. The result is a constant
456/// value determined at compile time, representing the address of the sub-element within the aggregate data structure,
457/// with the guarantee that the address is within the bounds of the object.
458#[must_use]
459pub fn const_in_bounds_gep2(
460    ty: &TypeRef,
461    constant_val: &ValueRef,
462    constant_indices: &[ValueRef],
463) -> ValueRef {
464    let constant_indices_ptr = crate::to_mut_ptr!(constant_indices);
465    unsafe {
466        ValueRef(core::LLVMConstInBoundsGEP2(
467            ty.get_ref(),
468            constant_val.0,
469            constant_indices_ptr,
470            *CUint::from(constant_indices.len()),
471        ))
472    }
473}
474
475/// Truncate a constant value to the specified type.
476///
477/// # Details
478///
479/// Truncates a constant integer value to a smaller integer type.
480///
481/// This function wraps the `LLVMConstTrunc` function from the LLVM core library. It generates a constant
482/// truncation instruction, which reduces the bit width of the integer value represented by `ValueRef` to the bit width
483/// of the target type specified by `to_type`. This is typically used when you need to narrow a constant integer
484/// value to a smaller type at compile time.
485///
486/// # Parameters
487///
488/// - `to_type`: A reference to the target type (`TypeRef`) to which the integer value should be truncated. This type must have a smaller bit width than the original integer type.
489///
490/// # Returns
491///
492/// Returns an instance of `ValueRef`, which encapsulates the result of the truncation. The result is a constant value
493/// determined at compile time, representing the truncated integer value.
494#[must_use]
495pub fn const_trunc(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
496    unsafe { ValueRef(core::LLVMConstTrunc(val.get_ref(), to_type.get_ref())) }
497}
498
499/// Convert a constant pointer to an integer of the specified type.
500///
501/// # Details
502///
503/// Converts a constant pointer value to an integer of the specified type.
504///
505/// This function wraps the `LLVMConstPtrToInt` function from the LLVM core library. It generates a constant
506/// pointer-to-integer conversion, which interprets the pointer value represented by `ValueRef` as an integer of the
507/// type specified by `to_type`. This is commonly used in low-level programming to perform operations where
508/// a pointer needs to be treated as an integer at compile time.
509///
510/// # Parameters
511///
512/// - `to_type`: A reference to the target integer type (`TypeRef`) to which the pointer value should be converted. This type specifies the bit width and signedness of the resulting integer.
513///
514/// # Returns
515///
516/// Returns an instance of `ValueRef`, which encapsulates the result of the pointer-to-integer conversion. The result
517/// is a constant value determined at compile time, representing the integer interpretation of the pointer value.
518#[must_use]
519pub fn const_ptr_to_int(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
520    unsafe { ValueRef(core::LLVMConstPtrToInt(val.get_ref(), to_type.get_ref())) }
521}
522
523/// Convert a constant integer to a pointer of the specified type.
524///
525/// # Details
526///
527/// Converts a constant integer value to a pointer of the specified type.
528///
529/// This function wraps the `LLVMConstIntToPtr` function from the LLVM core library. It generates a constant
530/// integer-to-pointer conversion, which interprets the integer value represented by `ValueRef` as a pointer of the
531/// type specified by `to_type`. This is often used in low-level programming to perform operations where
532/// an integer needs to be treated as a pointer at compile time.
533///
534/// # Parameters
535///
536/// - `to_type`: A reference to the target pointer type (`TypeRef`) to which the integer value should be converted. This type specifies the type of the pointer that the integer value will be interpreted as.
537///
538/// # Returns
539///
540/// Returns an instance of `ValueRef`, which encapsulates the result of the integer-to-pointer conversion. The result
541/// is a constant value determined at compile time, representing the pointer interpretation of the integer value.
542#[must_use]
543pub fn const_int_to_ptr(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
544    unsafe { ValueRef(core::LLVMConstIntToPtr(val.get_ref(), to_type.get_ref())) }
545}
546
547/// Perform a bitcast operation on a constant value to the specified type.
548///
549/// # Details
550///
551/// Performs a constant bitcast of a value to another type without changing the bit representation.
552///
553/// This function wraps the `LLVMConstBitCast` function from the LLVM core library. It generates a constant
554/// bitcast instruction, which reinterprets the value represented by `ValueRef` as another type specified by `to_type`.
555/// The bitcast does not change the underlying bit representation of the value; it merely reinterprets it as a different type.
556/// This is typically used for converting between types of the same size, such as casting between integers and pointers or between different floating-point types.
557///
558/// # Parameters
559///
560/// - `to_type`: A reference to the target type (`TypeRef`) to which the value should be cast. This type must have the same bit width as the original type.
561///
562/// # Returns
563///
564/// Returns an instance of `ValueRef`, which encapsulates the result of the bitcast. The result is a constant value
565/// determined at compile time, representing the value reinterpreted as the target type.
566#[must_use]
567pub fn const_bit_cast(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
568    unsafe { ValueRef(core::LLVMConstBitCast(val.get_ref(), to_type.get_ref())) }
569}
570
571/// Perform an address space cast operation on a constant value to the specified type.
572///
573/// # Details
574///
575/// Casts a constant pointer value to a different address space.
576///
577/// This function wraps the `LLVMConstAddrSpaceCast` function from the LLVM core library. It generates a constant
578/// address space cast, which reinterprets the pointer value represented by `ValueRef` as a pointer in a different
579/// address space specified by `to_type`. This is commonly used in systems with multiple memory address spaces
580/// where pointers may need to be converted between them at compile time.
581///
582/// # Parameters
583///
584/// - `to_type`: A reference to the target pointer type (`TypeRef`) that specifies the new address space. The type should have the same bit width as the original pointer type but reside in a different address space.
585///
586/// # Returns
587///
588/// Returns an instance of `ValueRef`, which encapsulates the result of the address space cast. The result is a constant
589/// value determined at compile time, representing the pointer value in the new address space.
590#[must_use]
591pub fn const_addr_space_cast(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
592    unsafe {
593        ValueRef(core::LLVMConstAddrSpaceCast(
594            val.get_ref(),
595            to_type.get_ref(),
596        ))
597    }
598}
599
600/// Perform either a truncation or bitcast operation on a constant value to the specified type.
601///
602/// # Details
603///
604/// Performs a constant truncation or bitcast of a value to a specified type, depending on the target type's bit width.
605///
606/// This function wraps the `LLVMConstTruncOrBitCast` function from the LLVM core library. It either truncates the value
607/// represented by [`ValueRef`] to a smaller integer type or performs a bitcast if the target type has the same bit width.
608/// The operation performed depends on the relationship between the original type and the target type's bit width.
609///
610/// - If the target type has a smaller bit width than the original type, a truncation is performed.
611/// - If the target type has the same bit width, a bitcast is performed, reinterpreting the value as the target type without changing its bit representation.
612///
613/// # Parameters
614///
615/// - `to_type`: A reference to the target type (`TypeRef`) to which the value should be truncated or bitcast. The nature of the operation depends on the bit width of this type relative to the original type.
616///
617/// # Returns
618///
619/// Returns an instance of `ValueRef`, which encapsulates the result of the truncation or bitcast. The result is a constant
620/// value determined at compile time, representing the value either truncated to a smaller type or reinterpreted as the target type.
621#[must_use]
622pub fn const_trunc_or_bit_cast(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
623    unsafe {
624        ValueRef(core::LLVMConstTruncOrBitCast(
625            val.get_ref(),
626            to_type.get_ref(),
627        ))
628    }
629}
630
631/// Perform a pointer cast operation on a constant value to the specified type.
632///
633/// # Details
634///
635/// Casts a constant pointer value to a different pointer type without changing the address or bit representation.
636///
637/// This function wraps the `LLVMConstPointerCast` function from the LLVM core library. It generates a constant
638/// pointer cast, which reinterprets the pointer value represented by `ValueRef` as a different pointer type specified
639/// by `to_type`. The cast does not alter the underlying address or bit representation of the pointer; it simply changes
640/// the type of the pointer. This is typically used when you need to change the type of a pointer while preserving its
641/// address in memory.
642///
643/// # Parameters
644///
645/// - `to_type`: A reference to the target pointer type (`TypeRef`) to which the pointer value should be cast. The target type must be a pointer type, but it may point to a different type than the original pointer.
646///
647/// # Returns
648///
649/// Returns an instance of `ValueRef`, which encapsulates the result of the pointer cast. The result is a constant value
650/// determined at compile time, representing the pointer value reinterpreted as the new type.
651#[must_use]
652pub fn const_pointer_cast(val: &ValueRef, to_type: &TypeRef) -> ValueRef {
653    unsafe { ValueRef(core::LLVMConstPointerCast(val.get_ref(), to_type.get_ref())) }
654}
655
656/// Extract an element from a vector constant at the specified index.
657///
658/// # Details
659///
660/// Extracts a single element from a constant vector at a specified index.
661///
662/// This function wraps the `LLVMConstExtractElement` function from the LLVM core library. It generates a constant
663/// extract element instruction, which retrieves a specific element from the vector value represented by `ValueRef`
664/// at the position specified by `index`. This is commonly used when working with constant vectors, allowing you to
665/// extract a single element at compile time.
666///
667/// # Parameters
668///
669/// - `index`: A reference to a constant value that specifies the index of the element to extract. The index should be an integer value and within the bounds of the vector.
670///
671/// # Returns
672///
673/// Returns an instance of `ValueRef`, which encapsulates the extracted element as a constant value determined at compile time.
674#[must_use]
675pub fn const_extract_element(val: &ValueRef, index: &ValueRef) -> ValueRef {
676    unsafe { ValueRef(core::LLVMConstExtractElement(val.get_ref(), index.0)) }
677}
678
679/// Insert an element into a vector constant at the specified index.
680///
681/// # Details
682///
683/// Inserts a constant element into a constant vector at a specified index.
684///
685/// This function wraps the `LLVMConstInsertElement` function from the LLVM core library. It generates a constant
686/// insert element instruction, which inserts the value represented by `element_value` into the vector value
687/// represented by `ValueRef` at the position specified by `index`. This is typically used to create or modify constant
688/// vectors by inserting elements at specific positions at compile time.
689///
690/// # Parameters
691///
692/// - `element_value`: A reference to the constant value that should be inserted into the vector. This value must be of the same type as the elements of the vector.
693/// - `index`: A reference to a constant value that specifies the index at which the element should be inserted. The index should be an integer value and within the bounds of the vector.
694///
695/// # Returns
696///
697/// Returns an instance of [`ValueRef`], which encapsulates the resulting vector after the insertion, as a constant value determined at compile time.
698#[must_use]
699pub fn const_insert_element(
700    val: &ValueRef,
701    element_value: &ValueRef,
702    index: &ValueRef,
703) -> ValueRef {
704    unsafe {
705        ValueRef(core::LLVMConstInsertElement(
706            val.get_ref(),
707            element_value.0,
708            index.0,
709        ))
710    }
711}
712
713/// Create a shuffle vector operation on two vector constants.
714///
715/// # Details
716///
717/// Creates a constant shuffling of elements from two vectors according to a specified mask.
718///
719/// This function wraps the `LLVMConstShuffleVector` function from the LLVM core library. It generates a constant
720/// shuffle vector instruction, which produces a new vector by selecting elements from two input vectors, `vector_a`
721/// and `vector_b`, based on the indices specified by `mask`. The resulting vector is determined at compile time and
722/// is a permutation of elements from the original vectors according to the mask.
723///
724/// # Parameters
725///
726/// - `vector_a`: A reference to the first input vector from which elements may be selected.
727/// - `vector_b`: A reference to the second input vector from which elements may be selected.
728/// - `mask`: A reference to a constant vector that specifies the indices of elements to select from `vector_a` and `vector_b`. The mask values determine which elements from the input vectors are placed in the resulting vector.
729///
730/// # Returns
731///
732/// Returns an instance of `ValueRef`, which encapsulates the resulting shuffled vector as a constant value determined at compile time.
733#[must_use]
734pub fn const_shuffle_vector(vector_a: &ValueRef, vector_b: &ValueRef, mask: &ValueRef) -> ValueRef {
735    unsafe {
736        ValueRef(core::LLVMConstShuffleVector(
737            vector_a.get_ref(),
738            vector_b.get_ref(),
739            mask.get_ref(),
740        ))
741    }
742}
743
744/// Obtain the address of a basic block in a function.
745///
746/// # Details
747///
748/// Retrieves the address of a basic block within a specified function.
749///
750/// This function wraps the `LLVMBlockAddress` function from the LLVM core library. It generates a constant
751/// representing the address of a specific basic block within a given function. This is typically used for low-level
752/// operations such as creating labels or handling jumps within a function at compile time.
753///
754/// # Parameters
755///
756/// - `function`: A reference to the function (`ValueRef`) that contains the basic block whose address is being retrieved.
757/// - `basic_block`: A reference to the basic block (`BasicBlockRef`) within the function whose address is to be retrieved.
758///
759/// # Returns
760///
761/// Returns an instance of [`ValueRef`], which encapsulates the address of the specified basic block as a constant value determined at compile time.
762#[must_use]
763pub fn block_address(function: &ValueRef, basic_block: &BasicBlockRef) -> ValueRef {
764    unsafe { ValueRef(core::LLVMBlockAddress(function.0, basic_block.get_ref())) }
765}