Kaida-Amethyst/MoonLLVM/IR does not have a README file
pub trait AggregateType : Type {
asAggregateTypeEnum(Self) -> AggregateTypeEnum
getIndexedType(Self, idxs : ArrayView[Int]) -> &Type?
}pub trait FPType : PrimitiveType {
asFPTypeEnum(Self) -> FPTypeEnum
getFPMantissaWidth(Self) -> Int
}fn to_float64(self : Float) -> Doublefn to_float64(self : Double) -> Doublepub trait GlobalValue : Value {
getGlobalValueBase(Self) -> GlobalValueBase
asGlobalValueEnum(Self) -> GlobalValueEnum
getModule(Self) -> Module
getLinkage(Self) -> Linkage
setLinkage(Self, linkage : Linkage) -> Unit
setUnnamedAddr(Self, unnamed_addr : UnnamedAddr) -> Unit
}pub trait Instruction : Value {
getInstBase(Self) -> InstBase
asInstEnum(Self) -> InstEnum
getParent(Self) -> Function
getModule(Self) -> Module
getBasicBlock(Self) -> BasicBlock?
getInstName(Self) -> String?
isIndependent(Self) -> Bool
isTerminator(Self) -> Bool
next(Self) -> &Instruction?
prev(Self) -> &Instruction?
insertAfter(Self, &Instruction) -> Unit raise LLVMValueError
insertBefore(Self, &Instruction) -> Unit raise LLVMValueError
moveBefore(Self, &Instruction) -> Unit
moveAfter(Self, &Instruction) -> Unit
removeFromParent(Self) -> Unit
eraseFromParent(Self) -> Unit
}trait IntegerNumberimpl IntegerNumber for Intimpl IntegerNumber for Int16impl IntegerNumber for Int64impl IntegerNumber for UIntimpl IntegerNumber for UInt16impl IntegerNumber for UInt64impl IntegerNumber for Int8impl IntegerNumber for UInt8pub trait IntegerType : PrimitiveType {
asIntegerTypeEnum(Self) -> IntegerTypeEnum
getBitMask(Self) -> UInt64
getSignBit(Self) -> UInt64
getExtendedType(Self) -> &IntegerType?
}test {
let ctx = Context::new()
let i8ty : &IntegerType = ctx.getInt8Ty()
assert_eq(i8ty.getBitWidth(), 8)
inspect(i8ty.getExtendedType().unwrap(), content="i16")
assert_eq(i8ty.getBitMask(), 0xFF)
assert_eq(i8ty.getExtendedType().unwrap().getSignBit(), 0x8000)
let i32ty = i8ty.getExtendedType().unwrap().getExtendedType().unwrap()
inspect(i32ty, content="i32")
guard i32ty.asIntegerTypeEnum() is Int32Type(i32ty)
inspect(i32ty, content="i32")
}pub trait PrimitiveType : Type {
asPrimitiveTypeEnum(Self) -> PrimitiveTypeEnum
getBitWidth(Self) -> Int
}pub trait Type : Show + Hash {
getContext(Self) -> Context
asTypeEnum(Self) -> TypeEnum
is16bitFPTy(Self) -> Bool
isIEEELikeFPTy(Self) -> Bool
isFloatingPointTy(Self) -> Bool
isScalableTargetExtTy(Self) -> Bool
isScalableTy(Self) -> Bool
isFPOrFPVectorTy(Self) -> Bool
isIntOrIntVectorTy(Self) -> Bool
isIntOrPtrTy(Self) -> Bool
isPtrOrPtrVectorTy(Self) -> Bool
canLosslesslyBitCastTo(Self, ty : &Type) -> Bool
isEmptyTy(Self) -> Bool
isFirstClassType(Self) -> Bool
isSingleValueType(Self) -> Bool
isAggregateType(Self) -> Bool
isSized(Self) -> Bool
isValidGEPType(Self) -> Bool
getPrimitiveSizeInBits(Self) -> TypeSize
getScalarSizeInBits(Self) -> Int
getScalarType(Self) -> &Type
tryAsFPType(Self) -> &FPType?
tryAsFPTypeEnum(Self) -> FPTypeEnum?
tryAsIntType(Self) -> &IntegerType?
tryAsIntTypeEnum(Self) -> IntegerTypeEnum?
tryAsPrimitiveType(Self) -> &PrimitiveType?
tryAsPrimitiveTypeEnum(Self) -> PrimitiveTypeEnum?
tryAsAggregateType(Self) -> &AggregateType?
tryAsAggregateTypeEnum(Self) -> AggregateTypeEnum?
tryAsAbstractType(Self) -> &AbstractType?
tryAsAbstractTypeEnum(Self) -> AbstractTypeEnum?
}pub trait UnSigned : Show {
asEnum(Self) -> UnSignedEnum
convert_to_uint64(Self) -> UInt64
convert_to_int64(Self) -> Int64
}pub trait Value : Show {
getValueBase(Self) -> ValueBase
asValueEnum(Self) -> ValueEnum
getType(Self) -> &Type
getContext(Self) -> Context
addUser(Self, user : &User) -> Unit
getValueRepr(Self) -> String
getName(Self) -> String?
setName(Self, name : String) -> Unit raise LLVMValueError
removeName(Self) -> Unit raise LLVMValueError
getNameOrSlot(Self) -> Either[String, UInt64]?
getNameOrSlotStr(Self) -> String
replaceAllUsersWith(Self, other : &Value) -> Unit
getUsers(Self) -> Array[&User]?
user_empty(Self) -> Bool
tryAsConstant(Self) -> &Constant?
tryAsConstantEnum(Self) -> ConstantEnum?
tryAsUser(Self) -> &User?
tryAsUserEnum(Self) -> UserEnum?
tryAsInst(Self) -> &Instruction?
tryAsInstEnum(Self) -> InstEnum?
tryAsGlobalValue(Self) -> &GlobalValue?
tryAsGlobalValueEnum(Self) -> GlobalValueEnum?
}pub enum AbstractTypeEnum {
VoidType(VoidType)
LabelType(LabelType)
MetadataType(MetadataType)
TokenType(TokenType)
FunctionType(FunctionType)
}impl Show for AbstractTypeEnumpub type AddressSpace UIntimpl Default for AddressSpaceimpl Eq for AddressSpaceimpl Hash for AddressSpaceimpl Show for AddressSpace#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn AddressSpace::inner(self : AddressSpace) -> UIntpub enum AggregateTypeEnum {
StructType(StructType)
ArrayType(ArrayType)
VectorType(VectorType)
ScalableVectorType(ScalableVectorType)
}impl Eq for AggregateTypeEnumimpl Show for AggregateTypeEnumtype Alignpub struct AllocaInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
parent : Function
data_ty : &Type
align : Align
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "foo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let inst = builder.createAlloca(i32_ty, name="var1")
inspect(inst, content=" %var1 = alloca i32, align 4")
}impl Instruction for AllocaInstimpl UnaryInst for AllocaInstimpl Value for AllocaInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "foo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let inst = builder.createAlloca(i32_ty)
inspect(inst.getName(), content="None")
inst.setName("var1")
inspect(inst.getName(), content="Some(\"var1\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "foo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let inst = builder.createAlloca(i32_ty)
inspect(inst.getValueRepr(), content="%0")
inst.setName("var1")
inspect(inst.getValueRepr(), content="%var1")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "foo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let inst = builder.createAlloca(i32_ty)
inspect(inst.getName(), content="None")
inst.setName("var1")
inspect(inst.getName(), content="Some(\"var1\")")
}impl Show for AllocaInsttest {
let ctx = Context::new()
let prog = ctx.addModule("demo")
let i32ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32ty, [i32ty, i32ty])
let f = prog.addFunction(fty, "add")
let arg0 = f.getArg(0).unwrap()
let arg1 = f.getArg(1).unwrap()
inspect(arg0, content="i32 %0")
inspect(arg1.getType(), content="i32")
assert_true(f.getArg(2) is None)
}test {
let ctx = Context::new()
let prog = ctx.addModule("demo")
let i32ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32ty, [i32ty, i32ty])
let f = prog.addFunction(fty, "add")
let arg0 = f.getArg(0).unwrap()
let arg1 = f.getArg(1).unwrap()
assert_true(f.getArg(2) is None)
inspect(arg0, content="i32 %0")
inspect(arg1.getType(), content="i32")
arg0.setName("lhs")
arg1.setName("rhs")
inspect(arg0, content="i32 %lhs")
inspect(arg1, content="i32 %rhs")
assert_true((try! arg1.setName("lhs")) is Err(_))
}test {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let arrty = ctx.getArrayType(i32ty, 16)
inspect(arrty, content="[16 x i32]")
assert_eq(arrty.getElementCount(), 16)
inspect(arrty.getElementType(), content="i32")
}impl AggregateType for ArrayTypepub(all) enum AtomicOrdering {
NotAtomic
Unordered
Monotonic
Acquire
Release
AcquireRelease
SequentiallyConsistent
}impl Eq for AtomicOrderingimpl Hash for AtomicOrderingimpl Show for AtomicOrderingimpl FPType for BFloatTypeimpl PrimitiveType for BFloatTypeimpl Type for BFloatTypeimpl Eq for BFloatTypeimpl Hash for BFloatTypeimpl Show for BFloatTypepub struct BasicBlock {
uid : UInt64
users : Array[&User]
parent : Function
name : String?
head : &Instruction?
id : Int
preds : Array[BasicBlock]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "ret_42")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let forty_two = ctx.getConstInt32(42)
let _ = builder.createRet(forty_two)
inspect(
bb,
content=(
#|entry:
#| ret i32 42
#|
),
)
}impl InsertPoint for BasicBlockimpl Value for BasicBlockimpl Eq for BasicBlockimpl Hash for BasicBlockimpl Show for BasicBlocktest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "ret_42")
let arg0 = fval.getArg(0).unwrap()
let arg1 = fval.getArg(1).unwrap()
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let sum1 = builder.createAdd(arg0, arg1, name="sum1")
let sum2 = builder.createAdd(arg0, arg1, name="sum2")
let mul = builder.createMul(sum1, sum2, name="mul")
let _ = builder.createRet(mul)
inspect(bb.firstInst().unwrap(), content=" %sum1 = add i32 %0, %1")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "ret_42")
let arg0 = fval.getArg(0).unwrap()
let arg1 = fval.getArg(1).unwrap()
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let sum1 = builder.createAdd(arg0, arg1, name="sum1")
let sum2 = builder.createAdd(arg0, arg1, name="sum2")
let mul = builder.createMul(sum1, sum2, name="mul")
let _ = builder.createRet(mul)
inspect(bb.lastInst().unwrap(), content=" ret i32 %mul")
}pub struct BinaryInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
lhs : &Value
rhs : &Value
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
opcode : BinaryOps
flags : Set[BinaryOpFlags]
fast_math_flags : Set[FastMathFlag]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "binary_ops_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createAdd(arg1, arg2, name="sum")
inspect(add, content=" %sum = add i32 %0, %1")
assert_true(add.asValueEnum() is BinaryInst(_))
let sub = builder.createSub(arg1, arg2, name="diff")
inspect(sub, content=" %diff = sub i32 %0, %1")
let mul = builder.createMul(arg1, arg2, name="product")
inspect(mul, content=" %product = mul i32 %0, %1")
let and_result = builder.createAnd(arg1, arg2, name="and_result")
inspect(and_result, content=" %and_result = and i32 %0, %1")
let or_result = builder.createOr(arg1, arg2, name="or_result")
inspect(or_result, content=" %or_result = or i32 %0, %1")
let xor_result = builder.createXor(arg1, arg2, name="xor_result")
inspect(xor_result, content=" %xor_result = xor i32 %0, %1")
}impl Instruction for BinaryInstimpl User for BinaryInstimpl Value for BinaryInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "binary_ops_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createAdd(arg1, arg2)
inspect(add.getName(), content="None")
add.setName("sum")
inspect(add.getName(), content="Some(\"sum\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "binary_ops_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createAdd(arg1, arg2)
inspect(add.getValueRepr(), content="%2")
add.setName("sum")
inspect(add.getValueRepr(), content="%sum")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "binary_ops_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createAdd(arg1, arg2)
inspect(add.getName(), content="None")
add.setName("sum")
inspect(add.getName(), content="Some(\"sum\")")
}impl Show for BinaryInstpub enum BinaryOpFlags {
NoUnsignedWrap
NoSignedWrap
Exact
}impl Eq for BinaryOpFlagsimpl Hash for BinaryOpFlagsimpl Show for BinaryOpFlagspub enum BinaryOps {
Add
FAdd
Sub
FSub
Mul
FMul
SDiv
UDiv
FDiv
URem
SRem
FRem
Shl
LShr
AShr
And
Or
Xor
}pub struct BranchInst {
uid : UInt64
vty : VoidType
condition : &Value?
trueBlock : BasicBlock?
falseBlock : BasicBlock?
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i1_ty])
let fval = mod.addFunction(fty, "branch_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let true_bb = fval.addBasicBlock(name="true_branch")
let false_bb = fval.addBasicBlock(name="false_branch")
let cond = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let cond_br = builder.createCondBr(cond, true_bb, false_bb)
inspect(
cond_br,
content=" br i1 %0, label %true_branch, label %false_branch",
)
assert_true(cond_br.asValueEnum() is BranchInst(_))
builder.setInsertPoint(true_bb)
let uncond_br = builder.createBr(false_bb)
inspect(uncond_br, content=" br label %false_branch")
}impl Instruction for BranchInstimpl User for BranchInstimpl Value for BranchInstimpl Show for BranchInstpub struct CallInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
function_type : FunctionType
callee : Either[Function, &Value]
args : Array[&Value]
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
tailCallKind : TailCallKind
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let add_fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let main_fty = ctx.getFunctionType(i32_ty, [])
let add_func = mod.addFunction(add_fty, "add")
let main_func = mod.addFunction(main_fty, "main")
let bb = main_func.addBasicBlock(name="entry")
let arg1 = ctx.getConstInt32(10)
let arg2 = ctx.getConstInt32(20)
builder.setInsertPoint(bb)
let call = builder.createCall(add_func, [arg1, arg2], name="sum")
inspect(call, content=" %sum = call i32 @add(i32 10, i32 20)")
assert_true(call.asValueEnum() is CallInst(_))
let void_fty = ctx.getFunctionType(ctx.getVoidTy(), [])
let void_func = mod.addFunction(void_fty, "void_func")
let void_call = builder.createCall(void_func, [])
inspect(void_call, content=" call void @void_func()")
}impl Instruction for CallInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let add_fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let main_fty = ctx.getFunctionType(i32_ty, [])
let add_func = mod.addFunction(add_fty, "add")
let main_func = mod.addFunction(main_fty, "main")
let bb = main_func.addBasicBlock(name="entry")
let arg1 = ctx.getConstInt32(10)
let arg2 = ctx.getConstInt32(20)
builder.setInsertPoint(bb)
let call = builder.createCall(add_func, [arg1, arg2])
inspect(call.getName(), content="None")
call.setName("sum")
inspect(call.getName(), content="Some(\"sum\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let add_fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let main_fty = ctx.getFunctionType(i32_ty, [])
let add_func = mod.addFunction(add_fty, "add")
let main_func = mod.addFunction(main_fty, "main")
let bb = main_func.addBasicBlock(name="entry")
let arg1 = ctx.getConstInt32(10)
let arg2 = ctx.getConstInt32(20)
builder.setInsertPoint(bb)
let call = builder.createCall(add_func, [arg1, arg2])
inspect(call.getValueRepr(), content="%0")
call.setName("sum")
inspect(call.getValueRepr(), content="%sum")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let add_fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let main_fty = ctx.getFunctionType(i32_ty, [])
let add_func = mod.addFunction(add_fty, "add")
let main_func = mod.addFunction(main_fty, "main")
let bb = main_func.addBasicBlock(name="entry")
let arg1 = ctx.getConstInt32(10)
let arg2 = ctx.getConstInt32(20)
builder.setInsertPoint(bb)
let call = builder.createCall(add_func, [arg1, arg2])
inspect(call.getName(), content="None")
call.setName("sum")
inspect(call.getName(), content="Some(\"sum\")")
}pub struct CastInst {
uid : UInt64
to_ty : &Type
from_val : &Value
name : String?
parent : Function
users : Array[&User]
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
opcode : CastOps
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(i32_ty, [i64_ty])
let fval = mod.addFunction(fty, "cast_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let trunc = builder.createTrunc(arg, i32_ty, name="truncated")
inspect(trunc, content=" %truncated = trunc i64 %0 to i32")
assert_true(trunc.asValueEnum() is CastInst(_))
let zext = builder.createZExt(trunc, i64_ty, name="extended")
inspect(zext, content=" %extended = zext i32 %truncated to i64")
let bitcast = builder.createBitCast(trunc, f32_ty, name="bits")
inspect(bitcast, content=" %bits = bitcast i32 %truncated to float")
}impl Instruction for CastInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let fty = ctx.getFunctionType(i32_ty, [i64_ty])
let fval = mod.addFunction(fty, "cast_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let trunc = builder.createTrunc(arg, i32_ty)
inspect(trunc.getName(), content="None")
trunc.setName("truncated")
inspect(trunc.getName(), content="Some(\"truncated\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let fty = ctx.getFunctionType(i32_ty, [i64_ty])
let fval = mod.addFunction(fty, "cast_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let trunc = builder.createTrunc(arg, i32_ty)
inspect(trunc.getValueRepr(), content="%1")
trunc.setName("truncated")
inspect(trunc.getValueRepr(), content="%truncated")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let fty = ctx.getFunctionType(i32_ty, [i64_ty])
let fval = mod.addFunction(fty, "cast_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let trunc = builder.createTrunc(arg, i32_ty)
inspect(trunc.getName(), content="None")
trunc.setName("truncated")
inspect(trunc.getName(), content="Some(\"truncated\")")
}pub(all) enum CastOps {
Trunc
ZExt
SExt
FPTrunc
FPExt
UIToFP
SIToFP
FPToUI
FPToSI
PtrToInt
IntToPtr
BitCast
}pub struct ConstantArray {
uid : UInt64
vty : ArrayType
data : Either[Array[&Constant], NumberArrayEnum]
}impl Constant for ConstantArrayimpl Value for ConstantArrayimpl Eq for ConstantArrayimpl Show for ConstantArraypub enum ConstantEnum {
ConstantInt(ConstantInt)
ConstantFP(ConstantFP)
ConstantPointerNull(ConstantPointerNull)
ConstantArray(ConstantArray)
ConstantVector(ConstantVector)
ConstantString(ConstantString)
ConstantStruct(ConstantStruct)
}impl Eq for ConstantEnumimpl Constant for ConstantFPimpl Value for ConstantFPimpl Eq for ConstantFPimpl Show for ConstantFPtest {
let ctx = Context::new()
let f32_0 = ctx.getConstFloat(0.0)
let f32_1_5 = ctx.getConstFloat(1.5)
let result1 = f32_0.add(f32_1_5)
assert_eq(result1.getValue(), 1.5)
let f64_2_5 = ctx.getConstDouble(2.5)
let f64_m1_5 = ctx.getConstDouble(-1.5)
let result2 = f64_2_5.add(f64_m1_5)
assert_eq(result2.getValue(), 1.0)
}fn ConstantFP::bitcast(self : ConstantFP, dst_ty : &PrimitiveType) -> &Constant raise LLVMValueErrortest {
let ctx = Context::new()
// Test f32 to i32 bitcast
let f32_2_0 = ctx.getConstFloat(2.0)
let i32_bits = f32_2_0.bitcast(ctx.getInt32Ty())
guard i32_bits.asConstantEnum() is ConstantInt(i32_bits)
assert_eq(i32_bits.getValueAsInt64(), 0x40000000) // 2.0f bit pattern
// Test f64 to i64 bitcast
let f64_2_0 = ctx.getConstDouble(2.0)
let i64_bits = f64_2_0.bitcast(ctx.getInt64Ty())
guard i64_bits.asConstantEnum() is ConstantInt(i64_bits)
assert_eq(i64_bits.getValueAsInt64(), 0x4000000000000000L) // 2.0 bit pattern
// Test f32 to f32 (same type should error)
let f32_val = ctx.getConstFloat(1.0)
assert_true((try! f32_val.bitcast(ctx.getFloatTy())) is Err(_))
// Test error case: different bit widths
let f64_val = ctx.getConstDouble(42.0)
assert_true((try! f64_val.bitcast(ctx.getInt32Ty())) is Err(_))
}fn ConstantFP::compare(self : ConstantFP, predicate : FloatPredicate, other : ConstantFP) -> ConstantInt raise LLVMValueErrortest {
let ctx = Context::new()
let f32_1_5 = ctx.getConstFloat(1.5)
let f32_2_5 = ctx.getConstFloat(2.5)
let f32_nan = ctx.getConstFloat(0.0 / 0.0)
// Test FCMP_OEQ (ordered equal)
inspect(f32_1_5.compare(OEQ, f32_1_5), content="i1 true")
inspect(f32_1_5.compare(OEQ, f32_2_5), content="i1 false")
inspect(f32_nan.compare(OEQ, f32_nan), content="i1 false") // NaN != NaN
// Test UEQ (unordered equal)
inspect(f32_1_5.compare(UEQ, f32_1_5), content="i1 true")
inspect(f32_nan.compare(UEQ, f32_nan), content="i1 true") // NaN == NaN in unordered
// Test OGT (ordered greater than)
inspect(f32_2_5.compare(OGT, f32_1_5), content="i1 true")
inspect(f32_1_5.compare(OGT, f32_2_5), content="i1 false")
inspect(f32_nan.compare(OGT, f32_1_5), content="i1 false") // NaN comparisons are false
// Test UGT (unordered greater than)
inspect(f32_2_5.compare(UGT, f32_1_5), content="i1 true")
inspect(f32_nan.compare(UGT, f32_1_5), content="i1 true") // NaN makes it unordered
// Test OLT (ordered less than)
inspect(f32_1_5.compare(OLT, f32_2_5), content="i1 true")
inspect(f32_2_5.compare(OLT, f32_1_5), content="i1 false")
// Test ORD (ordered - no NaNs)
inspect(f32_1_5.compare(ORD, f32_2_5), content="i1 true")
inspect(f32_nan.compare(ORD, f32_1_5), content="i1 false")
// Test UNO (unordered - has NaNs)
inspect(f32_1_5.compare(UNO, f32_2_5), content="i1 false")
inspect(f32_nan.compare(UNO, f32_1_5), content="i1 true")
// Test TRUE and FCMP_FALSE
inspect(f32_1_5.compare(TRUE, f32_2_5), content="i1 true")
inspect(f32_1_5.compare(FALSE, f32_2_5), content="i1 false")
// Test type mismatch
let f64_1_5 = ctx.getConstDouble(1.5)
assert_true((try! f32_1_5.compare(OEQ, f64_1_5)) is Err(_))
}test {
let ctx = Context::new()
let f32_0 = ctx.getConstFloat(0.0)
let f32_1_5 = ctx.getConstFloat(1.5)
let result1 = f32_0.div(f32_1_5)
assert_eq(result1.getValue(), 0.0)
let f64_2_5 = ctx.getConstDouble(2.5)
let f64_m1_5 = ctx.getConstDouble(-1.5)
let result2 = f64_2_5.div(f64_m1_5)
assert_eq(result2.getValue(), -5.0 / 3.0)
}test {
let ctx = Context::new()
// Test f32 to f64 extension
let f32_1_5 = ctx.getConstFloat(1.5)
let f64_1_5 = f32_1_5.fpext(ctx.getDoubleTy())
assert_eq(f64_1_5.getValue(), 1.5)
// Test f32 to f64 extension preserves value
let f32_pi = ctx.getConstFloat(3.14159265)
let f64_pi = f32_pi.fpext(ctx.getDoubleTy())
assert_eq(f64_pi.getValue(), 3.1415927410125732)
// Test error case: cannot extend to smaller type
let f64_val = ctx.getConstDouble(2.0)
assert_true((try! f64_val.fpext(ctx.getFloatTy())) is Err(_))
}test {
let ctx = Context::new()
// Test positive float to signed integer
let f32_3_7 = ctx.getConstFloat(3.7)
let i32_3 = f32_3_7.fptosi(ctx.getInt32Ty())
assert_eq(i32_3.getValueAsInt64(), 3)
// Test negative float to signed integer
let f64_m5_2 = ctx.getConstDouble(-5.2)
let i64_m5 = f64_m5_2.fptosi(ctx.getInt64Ty())
assert_eq(i64_m5.getValueAsInt64(), -5)
// Test zero conversion
let f32_0 = ctx.getConstFloat(0.0)
let i16_0 = f32_0.fptosi(ctx.getInt16Ty())
assert_eq(i16_0.getValueAsInt64(), 0)
// Test fractional part truncation
let f64_m9_9 = ctx.getConstDouble(-9.9)
let i32_m9 = f64_m9_9.fptosi(ctx.getInt32Ty())
assert_eq(i32_m9.getValueAsInt64(), -9)
}test {
let ctx = Context::new()
// Test positive float to unsigned integer
let f32_3_7 = ctx.getConstFloat(3.7)
let i32_3 = f32_3_7.fptoui(ctx.getInt32Ty())
assert_eq(i32_3.getValueAsInt64(), 3)
// Test zero conversion
let f64_0 = ctx.getConstDouble(0.0)
let i64_0 = f64_0.fptoui(ctx.getInt64Ty())
assert_eq(i64_0.getValueAsInt64(), 0)
// Test large float to i8 (overflow behavior)
let f32_1000 = ctx.getConstFloat(1000.0)
let i8_overflow = f32_1000.fptoui(ctx.getInt8Ty())
// The value will be truncated to fit in i8 range (1000 in i8 is -24)
assert_eq(i8_overflow.getValueAsInt64(), -24)
// Test fractional part truncation
let f64_9_9 = ctx.getConstDouble(9.9)
let i32_9 = f64_9_9.fptoui(ctx.getInt32Ty())
assert_eq(i32_9.getValueAsInt64(), 9)
}test {
let ctx = Context::new()
// Test f64 to f32 truncation
let f64_1_5 = ctx.getConstDouble(1.5)
let f32_1_5 = f64_1_5.fptrunc(ctx.getFloatTy())
assert_eq(f32_1_5.getValue(), 1.5)
// Test f64 to f32 truncation with another value
let f64_precise = ctx.getConstDouble(2.5)
let f32_truncated = f64_precise.fptrunc(ctx.getFloatTy())
// In constant folding, the value is preserved
assert_eq(f32_truncated.getValue(), 2.5)
// Test error case: cannot truncate to larger type
let f32_val = ctx.getConstFloat(2.0)
assert_true((try! f32_val.fptrunc(ctx.getDoubleTy())) is Err(_))
}test {
let ctx = Context::new()
let f32_0 = ctx.getConstFloat(0.0)
let f32_1_5 = ctx.getConstFloat(1.5)
let result1 = f32_0.mul(f32_1_5)
assert_eq(result1.getValue(), 0.0)
let f64_2_5 = ctx.getConstDouble(2.5)
let f64_m1_5 = ctx.getConstDouble(-1.5)
let result2 = f64_2_5.mul(f64_m1_5)
assert_eq(result2.getValue(), -3.75)
}test {
let ctx = Context::new()
let f32_0 = ctx.getConstFloat(0.0)
let f32_1_5 = ctx.getConstFloat(1.5)
let result1 = f32_0.sub(f32_1_5)
assert_eq(result1.getValue(), -1.5)
let f64_2_5 = ctx.getConstDouble(2.5)
let f64_m1_5 = ctx.getConstDouble(-1.5)
let result2 = f64_2_5.sub(f64_m1_5)
assert_eq(result2.getValue(), 4.0)
}test {
let ctx = Context::new()
let i8 = ctx.getConstInt8(0)
let i16 = ctx.getConstInt16(1)
let i32 = ctx.getConstInt32(-2)
let i64 = ctx.getConstInt64(16)
inspect(i8, content="i8 0")
inspect(i16, content="i16 1")
inspect(i32, content="i32 -2")
inspect(i64, content="i64 16")
}impl Constant for ConstantIntimpl Value for ConstantIntimpl Eq for ConstantIntimpl Show for ConstantInttest {
let ctx = Context::new()
let i8_0 = ctx.getConstInt8(0)
let i8_31 = ctx.getConstInt8(31)
inspect(i8_0.add(i8_31), content="i8 31")
let i16_5 = ctx.getConstInt16(5)
let i16_72 = ctx.getConstInt16(72)
inspect(i16_5.add(i16_72), content="i16 77")
let i32_m7 = ctx.getConstInt32(-7)
let i32_81 = ctx.getConstInt32(81)
inspect(i32_m7.add(i32_81), content="i32 74")
let i64_16 = ctx.getConstInt64(16)
let i64_m33 = ctx.getConstInt64(-33)
inspect(i64_16.add(i64_m33), content="i64 -17")
assert_true((try! i8_0.add(i16_5)) is Err(_))
}test {
let ctx = Context::new()
let i8_m1 = ctx.getConstInt8(-1) // 11111111
let i8_2 = ctx.getConstInt8(2) // shift by 2
inspect(i8_m1.ashr(i8_2), content="i8 -1") // 11111111 (sign extended)
let i16_m16 = ctx.getConstInt16(-16) // ...1111111111110000
let i16_2 = ctx.getConstInt16(2) // shift by 2
inspect(i16_m16.ashr(i16_2), content="i16 -4") // ...1111111111111100
let i32_m8 = ctx.getConstInt32(-8)
let i32_1 = ctx.getConstInt32(1)
inspect(i32_m8.ashr(i32_1), content="i32 -4") // -8 >> 1 = -4 (arithmetic)
let i64_m128 = ctx.getConstInt64(-128L)
let i64_3 = ctx.getConstInt64(3L)
inspect(i64_m128.ashr(i64_3), content="i64 -16") // -128 >> 3 = -16
// Positive numbers should behave like logical shift
let i32_64 = ctx.getConstInt32(64)
let i32_2 = ctx.getConstInt32(2)
inspect(i32_64.ashr(i32_2), content="i32 16") // 64 >> 2 = 16
}fn ConstantInt::bitcast(self : ConstantInt, dst_ty : &PrimitiveType) -> &Constant raise LLVMValueErrortest {
let ctx = Context::new()
// Test i32 to f32 bitcast
let i32_val = ctx.getConstInt32(0x40000000) // 2.0 in float
let f32_val = i32_val.bitcast(ctx.getFloatTy())
guard f32_val.asConstantEnum() is ConstantFP(f32_val)
assert_eq(f32_val.getValue(), 2.0)
// Test i64 to f64 bitcast
let i64_val = ctx.getConstInt64(0x4000000000000000L) // 2.0 in double
let f64_val = i64_val.bitcast(ctx.getDoubleTy())
guard f64_val.asConstantEnum() is ConstantFP(f64_val)
assert_eq(f64_val.getValue(), 2.0)
// Test error case: different bit widths
let i8_val = ctx.getConstInt8(42)
assert_true((try! i8_val.bitcast(ctx.getFloatTy())) is Err(_))
}fn ConstantInt::compare(self : ConstantInt, predicate : IntPredicate, other : ConstantInt) -> ConstantInt raise LLVMValueErrortest {
let ctx = Context::new()
let i8_5 = ctx.getConstInt8(5)
let i8_10 = ctx.getConstInt8(10)
let i8_m5 = ctx.getConstInt8(-5)
// Test EQ
inspect(i8_5.compare(EQ, i8_5), content="i1 true")
inspect(i8_5.compare(EQ, i8_10), content="i1 false")
// Test NE
inspect(i8_5.compare(NE, i8_10), content="i1 true")
inspect(i8_5.compare(NE, i8_5), content="i1 false")
// Test SGT (signed greater than)
inspect(i8_10.compare(SGT, i8_5), content="i1 true")
inspect(i8_5.compare(SGT, i8_10), content="i1 false")
inspect(i8_5.compare(SGT, i8_m5), content="i1 true")
// Test UGT (unsigned greater than)
let i8_200 = ctx.getConstInt8(200) // -56 as signed, 200 as unsigned
inspect(i8_200.compare(UGT, i8_10), content="i1 true")
inspect(i8_10.compare(UGT, i8_200), content="i1 false")
// Test SLT (signed less than)
inspect(i8_5.compare(SLT, i8_10), content="i1 true")
inspect(i8_m5.compare(SLT, i8_5), content="i1 true")
// Test ULE (unsigned less or equal)
inspect(i8_5.compare(ULE, i8_10), content="i1 true")
inspect(i8_5.compare(ULE, i8_5), content="i1 true")
// Test type mismatch
let i16_5 = ctx.getConstInt16(5)
assert_true((try! i8_5.compare(EQ, i16_5)) is Err(_))
}fn ConstantInt::compute_and(self : ConstantInt, other : ConstantInt) -> ConstantInt raise LLVMValueErrortest {
let ctx = Context::new()
let i8_6 = ctx.getConstInt8(6) // 00000110
let i8_3 = ctx.getConstInt8(3) // 00000011
inspect(i8_6.compute_and(i8_3), content="i8 2") // 00000010
let i16_m1 = ctx.getConstInt16(-1) // 1111111111111111
let i16_all_set = ctx.getConstInt16(-1)
inspect(i16_m1.compute_and(i16_all_set), content="i16 -1")
let i32_pattern = ctx.getConstInt32(0x0F0F0F0F)
let i32_mask = ctx.getConstInt32(0xFF00FF00)
inspect(i32_pattern.compute_and(i32_mask), content="i32 251662080") // 0x0F000F00
let i64_val = ctx.getConstInt64(0x123456789ABCDEF0L)
let i64_low_clear = ctx.getConstInt64(-1L << 4) // ...FFFFFFFFFFFFFFF0
inspect(i64_val.compute_and(i64_low_clear), content="i64 1311768467463790320") // 0x123456789ABCDEF0
}fn ConstantInt::compute_shl(self : ConstantInt, other : ConstantInt) -> ConstantInt raise LLVMValueErrortest {
let ctx = Context::new()
let i8_1 = ctx.getConstInt8(1) // 00000001
let i8_3 = ctx.getConstInt8(3) // shift by 3
inspect(i8_1.compute_shl(i8_3), content="i8 8") // 00001000
let i16_5 = ctx.getConstInt16(5) // ...00000101
let i16_2 = ctx.getConstInt16(2) // shift by 2
inspect(i16_5.compute_shl(i16_2), content="i16 20") // ...00010100
let i32_7 = ctx.getConstInt32(7)
let i32_4 = ctx.getConstInt32(4)
inspect(i32_7.compute_shl(i32_4), content="i32 112") // 7 << 4 = 112
let i64_val = ctx.getConstInt64(0x123L)
let i64_8 = ctx.getConstInt64(8L)
inspect(i64_val.compute_shl(i64_8), content="i64 74496") // 0x123 << 8 = 0x12300
}test {
let ctx = Context::new()
assert_true(ctx.getConstInt8(0).equals(0))
assert_true(ctx.getConstInt8(-1).equals(-1))
assert_true(ctx.getConstInt8(1).equals(1))
assert_true(ctx.getConstInt16(16).equals(16))
assert_true(ctx.getConstInt32(-128).equals(-128))
}test {
let ctx = Context::new()
let i8_zero = ctx.getConstInt8(0)
let i16_one = ctx.getConstInt16(1)
let i32_m2 = ctx.getConstInt32(-2)
let i64_m16 = ctx.getConstInt64(-16)
inspect(i8_zero.getIntegerType(), content="i8")
inspect(i16_one.getIntegerType(), content="i16")
inspect(i32_m2.getIntegerType(), content="i32")
inspect(i64_m16.getIntegerType(), content="i64")
}test {
let ctx = Context::new()
let i8_zero = ctx.getConstInt8(0)
let i16_one = ctx.getConstInt16(1)
let i32_two = ctx.getConstInt32(2)
let i64_m1 = ctx.getConstInt64(-1)
let i8_m1 = ctx.getConstInt8(-1)
assert_eq(i8_zero.getValueAsInt64(), 0)
assert_eq(i16_one.getValueAsInt64(), 1)
assert_eq(i32_two.getValueAsInt64(), 2)
assert_eq(i64_m1.getValueAsInt64(), -1)
assert_eq(i8_m1.getValueAsInt64(), -1)
}test {
let ctx = Context::new()
let i64_0 = ctx.getConstInt64(0)
let null_ptr = i64_0.inttoptr()
inspect(null_ptr, content="ptr null")
let i32_42 = ctx.getConstInt32(42)
let ptr_42 = i32_42.inttoptr()
inspect(ptr_42, content="ptr null") // Still null in constant folding
}test {
let ctx = Context::new()
let i8_200 = ctx.getConstInt8(200) // 11001000 (as unsigned)
let i8_2 = ctx.getConstInt8(2) // shift by 2
inspect(i8_200.lshr(i8_2), content="i8 50") // 00110010 (50)
let i16_val = ctx.getConstInt16(-32768) // 1000000000000000
let i16_1 = ctx.getConstInt16(1) // shift by 1
inspect(i16_val.lshr(i16_1), content="i16 16384") // 0100000000000000 (16384)
let i32_m1 = ctx.getConstInt32(-1) // 0xFFFFFFFF
let i32_4 = ctx.getConstInt32(4) // shift by 4
inspect(i32_m1.lshr(i32_4), content="i32 268435455") // 0x0FFFFFFF
let i64_val = ctx.getConstInt64(0x8000000000000000L) // MSB set
let i64_1 = ctx.getConstInt64(1L)
inspect(i64_val.lshr(i64_1), content="i64 4611686018427387904") // logical shift
}test {
let ctx = Context::new()
let i8_0 = ctx.getConstInt8(0)
let i8_31 = ctx.getConstInt8(31)
inspect(i8_0.mul(i8_31), content="i8 0")
let i16_5 = ctx.getConstInt16(5)
let i16_72 = ctx.getConstInt16(72)
inspect(i16_5.mul(i16_72), content="i16 360")
let i32_m7 = ctx.getConstInt32(-7)
let i32_81 = ctx.getConstInt32(81)
inspect(i32_m7.mul(i32_81), content="i32 -567")
let i64_16 = ctx.getConstInt64(16)
let i64_m33 = ctx.getConstInt64(-33)
inspect(i64_16.mul(i64_m33), content="i64 -528")
}test {
let ctx = Context::new()
let i8_6 = ctx.getConstInt8(6) // 00000110
let i8_3 = ctx.getConstInt8(3) // 00000011
inspect(i8_6.or(i8_3), content="i8 7") // 00000111
let i16_1 = ctx.getConstInt16(1) // ...0001
let i16_2 = ctx.getConstInt16(2) // ...0010
inspect(i16_1.or(i16_2), content="i16 3") // ...0011
let i32_pattern = ctx.getConstInt32(0x0F0F0F0F)
let i32_mask = ctx.getConstInt32(0xF0F0F0F0)
inspect(i32_pattern.or(i32_mask), content="i32 -1") // 0xFFFFFFFF
let i64_val = ctx.getConstInt64(0L)
let i64_m1 = ctx.getConstInt64(-1L)
inspect(i64_val.or(i64_m1), content="i64 -1")
}test {
let ctx = Context::new()
let i8_1 = ctx.getConstInt8(1)
let i8_31 = ctx.getConstInt8(31)
inspect(i8_31.sdiv(i8_1), content="i8 31")
let i16_5 = ctx.getConstInt16(5)
let i16_72 = ctx.getConstInt16(72)
inspect(i16_72.sdiv(i16_5), content="i16 14")
let i32_m7 = ctx.getConstInt32(-7)
let i32_81 = ctx.getConstInt32(81)
inspect(i32_m7.sdiv(i32_81), content="i32 0")
let i64_16 = ctx.getConstInt64(16)
let i64_m33 = ctx.getConstInt64(-33)
inspect(i64_16.sdiv(i64_m33), content="i64 0")
}test {
let ctx = Context::new()
let i8_m1 = ctx.getConstInt8(-1)
let i32_m1 = i8_m1.sext(ctx.getInt32Ty())
inspect(i32_m1, content="i32 -1")
let i1_true = ctx.getConstTrue()
let i8_true = i1_true.sext(ctx.getInt8Ty())
inspect(i8_true, content="i8 -1")
let i16_42 = ctx.getConstInt16(42)
let i64_42 = i16_42.sext(ctx.getInt64Ty())
inspect(i64_42, content="i64 42")
// Test error case: cannot sext to smaller type
let i32_val = ctx.getConstInt32(42)
assert_true((try! i32_val.sext(ctx.getInt8Ty())) is Err(_))
}test {
let ctx = Context::new()
let i32_m42 = ctx.getConstInt32(-42)
let f32_m42 = i32_m42.sitofp(ctx.getFloatTy())
assert_eq(f32_m42.getValue(), -42.0)
let i8_127 = ctx.getConstInt8(127)
let f64_127 = i8_127.sitofp(ctx.getDoubleTy())
assert_eq(f64_127.getValue(), 127.0)
let i64_0 = ctx.getConstInt64(0)
let f32_0 = i64_0.sitofp(ctx.getFloatTy())
assert_eq(f32_0.getValue(), 0.0)
}test {
let ctx = Context::new()
let i8_0 = ctx.getConstInt8(0)
let i8_31 = ctx.getConstInt8(31)
inspect(i8_31.sub(i8_0), content="i8 31")
inspect(i8_0.sub(i8_31), content="i8 -31")
let i16_5 = ctx.getConstInt16(5)
let i16_72 = ctx.getConstInt16(72)
inspect(i16_72.sub(i16_5), content="i16 67")
let i32_m7 = ctx.getConstInt32(-7)
let i32_81 = ctx.getConstInt32(81)
inspect(i32_m7.sub(i32_81), content="i32 -88")
let i64_16 = ctx.getConstInt64(16)
let i64_m33 = ctx.getConstInt64(-33)
inspect(i64_16.sub(i64_m33), content="i64 49")
assert_true((try! i32_81.sub(i64_16)) is Err(_))
}fn ConstantInt::trunc(self : ConstantInt, dst_ty : &IntegerType) -> ConstantInt raise LLVMValueErrortest {
let ctx = Context::new()
let i32_255 = ctx.getConstInt32(255)
let i8_255 = i32_255.trunc(ctx.getInt8Ty())
inspect(i8_255, content="i8 -1")
let i64_0xFFFF = ctx.getConstInt64(0xFFFF)
let i16_0xFFFF = i64_0xFFFF.trunc(ctx.getInt16Ty())
inspect(i16_0xFFFF, content="i16 -1")
let i32_12345 = ctx.getConstInt32(12345)
let i16_12345 = i32_12345.trunc(ctx.getInt16Ty())
inspect(i16_12345, content="i16 12345")
// Test error case: cannot truncate to larger type
let i8_val = ctx.getConstInt8(42)
assert_true((try! i8_val.trunc(ctx.getInt32Ty())) is Err(_))
}test {
let ctx = Context::new()
// Test case 1: i8 unsigned division
// 200u8 / 10u8 = 20u8. ConstantInt stores 20L.
let i8_200 = ctx.getConstInt8(200) // Internally stored as -56L
let i8_10 = ctx.getConstInt8(10)
inspect(i8_200.udiv(i8_10), content="i8 20")
// Test case 2: i8 unsigned division with -1 (255u8)
// 255u8 / 2u8 = 127u8. ConstantInt stores 127L.
let i8_m1 = ctx.getConstInt8(-1) // Internally stored as -1L, represents 255u8
let i8_2 = ctx.getConstInt8(2)
inspect(i8_m1.udiv(i8_2), content="i8 127")
// Test case 3: i32 unsigned division
// 2147483647u / 2u = 1073741823u.
let i32_max_signed = ctx.getConstInt32(@int.max_value) // 2147483647
let i32_2 = ctx.getConstInt32(2)
inspect(i32_max_signed.udiv(i32_2), content="i32 1073741823")
// Test case 4: i64 unsigned division (UInt64.max_value / 2)
// (-1L as UInt64) / 2 = (2^64 - 1) / 2 = 2^63 - 1 (which is Int64.max_value)
let i64_m1 = ctx.getConstInt64(-1L)
let i64_2 = ctx.getConstInt64(2L)
inspect(i64_m1.udiv(i64_2), content="i64 9223372036854775807")
// Test case 5: Type mismatch
let i8_5 = ctx.getConstInt8(5)
let i16_2 = ctx.getConstInt16(2)
assert_true((try! i8_5.udiv(i16_2)) is Err(_))
// Test case 6: Division by zero
let i8_0 = ctx.getConstInt8(0)
assert_true((try! i8_5.udiv(i8_0)) is Err(_))
// Test case 7: i1 unsigned division
let i1_true = ctx.getConstTrue()
let i1_false = ctx.getConstFalse()
inspect(i1_true.udiv(i1_true), content="i1 true") // 1u / 1u = 1u
inspect(i1_false.udiv(i1_true), content="i1 false") // 0u / 1u = 0u
}test {
let ctx = Context::new()
let i32_255 = ctx.getConstInt32(255)
let f32_255 = i32_255.uitofp(ctx.getFloatTy())
assert_eq(f32_255.getValue(), 255.0)
let i8_m1 = ctx.getConstInt8(-1) // 255 as unsigned
let f64_255 = i8_m1.uitofp(ctx.getDoubleTy())
assert_eq(f64_255.getValue(), 255.0)
let i64_0 = ctx.getConstInt64(0)
let f32_0 = i64_0.uitofp(ctx.getFloatTy())
assert_eq(f32_0.getValue(), 0.0)
}test {
let ctx = Context::new()
let i8_6 = ctx.getConstInt8(6) // 00000110
let i8_3 = ctx.getConstInt8(3) // 00000011
inspect(i8_6.xor(i8_3), content="i8 5") // 00000101
let i16_val = ctx.getConstInt16(0xAA) // ...10101010
let i16_m1 = ctx.getConstInt16(-1) // ...11111111
inspect(i16_val.xor(i16_m1), content="i16 -171") // ...01010101 (which is -0xAB or -171 for i16)
let i32_pattern = ctx.getConstInt32(0x0F0F0F0F)
let i32_self_xor = i32_pattern.xor(i32_pattern)
inspect(i32_self_xor, content="i32 0")
let i64_val = ctx.getConstInt64(12345L)
let i64_0 = ctx.getConstInt64(0L)
inspect(i64_val.xor(i64_0), content="i64 12345")
}test {
let ctx = Context::new()
let i8_255 = ctx.getConstInt8(255) // -1 as signed, 255 as unsigned
let i32_255 = i8_255.zext(ctx.getInt32Ty())
inspect(i32_255, content="i32 255")
let i1_true = ctx.getConstTrue()
let i8_true = i1_true.zext(ctx.getInt8Ty())
inspect(i8_true, content="i8 1")
let i16_42 = ctx.getConstInt16(42)
let i64_42 = i16_42.zext(ctx.getInt64Ty())
inspect(i64_42, content="i64 42")
// Test error case: cannot zext to smaller type
let i32_val = ctx.getConstInt32(42)
assert_true((try! i32_val.zext(ctx.getInt8Ty())) is Err(_))
}impl Constant for ConstantPointerNullimpl Value for ConstantPointerNullimpl Eq for ConstantPointerNullimpl Show for ConstantPointerNullimpl Constant for ConstantStringimpl Value for ConstantStringimpl Eq for ConstantStringimpl Show for ConstantStringtest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let sty = ctx.getStructType([i32ty, f32ty])
let i32_val = ctx.getConstInt32(42)
let f32_val = ctx.getConstFloat(3.14)
let struct_val = ConstantStruct::new(sty, [i32_val, f32_val])
inspect(
struct_val,
content="{ i32, float } { i32 42, float 0x40091EB860000000 }",
)
}impl Constant for ConstantStructimpl Value for ConstantStructimpl Eq for ConstantStructimpl Show for ConstantStructtest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let sty = ctx.getStructType([i32ty, f32ty])
let i32_val = ctx.getConstInt32(42)
let f32_val = ctx.getConstFloat(3.14)
let struct_val = ConstantStruct::new(sty, [i32_val, f32_val])
inspect(struct_val.extractValue([0]), content="Some(i32 42)")
inspect(
struct_val.extractValue([1]),
content="Some(float 0x40091EB860000000)",
)
inspect(struct_val.extractValue([2]), content="None") // Out of bounds
}fn ConstantStruct::insertValue(self : ConstantStruct, indices : ArrayView[Int], value : &Constant) -> ConstantStruct?test {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let sty = ctx.getStructType([i32ty, f32ty])
let i32_val = ctx.getConstInt32(42)
let f32_val = ctx.getConstFloat(3.14)
let struct_val = ConstantStruct::new(sty, [i32_val, f32_val])
// Insert new value at index 0
let new_i32_val = ctx.getConstInt32(100)
guard struct_val.insertValue([0], new_i32_val) is Some(new_struct)
// Verify the new value was inserted
assert_true(new_struct.extractValue([0]) is Some(_))
}pub struct ConstantVector {
uid : UInt64
vty : VectorType
data : Either[Array[&Constant], NumberArrayEnum]
}impl Constant for ConstantVectorimpl Value for ConstantVectorimpl Eq for ConstantVectorimpl Show for ConstantVectorpub struct Context {
key : UInt
// private fields
}fn Context::getArrayType(self : Context, elementType : &Type, numElements : Int) -> ArrayType raise LLVMTypeErrortest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let arrty = ctx.getArrayType(i32ty, 16)
inspect(arrty, content="[16 x i32]")
inspect(arrty.getElementType(), content="i32")
assert_eq(arrty.getElementCount(), 16)
}test {
let ctx = Context::new()
let bfloat_ty = ctx.getBFloatTy()
inspect(bfloat_ty, content="bfloat")
}test {
let ctx = Context::new()
inspect(ctx.getConstBool(true), content="i1 true")
inspect(ctx.getConstBool(false), content="i1 false")
}test {
let ctx = Context::new()
let one = ctx.getConstDouble(1.0)
let two = ctx.getConstDouble(2.0)
inspect(one, content="double 0x3FF0000000000000")
inspect(two, content="double 0x4000000000000000")
}test {
let ctx = Context::new()
let data : Array[Double] = [1.0, 2.0]
let arr = ctx.getConstDoubleArray(data)
inspect(
arr,
content="[2 x double] [double 0x3FF0000000000000, double 0x4000000000000000]",
)
}test {
let ctx = Context::new()
let data : Array[Double] = [1.0, 2.0]
let arr = ctx.getConstDoubleVector(data)
inspect(
arr,
content="<2 x double> <double 0x3FF0000000000000, double 0x4000000000000000>",
)
}test {
let ctx = Context::new()
inspect(ctx.getConstFalse(), content="i1 false")
}test {
let ctx = Context::new()
let one = ctx.getConstFloat(1.0)
let two = ctx.getConstFloat(2.0)
inspect(one, content="float 0x3FF0000000000000")
inspect(two, content="float 0x4000000000000000")
}test {
let ctx = Context::new()
let data : Array[Float] = [1.0, 2.0]
let arr = ctx.getConstFloatArray(data)
inspect(
arr,
content="[2 x float] [float 0x3FF0000000000000, float 0x4000000000000000]",
)
}test {
let ctx = Context::new()
let data : Array[Float] = [1.0, 2.0]
let arr = ctx.getConstFloatVector(data)
inspect(
arr,
content="<2 x float> <float 0x3FF0000000000000, float 0x4000000000000000>",
)
}test {
let ctx = Context::new()
let inf = ctx.getConstInfDouble()
let neg_inf = ctx.getConstInfDouble(isNegative=true)
inspect(inf, content="double 0x7FF0000000000000")
inspect(neg_inf, content="double 0xFFF0000000000000")
}test {
let ctx = Context::new()
let inf = ctx.getConstInfFloat()
let neg_inf = ctx.getConstInfFloat(isNegative=true)
inspect(inf, content="float 0x7FF0000000000000")
inspect(neg_inf, content="float 0xFFF0000000000000")
}test {
let ctx = Context::new()
inspect(ctx.getConstInt16(0), content="i16 0")
inspect(ctx.getConstInt16(1), content="i16 1")
inspect(ctx.getConstInt16(-1), content="i16 -1")
}test {
let ctx = Context::new()
let data : Array[Int16] = [42, 63, 77, 89]
let arr = ctx.getConstInt16Array(data)
inspect(arr, content="[4 x i16] [i16 42, i16 63, i16 77, i16 89]")
}test {
let ctx = Context::new()
let data : Array[Int16] = [42, 63, 77, 89]
let arr = ctx.getConstInt16Vector(data)
inspect(arr, content="<4 x i16> <i16 42, i16 63, i16 77, i16 89>")
}test {
let ctx = Context::new()
inspect(ctx.getConstInt32(0), content="i32 0")
inspect(ctx.getConstInt32(1), content="i32 1")
inspect(ctx.getConstInt32(-1), content="i32 -1")
}test {
let ctx = Context::new()
let data : Array[Int] = [42, 63, 77, 89]
let arr = ctx.getConstInt32Array(data)
inspect(arr, content="[4 x i32] [i32 42, i32 63, i32 77, i32 89]")
}test {
let ctx = Context::new()
let data : Array[Int] = [42, 63, 77, 89]
let arr = ctx.getConstInt32Vector(data)
inspect(arr, content="<4 x i32> <i32 42, i32 63, i32 77, i32 89>")
}test {
let ctx = Context::new()
inspect(ctx.getConstInt64(0), content="i64 0")
inspect(ctx.getConstInt64(1), content="i64 1")
inspect(ctx.getConstInt64(-1), content="i64 -1")
}test {
let ctx = Context::new()
let data : Array[Int64] = [42, 63, 77, 89]
let arr = ctx.getConstInt64Array(data)
inspect(arr, content="[4 x i64] [i64 42, i64 63, i64 77, i64 89]")
}test {
let ctx = Context::new()
let data : Array[Int64] = [42, 63, 77, 89]
let arr = ctx.getConstInt64Vector(data)
inspect(arr, content="<4 x i64> <i64 42, i64 63, i64 77, i64 89>")
}test {
let ctx = Context::new()
inspect(ctx.getConstInt8(0), content="i8 0")
inspect(ctx.getConstInt8(1), content="i8 1")
inspect(ctx.getConstInt8(-1), content="i8 -1")
}test {
let ctx = Context::new()
let data : Array[Int] = [42, 63, 77, 89]
let arr = ctx.getConstInt8Array(data)
inspect(arr, content="[4 x i8] [i8 42, i8 63, i8 77, i8 89]")
}test {
let ctx = Context::new()
let data : Array[Int] = [42, 63, 77, 89]
let arr = ctx.getConstInt8Vector(data)
inspect(arr, content="<4 x i8> <i8 42, i8 63, i8 77, i8 89>")
}test {
let ctx = Context::new()
let nan = ctx.getConstNaNDouble()
let neg_nan = ctx.getConstNaNDouble(isNegative=true)
inspect(nan, content="double 0x7FF8000000000000")
inspect(neg_nan, content="double 0xFFF8000000000000")
}test {
let ctx = Context::new()
let nan = ctx.getConstNaNDouble()
let neg_nan = ctx.getConstNaNDouble(isNegative=true)
inspect(nan, content="double 0x7FF8000000000000")
inspect(neg_nan, content="double 0xFFF8000000000000")
}fn Context::getConstPointerNull(self : Context, ty : &Type, addressSpace? : UInt) -> ConstantPointerNulltest {
let ctx = Context::new()
let nan = ctx.getConstQNaNDouble()
let neg_nan = ctx.getConstQNaNDouble(isNegative=true)
inspect(nan, content="double 0x7FF8000000000000")
inspect(neg_nan, content="double 0xFFF8000000000000")
}test {
let ctx = Context::new()
let nan = ctx.getConstQNaNFloat()
let neg_nan = ctx.getConstQNaNFloat(isNegative=true)
inspect(nan, content="float 0x7FF8000000000000")
inspect(neg_nan, content="float 0xFFF8000000000000")
}test {
let ctx = Context::new()
let nan = ctx.getConstSNaNDouble()
let neg_nan = ctx.getConstSNaNDouble(isNegative=true)
inspect(nan, content="double 0x7FF4000000000000")
inspect(neg_nan, content="double 0xFFF4000000000000")
}test {
let ctx = Context::new()
let nan = ctx.getConstSNaNFloat()
let neg_nan = ctx.getConstSNaNFloat(isNegative=true)
inspect(nan, content="float 0x7FF4000000000000")
inspect(neg_nan, content="float 0xFFF4000000000000")
}test {
let ctx = Context::new()
inspect(ctx.getConstTrue(), content="i1 true")
}test {
let ctx = Context::new()
let data : Array[UInt16] = [42, 63, 77, 89]
let arr = ctx.getConstUInt16Array(data)
inspect(arr, content="[4 x i16] [i16 42, i16 63, i16 77, i16 89]")
}test {
let ctx = Context::new()
let data : Array[UInt16] = [42, 63, 77, 89]
let arr = ctx.getConstUInt16Vector(data)
inspect(arr, content="<4 x i16> <i16 42, i16 63, i16 77, i16 89>")
}test {
let ctx = Context::new()
let data : Array[UInt] = [42, 63, 77, 89]
let arr = ctx.getConstUInt32Array(data)
inspect(arr, content="[4 x i32] [i32 42, i32 63, i32 77, i32 89]")
}test {
let ctx = Context::new()
let data : Array[UInt] = [42, 63, 77, 89]
let arr = ctx.getConstUInt32Vector(data)
inspect(arr, content="<4 x i32> <i32 42, i32 63, i32 77, i32 89>")
}test {
let ctx = Context::new()
let data : Array[UInt64] = [42, 63, 77, 89]
let arr = ctx.getConstUInt64Array(data)
inspect(arr, content="[4 x i64] [i64 42, i64 63, i64 77, i64 89]")
}test {
let ctx = Context::new()
let data : Array[UInt64] = [42, 63, 77, 89]
let arr = ctx.getConstUInt64Vector(data)
inspect(arr, content="<4 x i64> <i64 42, i64 63, i64 77, i64 89>")
}test {
let ctx = Context::new()
let data : Array[Byte] = [42, 63, 77, 89]
let arr = ctx.getConstUInt8Array(data)
inspect(arr, content="[4 x i8] [i8 42, i8 63, i8 77, i8 89]")
}test {
let ctx = Context::new()
let data : Array[Byte] = [42, 63, 77, 89]
let arr = ctx.getConstUInt8Vector(data)
inspect(arr, content="<4 x i8> <i8 42, i8 63, i8 77, i8 89>")
}let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let zero_i32 = ctx.getConstZero(i32ty)
inspect(zero_i32, content="i32 0")test {
let ctx = Context::new()
let zero = ctx.getConstZeroDouble()
let neg_zero = ctx.getConstZeroDouble(isNegative=true)
inspect(zero, content="double 0x0")
inspect(neg_zero, content="double 0x8000000000000000")
}test {
let ctx = Context::new()
let zero = ctx.getConstZeroFloat()
let neg_zero = ctx.getConstZeroFloat(isNegative=true)
inspect(zero, content="float 0x0")
inspect(neg_zero, content="float 0x8000000000000000")
}test {
let ctx = Context::new()
let doubletype = ctx.getDoubleTy()
inspect(doubletype, content="double")
}test {
let ctx = Context::new()
let fp128ty = ctx.getFP128Ty()
inspect(fp128ty, content="fp128")
}fn Context::getFixedVectorType(self : Context, elementType : &Type, elementQuantity : Int) -> VectorType raise LLVMTypeErrortest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let fixedVecTy = ctx.getFixedVectorType(i32ty, 32)
inspect(fixedVecTy, content="<32 x i32>")
}test {
let ctx = Context::new()
let f32ty = ctx.getFloatTy()
inspect(f32ty, content="float")
}fn Context::getFunctionType(self : Context, returnType : &Type, paramTypes : Array[&Type], isVarArg? : Bool) -> FunctionType raise LLVMTypeErrortest {
let ctx = Context::new()
let voidty = ctx.getVoidTy()
let i32ty = ctx.getInt32Ty()
let f64ty = ctx.getDoubleTy()
let fty = ctx.getFunctionType(voidty, [i32ty, f64ty])
inspect(fty, content="void (i32, double)")
}test {
let ctx = Context::new()
let half_ty = ctx.getHalfTy()
inspect(half_ty, content="half")
}test {
let ctx = Context::new()
inspect(ctx.getPtrTy(), content="ptr")
let addressSpace = AddressSpace::new(1)
inspect(ctx.getPtrTy(addressSpace~), content="ptr")
}fn Context::getScalableVectorType(self : Context, elementType : &Type, elementQuantity : Int) -> ScalableVectorType raise LLVMTypeErrortest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let scalableVecTy = ctx.getScalableVectorType(i32ty, 16)
inspect(scalableVecTy, content="<vscale x 16 x i32>")
}fn Context::getStructType(self : Context, elements : Array[&Type], name? : String, isPacked? : Bool) -> StructType raise LLVMTypeErrortest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let f64ty = ctx.getDoubleTy()
let sty = ctx.getStructType([i32ty, f32ty, f64ty], name="foo")
inspect(sty.full_info(), content="%foo = type { i32, float, double }")
// Cannot create a ananymous struct type with empty elements.
assert_true((try! ctx.getStructType([])) is Err(_))
// Cannot create a struct which has same name with other struct.
// the `foo` struct is already created.
assert_true((try! ctx.getStructType([], name="foo")) is Err(_))
}test {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let _ = ctx.getStructType([i32ty, f32ty], name="foo")
let sty = ctx.getStructTypeByName("foo").unwrap()
inspect(sty.full_info(), content="%foo = type { i32, float }")
}test {
let ctx = Context::new()
let tokenty = ctx.getTokenTy()
inspect(tokenty, content="token")
}test {
let ctx = Context::new()
let voidty = ctx.getVoidTy()
inspect(voidty, content="void")
}pub(all) enum DLLStorageClass {
DefaultDLLStorageClass
DLLImportStorageClass
DLLExportStorageClass
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let datalayout = mod.getDataLayout()
let i8ty = ctx.getInt8Ty()
let i32ty = ctx.getInt32Ty()
let i64ty = ctx.getInt64Ty()
// Non-packed struct: { i8, i32, i64 }
let normal_struct = ctx.getStructType([i8ty, i32ty, i64ty])
assert_eq(datalayout.getStructTypeOffset(normal_struct, 0), 0) // i8
assert_eq(datalayout.getStructTypeOffset(normal_struct, 1), 4) // i32, aligned
assert_eq(datalayout.getStructTypeOffset(normal_struct, 2), 8) // i64, aligned
// Packed struct: packed { i8, i32, i64 }
let packed_struct = ctx.getStructType([i8ty, i32ty, i64ty], isPacked=true)
assert_eq(datalayout.getStructTypeOffset(packed_struct, 0), 0) // i8
assert_eq(datalayout.getStructTypeOffset(packed_struct, 1), 1) // i32, no padding
assert_eq(datalayout.getStructTypeOffset(packed_struct, 2), 5) // i64, no padding
// Invalid indices return 0
assert_eq(datalayout.getStructTypeOffset(normal_struct, -1), 0)
assert_eq(datalayout.getStructTypeOffset(normal_struct, 10), 0)
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let datalayout = mod.getDataLayout()
// Basic types
let i32ty = ctx.getInt32Ty()
assert_eq(datalayout.getTypeAllocSize(i32ty), 4)
// Array types
let arrty = ctx.getArrayType(i32ty, 10)
assert_eq(datalayout.getTypeAllocSize(arrty), 40) // 4 * 10
// Struct types with alignment
let struct_ty = ctx.getStructType([ctx.getInt8Ty(), i32ty])
assert_eq(datalayout.getTypeAllocSize(struct_ty), 8) // 1 + 3 padding + 4
}impl Eq for DoubleArrayimpl Hash for DoubleArrayimpl Show for DoubleArray#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn DoubleArray::inner(self : DoubleArray) -> Array[Double]impl FPType for DoubleTypeimpl PrimitiveType for DoubleTypeimpl Type for DoubleTypeimpl Eq for DoubleTypeimpl Hash for DoubleTypeimpl Show for DoubleTypepub struct ExtractValueInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
aggregate : &Value
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
indices : Array[Int]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(i32_ty, [struct_ty])
let fval = mod.addFunction(fty, "extractvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let extract = builder.createExtractValue(aggregate, [0], name="field")
inspect(extract, content=" %field = extractvalue { i32, i32 } %0, 0")
assert_true(extract.asValueEnum() is ExtractValueInst(_))
}impl Instruction for ExtractValueInstimpl UnaryInst for ExtractValueInstimpl User for ExtractValueInstimpl Value for ExtractValueInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(i32_ty, [struct_ty])
let fval = mod.addFunction(fty, "extractvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let extract = builder.createExtractValue(aggregate, [0])
inspect(extract.getName(), content="None")
extract.setName("field")
inspect(extract.getName(), content="Some(\"field\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(i32_ty, [struct_ty])
let fval = mod.addFunction(fty, "extractvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let extract = builder.createExtractValue(aggregate, [0])
inspect(extract.getValueRepr(), content="%1")
extract.setName("field")
inspect(extract.getValueRepr(), content="%field")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(i32_ty, [struct_ty])
let fval = mod.addFunction(fty, "extractvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let extract = builder.createExtractValue(aggregate, [0])
inspect(extract.getName(), content="None")
extract.setName("field")
inspect(extract.getName(), content="Some(\"field\")")
}impl Show for ExtractValueInstpub struct FCmpInst {
uid : UInt64
vty : Int1Type
lhs : &Value
rhs : &Value
name : String?
parent : Function
users : Array[&User]
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
predicate : FloatPredicate
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fcmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let oeq_cmp = builder.createFCmp(OEQ, arg1, arg2, name="oeq_cmp")
inspect(oeq_cmp, content=" %oeq_cmp = fcmp oeq float %0, %1")
assert_true(oeq_cmp.asValueEnum() is FCmpInst(_))
let ogt_cmp = builder.createFCmp(OGT, arg1, arg2, name="ogt_cmp")
inspect(ogt_cmp, content=" %ogt_cmp = fcmp ogt float %0, %1")
let olt_cmp = builder.createFCmp(OLT, arg1, arg2, name="olt_cmp")
inspect(olt_cmp, content=" %olt_cmp = fcmp olt float %0, %1")
let uno_cmp = builder.createFCmp(UNO, arg1, arg2, name="uno_cmp")
inspect(uno_cmp, content=" %uno_cmp = fcmp uno float %0, %1")
}impl Instruction for FCmpInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fcmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let oeq_cmp = builder.createFCmp(OEQ, arg1, arg2)
inspect(oeq_cmp.getName(), content="None")
oeq_cmp.setName("oeq_cmp")
inspect(oeq_cmp.getName(), content="Some(\"oeq_cmp\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fcmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let oeq_cmp = builder.createFCmp(OEQ, arg1, arg2)
inspect(oeq_cmp.getValueRepr(), content="%2")
oeq_cmp.setName("oeq_cmp")
inspect(oeq_cmp.getValueRepr(), content="%oeq_cmp")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fcmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let oeq_cmp = builder.createFCmp(OEQ, arg1, arg2)
inspect(oeq_cmp.getName(), content="None")
oeq_cmp.setName("oeq_cmp")
inspect(oeq_cmp.getName(), content="Some(\"oeq_cmp\")")
}pub struct FNegInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
operand : &Value
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
fast_math_flags : Set[FastMathFlag]
}pub enum FPTypeEnum {
HalfType(HalfType)
BFloatType(BFloatType)
FloatType(FloatType)
DoubleType(DoubleType)
FP128Type(FP128Type)
}pub(all) enum FastMathFlag {
AllowReassoc
NoNaNs
NoInfs
NoSignedZeros
AllowReciprocal
AllowContract
ApproxFunc
}impl Eq for FastMathFlagimpl Hash for FastMathFlagimpl Show for FastMathFlagimpl Eq for FloatArrayimpl Hash for FloatArrayimpl Show for FloatArray#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn FloatArray::inner(self : FloatArray) -> Array[Float]pub(all) enum FloatPredicate {
FALSE
OEQ
OGT
OGE
OLT
OLE
ONE
ORD
UNO
UEQ
UGT
UGE
ULT
ULE
UNE
TRUE
}impl Show for FloatPredicatetype FloatingEnumimpl Eq for FloatingEnumimpl Hash for FloatingEnumimpl Show for FloatingEnumpub(all) enum FnAttr {
AllocKind(Int)
AllocSize(Int)
AlwaysInline
Builtin
Cold
Convergent
Hot
DisableSanitizerInstrumentation
FnRetThunkExtern
HybridPatchable
InlineHint
JumpTable
Memory(Int)
MinSize
Naked
NoBuiltin
NoCallback
NoDivergenceSource
NoDuplicate
NoFree
NoImplicitFloat
NoInline
NonLazyBind
NoMerge
NoRecurse
NoRedZone
NoReturn
NoSync
NoCfCheck
NoProfile
SkipProfile
NoUnwind
NoSanitizeBounds
NoSanitizeCoverage
NullPointerIsValid
OptimizeForDebugging
OptForFuzzing
OptimizeForSize
OptimizeNone
Preallocated(&Type)
ReturnTwice
SafeStack
ShadowCallStack
StackAlignment(Int)
Speculatable
StackProtect
StackProtectReq
StackProtectStrong
StrictFP
SanitizeAddress
SanitizeThread
SanitizeType
SanitizeMemory
SanitizeHWAddress
SanitizeMemTag
SanitizeNumericalStability
SanitizeRealtime
SanitizeRealtimeBlocking
SpeculativeLoadHardening
UWTable(Int)
VScaleRange(Int)
WillReturn
MustProgress
PresplitCoroutine
CoroDestroyOnlyWhenComplete
CoroElideSafe
DenormalFPMath
DenormalFPMathF32
}pub struct Function {
uid : UInt64
fty : FunctionType
users : Array[&User]
linkage : Ref[Linkage]
visibility : Ref[Visibility]
unnamed_addr : Ref[UnnamedAddr]
mod : Module
index : Int
addressSpace : AddressSpace
arguments : Array[Argument]
symbols : Map[String, &Value]
attrSet : AttributeSet
basicBlocks : Array[BasicBlock]
// private fields
}impl GlobalValue for Functiontest {
let ctx = Context::new()
let int32ty = ctx.getInt32Ty()
let voidty = ctx.getVoidTy()
let f32ty = ctx.getFloatTy()
let f64ty = ctx.getDoubleTy()
let fty = ctx.getFunctionType(voidty, [int32ty, f32ty, f64ty])
inspect(fty, content="void (i32, float, double)")
}impl AbstractType for FunctionTypeimpl Type for FunctionTypeimpl Eq for FunctionTypeimpl Hash for FunctionTypeimpl Show for FunctionTypepub struct GetElementPtrInst {
uid : UInt64
vty : PointerType
users : Array[&User]
ptr : &Value
indices : Array[&Value]
name : String?
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
isInbounds : Bool
pointeeType : &Type
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let array_ty = ctx.getArrayType(i32_ty, 10)
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ptr_ty, [ptr_ty])
let fval = mod.addFunction(fty, "gep_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
let zero = ctx.getConstInt32(0)
let two = ctx.getConstInt32(2)
builder.setInsertPoint(bb)
let gep = builder.createGEP(
arg,
array_ty,
[zero, two],
name="elem_ptr",
inbounds=true,
)
inspect(
gep,
content=" %elem_ptr = getelementptr inbounds [10 x i32], ptr %0, i32 0, i32 2",
)
assert_true(gep.asValueEnum() is GetElementPtrInst(_))
}impl Instruction for GetElementPtrInstimpl User for GetElementPtrInstimpl Value for GetElementPtrInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let array_ty = ctx.getArrayType(i32_ty, 10)
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ptr_ty, [ptr_ty])
let fval = mod.addFunction(fty, "gep_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
let zero = ctx.getConstInt32(0)
let two = ctx.getConstInt32(2)
builder.setInsertPoint(bb)
let gep = builder.createGEP(arg, array_ty, [zero, two])
inspect(gep.getName(), content="None")
gep.setName("elem_ptr")
inspect(gep.getName(), content="Some(\"elem_ptr\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let array_ty = ctx.getArrayType(i32_ty, 10)
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ptr_ty, [ptr_ty])
let fval = mod.addFunction(fty, "gep_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
let zero = ctx.getConstInt32(0)
let two = ctx.getConstInt32(2)
builder.setInsertPoint(bb)
let gep = builder.createGEP(arg, array_ty, [zero, two])
inspect(gep.getValueRepr(), content="%1")
gep.setName("elem_ptr")
inspect(gep.getValueRepr(), content="%elem_ptr")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let array_ty = ctx.getArrayType(i32_ty, 10)
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ptr_ty, [ptr_ty])
let fval = mod.addFunction(fty, "gep_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
let zero = ctx.getConstInt32(0)
let two = ctx.getConstInt32(2)
builder.setInsertPoint(bb)
let gep = builder.createGEP(arg, array_ty, [zero, two])
inspect(gep.getName(), content="None")
gep.setName("elem_ptr")
inspect(gep.getName(), content="Some(\"elem_ptr\")")
}impl Show for GetElementPtrInstpub struct GlobalConstant {
uid : UInt64
vty : &Type
elementTy : &Type
users : Array[&User]
mod : Module
name : String
linkage : Ref[Linkage]
visibility : Ref[Visibility]
unnamed_addr : Ref[UnnamedAddr]
value : &Constant
}impl GlobalValue for GlobalConstantimpl Value for GlobalConstantimpl Show for GlobalConstantpub enum GlobalValueEnum {
Function(Function)
GlobalVariable(GlobalVariable)
GlobalConstant(GlobalConstant)
}pub struct GlobalVariable {
uid : UInt64
vty : &Type
elementTy : &Type
users : Array[&User]
mod : Module
name : String
linkage : Ref[Linkage]
visibility : Ref[Visibility]
unnamed_addr : Ref[UnnamedAddr]
initializer : &Constant?
initializerTy : &Type
}impl GlobalValue for GlobalVariableimpl Value for GlobalVariableimpl Show for GlobalVariablepub struct ICmpInst {
uid : UInt64
vty : Int1Type
lhs : &Value
rhs : &Value
name : String?
parent : Function
users : Array[&User]
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
predicate : IntPredicate
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "icmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let eq_cmp = builder.createICmp(EQ, arg1, arg2, name="eq_cmp")
inspect(eq_cmp, content=" %eq_cmp = icmp eq i32 %0, %1")
assert_true(eq_cmp.asValueEnum() is ICmpInst(_))
let ne_cmp = builder.createICmp(NE, arg1, arg2, name="ne_cmp")
inspect(ne_cmp, content=" %ne_cmp = icmp ne i32 %0, %1")
let sgt_cmp = builder.createICmp(SGT, arg1, arg2, name="sgt_cmp")
inspect(sgt_cmp, content=" %sgt_cmp = icmp sgt i32 %0, %1")
let ugt_cmp = builder.createICmp(UGT, arg1, arg2, name="ugt_cmp")
inspect(ugt_cmp, content=" %ugt_cmp = icmp ugt i32 %0, %1")
}impl Instruction for ICmpInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "icmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let eq_cmp = builder.createICmp(EQ, arg1, arg2)
inspect(eq_cmp.getName(), content="None")
eq_cmp.setName("eq_cmp")
inspect(eq_cmp.getName(), content="Some(\"eq_cmp\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "icmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let eq_cmp = builder.createICmp(EQ, arg1, arg2)
inspect(eq_cmp.getValueRepr(), content="%2")
eq_cmp.setName("eq_cmp")
inspect(eq_cmp.getValueRepr(), content="%eq_cmp")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "icmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let eq_cmp = builder.createICmp(EQ, arg1, arg2)
inspect(eq_cmp.getName(), content="None")
eq_cmp.setName("eq_cmp")
inspect(eq_cmp.getName(), content="Some(\"eq_cmp\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "ashr_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let ashr_result = builder.createAShr(arg1, arg2, name="result")
inspect(ashr_result, content=" %result = ashr i32 %0, %1")
assert_true(ashr_result.asValueEnum() is BinaryInst(_))
let twenty = ctx.getConstInt32(20) // 10100 in binary
let two = ctx.getConstInt32(2) // shift right by 2
let five = builder.createAShr(twenty, two) // 101 in binary = 5
inspect(five, content="i32 5")
assert_true(five.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "add_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createAdd(arg1, arg2, name="sum")
inspect(add, content=" %sum = add i32 %0, %1")
assert_true(add.asValueEnum() is BinaryInst(_))
let one = ctx.getConstInt32(1)
let two = ctx.getConstInt32(2)
let three = builder.createAdd(one, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}fn IRBuilder::createAlloca(self : IRBuilder, data_ty : &Type, addressSpace? : AddressSpace, name? : String) -> AllocaInst raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "foo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let inst = builder.createAlloca(i32_ty, name="var1")
inspect(inst, content=" %var1 = alloca i32, align 4")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "and_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let and_result = builder.createAnd(arg1, arg2, name="result")
inspect(and_result, content=" %result = and i32 %0, %1")
assert_true(and_result.asValueEnum() is BinaryInst(_))
let val1 = ctx.getConstInt32(12) // 1100 in binary
let val2 = ctx.getConstInt32(10) // 1010 in binary
let result = builder.createAnd(val1, val2) // 1000 in binary = 8
inspect(result, content="i32 8")
assert_true(result.asValueEnum() is ConstantInt(_))
}fn IRBuilder::createBitCast(self : IRBuilder, src_val : &Value, dst_ty : &PrimitiveType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [i32_ty])
let fval = mod.addFunction(fty, "bitcast_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let bitcast = builder.createBitCast(arg, f32_ty, name="bits")
inspect(bitcast, content=" %bits = bitcast i32 %0 to float")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "br_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let target_bb = fval.addBasicBlock(name="target")
builder.setInsertPoint(entry_bb)
let br = builder.createBr(target_bb)
inspect(br, content=" br label %target")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let add_fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let main_fty = ctx.getFunctionType(i32_ty, [])
let add_func = mod.addFunction(add_fty, "add")
let main_func = mod.addFunction(main_fty, "main")
let bb = main_func.addBasicBlock(name="entry")
let arg1 = ctx.getConstInt32(10)
let arg2 = ctx.getConstInt32(20)
builder.setInsertPoint(bb)
let call = builder.createCall(add_func, [arg1, arg2], name="sum")
inspect(call, content=" %sum = call i32 @add(i32 10, i32 20)")
}fn IRBuilder::createCondBr(self : IRBuilder, cond : &Value, true_dst : BasicBlock, false_dst : BasicBlock) -> &Instruction raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i1_ty])
let fval = mod.addFunction(fty, "cond_br_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let true_bb = fval.addBasicBlock(name="true_branch")
let false_bb = fval.addBasicBlock(name="false_branch")
let cond = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let cond_br = builder.createCondBr(cond, true_bb, false_bb)
inspect(
cond_br,
content=" br i1 %0, label %true_branch, label %false_branch",
)
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "exact_sdiv_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let div = builder.createExactSDiv(arg1, arg2, name="quotient")
inspect(div, content = " %quotient = sdiv exact i32 %0, %1")
assert_true(div.asValueEnum() is BinaryInst(_))
let twelve = ctx.getConstInt32(12)
let three = ctx.getConstInt32(3)
let four = builder.createExactSDiv(twelve, three)
inspect(four, content = " %2 = sdiv exact i32 12, 3")
assert_true(four.asValueEnum() is ConstantInt(_))let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "exact_udiv_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let div = builder.createExactUDiv(arg1, arg2, name="quotient")
inspect(div, content = " %quotient = udiv exact i32 %0, %1")
assert_true(div.asValueEnum() is BinaryInst(_))
let twelve = ctx.getConstInt32(12)
let three = ctx.getConstInt32(3)
let four = builder.createExactUDiv(twelve, three)
inspect(four, content = " %2 = udiv exact i32 12, 3")
assert_true(four.asValueEnum() is ConstantInt(_))let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(i32_ty, [struct_ty])
let fval = mod.addFunction(fty, "extractvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let extract = builder.createExtractValue(aggregate, 0, name="field")
inspect(extract, content = " %field = extractvalue { i32, i32 } %0, 0")let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fadd_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let fadd = builder.createFAdd(arg1, arg2, name="sum")
inspect(fadd, content = " %sum = fadd float %0, %1")
assert_true(fadd.asValueEnum() is BinaryInst(_))
let one = ctx.getConstFloat(1.0)
let two = ctx.getConstFloat(2.0)
let three = builder.createFAdd(one, two)
inspect(three, content = " %2 = fadd float 0x3FF0000000000000, 0x4000000000000000")
assert_true(three.asValueEnum() is ConstantFP(_))
let nnan_fadd = builder.createFAdd(arg1, arg2, name="sum_nnan", fast_math=[NoNaNs])
inspect(nnan_fadd, content = " %sum_nnan = fadd nnan float %0, %1")
let ninf_fadd = builder.createFAdd(arg1, arg2, name="sum_ninf", fast_math=[NoInfs])
inspect(ninf_fadd, content = " %sum_ninf = fadd ninf float %0, %1")
let nnan_ninf_fadd = builder.createFAdd(
arg1, arg2, name="sum_nnan_ninf", fast_math=[NoNaNs, NoInfs]
)
inspect(nnan_ninf_fadd, content = " %sum_nnan_ninf = fadd nnan ninf float %0, %1")test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fcmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg0 = fval.getArg(0).unwrap()
let arg1 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let oeq_cmp = builder.createFCmp(
FloatPredicate::OEQ,
arg0,
arg1,
name="oeq_cmp",
)
inspect(oeq_cmp, content=" %oeq_cmp = fcmp oeq float %0, %1")
assert_true(oeq_cmp.asValueEnum() is FCmpInst(_))
let val1 = ctx.getConstFloat(3.14)
let val2 = ctx.getConstFloat(3.14)
let result = builder.createFCmpOEQ(val1, val2)
inspect(result, content="i1 true")
assert_true(result.asValueEnum() is ConstantInt(_))
let ogt_cmp = builder.createFCmpOGT(arg0, arg1, name="ogt_cmp")
inspect(ogt_cmp, content=" %ogt_cmp = fcmp ogt float %0, %1")
let oge_cmp = builder.createFCmpOGE(arg0, arg1, name="oge_cmp")
inspect(oge_cmp, content=" %oge_cmp = fcmp oge float %0, %1")
let olt_cmp = builder.createFCmpOLT(arg0, arg1, name="olt_cmp")
inspect(olt_cmp, content=" %olt_cmp = fcmp olt float %0, %1")
let ole_cmp = builder.createFCmpOLE(arg0, arg1, name="ole_cmp")
inspect(ole_cmp, content=" %ole_cmp = fcmp ole float %0, %1")
let one_cmp = builder.createFCmpONE(arg0, arg1, name="one_cmp")
inspect(one_cmp, content=" %one_cmp = fcmp one float %0, %1")
let ord_cmp = builder.createFCmpORD(arg0, arg1, name="ord_cmp")
inspect(ord_cmp, content=" %ord_cmp = fcmp ord float %0, %1")
let ueq_cmp = builder.createFCmpUEQ(arg0, arg1, name="ueq_cmp")
inspect(ueq_cmp, content=" %ueq_cmp = fcmp ueq float %0, %1")
let ugt_cmp = builder.createFCmpUGT(arg0, arg1, name="ugt_cmp")
inspect(ugt_cmp, content=" %ugt_cmp = fcmp ugt float %0, %1")
let uge_cmp = builder.createFCmpUGE(arg0, arg1, name="uge_cmp")
inspect(uge_cmp, content=" %uge_cmp = fcmp uge float %0, %1")
let ult_cmp = builder.createFCmpULT(arg0, arg1, name="ult_cmp")
inspect(ult_cmp, content=" %ult_cmp = fcmp ult float %0, %1")
let ule_cmp = builder.createFCmpULE(arg0, arg1, name="ule_cmp")
inspect(ule_cmp, content=" %ule_cmp = fcmp ule float %0, %1")
let une_cmp = builder.createFCmpUNE(arg0, arg1, name="une_cmp")
inspect(une_cmp, content=" %une_cmp = fcmp une float %0, %1")
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fdiv_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let fdiv = builder.createFDiv(arg1, arg2, name="quotient")
inspect(fdiv, content = " %quotient = fdiv float %0, %1")
assert_true(fdiv.asValueEnum() is BinaryInst(_))
let eight = ctx.getConstFloat(8.0)
let two = ctx.getConstFloat(2.0)
let four = builder.createFDiv(eight, two)
inspect(four, content = " %2 = fdiv float 0x4020000000000000, 0x4000000000000000")
assert_true(four.asValueEnum() is ConstantFP(_))let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fmul_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let fmul = builder.createFMul(arg1, arg2, name="product")
inspect(fmul, content = " %product = fmul float %0, %1")
assert_true(fmul.asValueEnum() is BinaryInst(_))
let three = ctx.getConstFloat(3.0)
let four = ctx.getConstFloat(4.0)
let twelve = builder.createFMul(three, four)
inspect(twelve, content = " %2 = fmul float 0x4008000000000000, 0x4010000000000000")
assert_true(twelve.asValueEnum() is ConstantFP(_))test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty])
let fval = mod.addFunction(fty, "fneg_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let fneg = builder.createFNeg(arg, name="neg_value")
inspect(fneg, content=" %neg_value = fneg float %0")
assert_true(fneg.asValueEnum() is FNegInst(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let f64_ty = ctx.getDoubleTy()
let fty = ctx.getFunctionType(f64_ty, [f32_ty])
let fval = mod.addFunction(fty, "fpext_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let fpext = builder.createFPExt(arg, f64_ty, name="extended")
inspect(fpext, content=" %extended = fpext float %0 to double")
}fn IRBuilder::createFPToSI(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [f32_ty])
let fval = mod.addFunction(fty, "fptosi_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let fptosi = builder.createFPToSI(arg, i32_ty, name="converted")
inspect(fptosi, content=" %converted = fptosi float %0 to i32")
}fn IRBuilder::createFPToUI(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [f32_ty])
let fval = mod.addFunction(fty, "fptoui_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let fptoui = builder.createFPToUI(arg, i32_ty, name="converted")
inspect(fptoui, content=" %converted = fptoui float %0 to i32")
assert_true(fptoui.asValueEnum() is CastInst(_))
let float_val = ctx.getConstFloat(3.14)
let int_val = builder.createFPToUI(float_val, i32_ty)
inspect(int_val, content="i32 3")
assert_true(int_val.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f64_ty = ctx.getDoubleTy()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f64_ty])
let fval = mod.addFunction(fty, "fptrunc_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let fptrunc = builder.createFPTrunc(arg, f32_ty, name="truncated")
inspect(fptrunc, content=" %truncated = fptrunc double %0 to float")
assert_true(fptrunc.asValueEnum() is CastInst(_))
let big_val = ctx.getConstDouble(3.14159)
let small_val = builder.createFPTrunc(big_val, f32_ty)
assert_true(small_val.asValueEnum() is ConstantFP(_))
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "frem_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let frem = builder.createFRem(arg1, arg2, name="remainder")
inspect(frem, content = " %remainder = frem float %0, %1")
assert_true(frem.asValueEnum() is BinaryInst(_))
let five_and_half = ctx.getConstFloat(5.5)
let two = ctx.getConstFloat(2.0)
let one_and_half = builder.createFRem(five_and_half, two)
inspect(one_and_half, content = " %2 = frem float 0x4016000000000000, 0x4000000000000000")
assert_true(one_and_half.asValueEnum() is ConstantFP(_))let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [f32_ty, f32_ty])
let fval = mod.addFunction(fty, "fsub_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let fsub = builder.createFSub(arg1, arg2, name="diff")
inspect(fsub, content = " %diff = fsub float %0, %1")
assert_true(fsub.asValueEnum() is BinaryInst(_))
let five = ctx.getConstFloat(5.0)
let two = ctx.getConstFloat(2.0)
let three = builder.createFSub(five, two)
inspect(three, content = " %2 = fsub float 0x4014000000000000, 0x4000000000000000")
assert_true(three.asValueEnum() is ConstantFP(_))test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let array_ty = ctx.getArrayType(i32_ty, 10)
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ctx.getPtrTy(), [ptr_ty])
let fval = mod.addFunction(fty, "gep_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
let zero = ctx.getConstInt32(0)
let two = ctx.getConstInt32(2)
builder.setInsertPoint(bb)
let gep = builder.createGEP(
arg,
array_ty,
[zero, two],
name="elem_ptr",
inbounds=true,
)
inspect(
gep,
content=" %elem_ptr = getelementptr inbounds [10 x i32], ptr %0, i32 0, i32 2",
)
}fn IRBuilder::createGlobalString(self : IRBuilder, string : String, name? : String) -> GlobalConstant raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "icmp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg0 = fval.getArg(0).unwrap()
let arg1 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let eq_cmp = builder.createICmp(IntPredicate::EQ, arg0, arg1, name="eq_cmp")
inspect(eq_cmp, content=" %eq_cmp = icmp eq i32 %0, %1")
assert_true(eq_cmp.asValueEnum() is ICmpInst(_))
let val1 = ctx.getConstInt32(5)
let val2 = ctx.getConstInt32(5)
let result = builder.createICmpEQ(val1, val2)
inspect(result, content="i1 true")
assert_true(result.asValueEnum() is ConstantInt(_))
let ne_cmp = builder.createICmpNE(arg0, arg1, name="ne_cmp")
inspect(ne_cmp, content=" %ne_cmp = icmp ne i32 %0, %1")
let sgt_cmp = builder.createICmpSGT(arg0, arg1, name="sgt_cmp")
inspect(sgt_cmp, content=" %sgt_cmp = icmp sgt i32 %0, %1")
let sge_cmp = builder.createICmpSGE(arg0, arg1, name="sge_cmp")
inspect(sge_cmp, content=" %sge_cmp = icmp sge i32 %0, %1")
let slt_cmp = builder.createICmpSLT(arg0, arg1, name="slt_cmp")
inspect(slt_cmp, content=" %slt_cmp = icmp slt i32 %0, %1")
let sle_cmp = builder.createICmpSLE(arg0, arg1, name="sle_cmp")
inspect(sle_cmp, content=" %sle_cmp = icmp sle i32 %0, %1")
let ugt_cmp = builder.createICmpUGT(arg0, arg1, name="ugt_cmp")
inspect(ugt_cmp, content=" %ugt_cmp = icmp ugt i32 %0, %1")
let uge_cmp = builder.createICmpUGE(arg0, arg1, name="uge_cmp")
inspect(uge_cmp, content=" %uge_cmp = icmp uge i32 %0, %1")
let ult_cmp = builder.createICmpULT(arg0, arg1, name="ult_cmp")
inspect(ult_cmp, content=" %ult_cmp = icmp ult i32 %0, %1")
let ule_cmp = builder.createICmpULE(arg0, arg1, name="ule_cmp")
inspect(ule_cmp, content=" %ule_cmp = icmp ule i32 %0, %1")
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(struct_ty, [struct_ty, i32_ty])
let fval = mod.addFunction(fty, "insertvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
let new_value = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let insert = builder.createInsertValue(aggregate, new_value, 1, name="updated")
inspect(insert, content = " %updated = insertvalue { i32, i32 } %0, i32 %1, 1")test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i64_ty = ctx.getInt64Ty()
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(ptr_ty, [i64_ty])
let fval = mod.addFunction(fty, "inttoptr_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let inttoptr = builder.createIntToPtr(arg, name="ptr")
inspect(inttoptr, content=" %ptr = inttoptr i64 %0 to ptr")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "lshr_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let lshr_result = builder.createLShr(arg1, arg2, name="result")
inspect(lshr_result, content=" %result = lshr i32 %0, %1")
assert_true(lshr_result.asValueEnum() is BinaryInst(_))
let twenty = ctx.getConstInt32(20) // 10100 in binary
let two = ctx.getConstInt32(2) // shift right by 2
let five = builder.createLShr(twenty, two) // 101 in binary = 5
inspect(five, content="i32 5")
assert_true(five.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(ctx.getVoidTy(), [])
let fval = mod.addFunction(fty, "load_demo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let alloca = builder.createAlloca(i32_ty, name="temp")
let load = builder.createLoad(i32_ty, alloca, name="val")
inspect(load, content=" %val = load i32, ptr %temp, align 4")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "mul_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let mul = builder.createMul(arg1, arg2, name="product")
inspect(mul, content=" %product = mul i32 %0, %1")
assert_true(mul.asValueEnum() is BinaryInst(_))
let three = ctx.getConstInt32(3)
let four = ctx.getConstInt32(4)
let twelve = builder.createMul(three, four)
inspect(twelve, content="i32 12")
assert_true(twelve.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nsw_add_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createNSWAdd(arg1, arg2, name="sum")
inspect(add, content=" %sum = add nsw i32 %0, %1")
assert_true(add.asValueEnum() is BinaryInst(_))
let one = ctx.getConstInt32(1)
let two = ctx.getConstInt32(2)
let three = builder.createNSWAdd(one, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nsw_mul_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let mul = builder.createNSWMul(arg1, arg2, name="product")
inspect(mul, content=" %product = mul nsw i32 %0, %1")
assert_true(mul.asValueEnum() is BinaryInst(_))
let three = ctx.getConstInt32(3)
let four = ctx.getConstInt32(4)
let twelve = builder.createNSWMul(three, four)
inspect(twelve, content="i32 12")
assert_true(twelve.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nsw_sub_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let sub = builder.createNSWSub(arg1, arg2, name="diff")
inspect(sub, content=" %diff = sub nsw i32 %0, %1")
assert_true(sub.asValueEnum() is BinaryInst(_))
let five = ctx.getConstInt32(5)
let two = ctx.getConstInt32(2)
let three = builder.createNSWSub(five, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nuw_add_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let add = builder.createNUWAdd(arg1, arg2, name="sum")
inspect(add, content=" %sum = add nuw i32 %0, %1")
assert_true(add.asValueEnum() is BinaryInst(_))
let one = ctx.getConstInt32(1)
let two = ctx.getConstInt32(2)
let three = builder.createNUWAdd(one, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nuw_mul_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let mul = builder.createNUWMul(arg1, arg2, name="product")
inspect(mul, content=" %product = mul nuw i32 %0, %1")
assert_true(mul.asValueEnum() is BinaryInst(_))
let three = ctx.getConstInt32(3)
let four = ctx.getConstInt32(4)
let twelve = builder.createNUWMul(three, four)
inspect(twelve, content="i32 12")
assert_true(twelve.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "nuw_sub_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let sub = builder.createNUWSub(arg1, arg2, name="diff")
inspect(sub, content=" %diff = sub nuw i32 %0, %1")
assert_true(sub.asValueEnum() is BinaryInst(_))
let five = ctx.getConstInt32(5)
let two = ctx.getConstInt32(2)
let three = builder.createNUWSub(five, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "or_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let or_result = builder.createOr(arg1, arg2, name="result")
inspect(or_result, content=" %result = or i32 %0, %1")
assert_true(or_result.asValueEnum() is BinaryInst(_))
let val1 = ctx.getConstInt32(12) // 1100 in binary
let val2 = ctx.getConstInt32(10) // 1010 in binary
let result = builder.createOr(val1, val2) // 1110 in binary = 14
inspect(result, content="i32 14")
assert_true(result.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block_bb = fval.addBasicBlock(name="block")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block_bb)
inspect(phi, content=" %result = phi i32 [ 10, %entry ], [ 20, %block ]")
}fn IRBuilder::createPtrToInt(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i64_ty = ctx.getInt64Ty()
let ptr_ty = ctx.getPtrTy()
let fty = ctx.getFunctionType(i64_ty, [ptr_ty])
let fval = mod.addFunction(fty, "ptrtoint_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let ptrtoint = builder.createPtrToInt(arg, i64_ty, name="int_val")
inspect(ptrtoint, content=" %int_val = ptrtoint ptr %0 to i64")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty])
let fval = mod.addFunction(fty, "direct_ret")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let ret = builder.createRet(arg)
inspect(ret, content=" ret i32 %0")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "direct_ret")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ret = builder.createRetVoid()
inspect(ret, content=" ret void")
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "sdiv_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let div = builder.createSDiv(arg1, arg2, name="quotient")
inspect(div, content = " %quotient = sdiv i32 %0, %1")
assert_true(div.asValueEnum() is BinaryInst(_))
let twelve = ctx.getConstInt32(12)
let three = ctx.getConstInt32(3)
let four = builder.createSDiv(twelve, three)
inspect(four, content = " %2 = sdiv i32 12, 3")
assert_true(four.asValueEnum() is ConstantInt(_))fn IRBuilder::createSExt(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let fty = ctx.getFunctionType(i64_ty, [i32_ty])
let fval = mod.addFunction(fty, "sext_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let sext = builder.createSExt(arg, i64_ty, name="extended")
inspect(sext, content=" %extended = sext i32 %0 to i64")
assert_true(sext.asValueEnum() is CastInst(_))
let small_val = ctx.getConstInt32(-42)
let big_val = builder.createSExt(small_val, i64_ty)
inspect(big_val, content="i64 -42")
assert_true(big_val.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [i32_ty])
let fval = mod.addFunction(fty, "sitofp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let sitofp = builder.createSIToFP(arg, f32_ty, name="converted")
inspect(sitofp, content=" %converted = sitofp i32 %0 to float")
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "srem_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let rem = builder.createSRem(arg1, arg2, name="remainder")
inspect(rem, content = " %remainder = srem i32 %0, %1")
assert_true(rem.asValueEnum() is BinaryInst(_))
let thirteen = ctx.getConstInt32(13)
let five = ctx.getConstInt32(5)
let three = builder.createSRem(thirteen, five)
inspect(three, content = " %2 = srem i32 13, 5")
assert_true(three.asValueEnum() is ConstantInt(_))test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i1_ty, i32_ty, i32_ty])
let fval = mod.addFunction(fty, "select_demo")
let bb = fval.addBasicBlock(name="entry")
let cond = fval.getArg(0).unwrap()
let true_val = fval.getArg(1).unwrap()
let false_val = fval.getArg(2).unwrap()
builder.setInsertPoint(bb)
let select = builder.createSelect(cond, true_val, false_val, name="result")
inspect(select, content=" %result = select i1 %0, i32 %1, i32 %2")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "shl_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let shl_result = builder.createShl(arg1, arg2, name="result")
inspect(shl_result, content=" %result = shl i32 %0, %1")
assert_true(shl_result.asValueEnum() is BinaryInst(_))
let val = ctx.getConstInt32(5) // 101 in binary
let shift = ctx.getConstInt32(2) // shift left by 2
let result = builder.createShl(val, shift) // 10100 in binary = 20
inspect(result, content="i32 20")
assert_true(result.asValueEnum() is ConstantInt(_))
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(ctx.getVoidTy(), [])
let fval = mod.addFunction(fty, "store_demo")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let alloca = builder.createAlloca(i32_ty, name="temp")
let const_val = ctx.getConstInt32(42)
let store = builder.createStore(const_val, alloca)
inspect(store, content=" store i32 42, ptr %temp, align 4")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "sub_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let sub = builder.createSub(arg1, arg2, name="diff")
inspect(sub, content=" %diff = sub i32 %0, %1")
assert_true(sub.asValueEnum() is BinaryInst(_))
let five = ctx.getConstInt32(5)
let two = ctx.getConstInt32(2)
let three = builder.createSub(five, two)
inspect(three, content="i32 3")
assert_true(three.asValueEnum() is ConstantInt(_))
}fn IRBuilder::createSwitch(self : IRBuilder, cond : &Value, defaultDest : BasicBlock) -> SwitchInst raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i32_ty])
let fval = mod.addFunction(fty, "switch_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let case1_bb = fval.addBasicBlock(name="case1")
let default_bb = fval.addBasicBlock(name="default")
let value = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let switch = builder.createSwitch(value, default_bb)
let case_val = ctx.getConstInt32(42)
switch.addCase(case_val, case1_bb)
let expect =
#| switch i32 %0, label %default [
#| i32 42, label %case1
#| ]
inspect(switch, content=expect)
}fn IRBuilder::createTrunc(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i64_ty = ctx.getInt64Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i64_ty])
let fval = mod.addFunction(fty, "trunc_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let trunc = builder.createTrunc(arg, i32_ty, name="truncated")
inspect(trunc, content=" %truncated = trunc i64 %0 to i32")
assert_true(trunc.asValueEnum() is CastInst(_))
let big_val = ctx.getConstInt64(0x123456789L)
let small_val = builder.createTrunc(big_val, i32_ty)
inspect(small_val, content="i32 591751049")
assert_true(small_val.asValueEnum() is ConstantInt(_))
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "udiv_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let div = builder.createUDiv(arg1, arg2, name="quotient")
inspect(div, content = " %quotient = udiv i32 %0, %1")
assert_true(div.asValueEnum() is BinaryInst(_))
let twelve = ctx.getConstInt32(12)
let three = ctx.getConstInt32(3)
let four = builder.createUDiv(twelve, three)
inspect(four, content = " %2 = udiv i32 12, 3")
assert_true(four.asValueEnum() is ConstantInt(_))test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let f32_ty = ctx.getFloatTy()
let fty = ctx.getFunctionType(f32_ty, [i32_ty])
let fval = mod.addFunction(fty, "uitofp_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let uitofp = builder.createUIToFP(arg, f32_ty, name="converted")
inspect(uitofp, content=" %converted = uitofp i32 %0 to float")
assert_true(uitofp.asValueEnum() is CastInst(_))
let int_val = ctx.getConstInt32(42)
let float_val = builder.createUIToFP(int_val, f32_ty)
assert_true(float_val.asValueEnum() is ConstantFP(_))
}let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "urem_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let rem = builder.createURem(arg1, arg2, name="remainder")
inspect(rem, content = " %remainder = urem i32 %0, %1")
assert_true(rem.asValueEnum() is BinaryInst(_))
let thirteen = ctx.getConstInt32(13)
let five = ctx.getConstInt32(5)
let three = builder.createURem(thirteen, five)
inspect(three, content = " %2 = urem i32 13, 5")
assert_true(three.asValueEnum() is ConstantInt(_))test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i32_ty, i32_ty])
let fval = mod.addFunction(fty, "xor_demo")
let bb = fval.addBasicBlock(name="entry")
let arg1 = fval.getArg(0).unwrap()
let arg2 = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let xor_result = builder.createXor(arg1, arg2, name="result")
inspect(xor_result, content=" %result = xor i32 %0, %1")
assert_true(xor_result.asValueEnum() is BinaryInst(_))
let val1 = ctx.getConstInt32(12) // 1100 in binary
let val2 = ctx.getConstInt32(10) // 1010 in binary
let result = builder.createXor(val1, val2) // 0110 in binary = 6
inspect(result, content="i32 6")
assert_true(result.asValueEnum() is ConstantInt(_))
}fn IRBuilder::createZExt(self : IRBuilder, src_val : &Value, dst_ty : &IntegerType, name? : String) -> &Value raisetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let i64_ty = ctx.getInt64Ty()
let fty = ctx.getFunctionType(i64_ty, [i32_ty])
let fval = mod.addFunction(fty, "zext_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let zext = builder.createZExt(arg, i64_ty, name="extended")
inspect(zext, content=" %extended = zext i32 %0 to i64")
assert_true(zext.asValueEnum() is CastInst(_))
let small_val = ctx.getConstInt32(42)
let big_val = builder.createZExt(small_val, i64_ty)
inspect(big_val, content="i64 42")
assert_true(big_val.asValueEnum() is ConstantInt(_))
}pub struct InsertValueInst {
uid : UInt64
vty : &Type
users : Array[&User]
aggregate : &Value
insert_val : &Value
name : String?
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
indices : Array[Int]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(struct_ty, [struct_ty, i32_ty])
let fval = mod.addFunction(fty, "insertvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
let new_value = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let insert = builder.createInsertValue(
aggregate,
new_value,
[1],
name="updated",
)
inspect(insert, content=" %updated = insertvalue { i32, i32 } %0, i32 %1, 1")
assert_true(insert.asValueEnum() is InsertValueInst(_))
}impl Instruction for InsertValueInstimpl User for InsertValueInstimpl Value for InsertValueInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(struct_ty, [struct_ty, i32_ty])
let fval = mod.addFunction(fty, "insertvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
let new_value = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let insert = builder.createInsertValue(aggregate, new_value, [1])
inspect(insert.getName(), content="None")
insert.setName("updated")
inspect(insert.getName(), content="Some(\"updated\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(struct_ty, [struct_ty, i32_ty])
let fval = mod.addFunction(fty, "insertvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
let new_value = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let insert = builder.createInsertValue(aggregate, new_value, [1])
inspect(insert.getValueRepr(), content="%2")
insert.setName("updated")
inspect(insert.getValueRepr(), content="%updated")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let struct_ty = ctx.getStructType([i32_ty, i32_ty])
let fty = ctx.getFunctionType(struct_ty, [struct_ty, i32_ty])
let fval = mod.addFunction(fty, "insertvalue_demo")
let bb = fval.addBasicBlock(name="entry")
let aggregate = fval.getArg(0).unwrap()
let new_value = fval.getArg(1).unwrap()
builder.setInsertPoint(bb)
let insert = builder.createInsertValue(aggregate, new_value, [1])
inspect(insert.getName(), content="None")
insert.setName("updated")
inspect(insert.getName(), content="Some(\"updated\")")
}impl Show for InsertValueInstpub enum InstEnum {
AllocaInst(AllocaInst)
LoadInst(LoadInst)
ExtractValueInst(ExtractValueInst)
FNegInst(FNegInst)
CastInst(CastInst)
BinaryInst(BinaryInst)
ICmpInst(ICmpInst)
FCmpInst(FCmpInst)
StoreInst(StoreInst)
GetElementPtrInst(GetElementPtrInst)
SelectInst(SelectInst)
InsertValueInst(InsertValueInst)
PHINode(PHINode)
ReturnInst(ReturnInst)
BranchInst(BranchInst)
SwitchInst(SwitchInst)
CallInst(CallInst)
}impl Eq for Int16Arrayimpl Hash for Int16Arrayimpl Show for Int16Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn Int16Array::inner(self : Int16Array) -> Array[Int16]test {
let ctx = Context::new()
inspect(ctx.getInt16Ty(), content="i16")
}impl IntegerType for Int16Typeimpl PrimitiveType for Int16Typetest {
let ctx = Context::new()
inspect(ctx.getInt1Ty(), content="i1")
}impl IntegerType for Int1Typeimpl PrimitiveType for Int1Typeimpl Eq for Int32Arrayimpl Hash for Int32Arrayimpl Show for Int32Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn Int32Array::inner(self : Int32Array) -> Array[Int]test {
let ctx = Context::new()
inspect(ctx.getInt32Ty(), content="i32")
}impl IntegerType for Int32Typeimpl PrimitiveType for Int32Typeimpl Eq for Int64Arrayimpl Hash for Int64Arrayimpl Show for Int64Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn Int64Array::inner(self : Int64Array) -> Array[Int64]test {
let ctx = Context::new()
inspect(ctx.getInt64Ty(), content="i64")
}impl IntegerType for Int64Typeimpl PrimitiveType for Int64Typetest {
let ctx = Context::new()
inspect(ctx.getInt8Ty(), content="i8")
}impl IntegerType for Int8Typeimpl PrimitiveType for Int8Typepub(all) enum IntPredicate {
EQ
NE
UGT
UGE
ULT
ULE
SGT
SGE
SLT
SLE
}impl Show for IntPredicateimpl Eq for IntegerTypeEnumimpl Hash for IntegerTypeEnumimpl Show for IntegerTypeEnumpub(all) enum Linkage {
External
AvailableExternally
LinkOnceAny
LinkOnceODR
WeakAny
WeakODR
Appending
Internal
Private
ExternalWeak
Common
}pub(all) struct LoadInst {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
ptr : &Value
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
isVolatile : Bool
atomicOrdering : AtomicOrdering
align : Align
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [ptr_ty])
let fval = mod.addFunction(fty, "load_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
ptr.setName("arg0")
let val = builder.createLoad(i32_ty, ptr, name="val")
let _ = builder.createRet(val)
inspect(val, content=" %val = load i32, ptr %arg0, align 4")
}impl Instruction for LoadInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [ptr_ty])
let fval = mod.addFunction(fty, "load_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
let val = builder.createLoad(i32_ty, ptr)
inspect(val.getName(), content="None")
val.setName("val")
inspect(val.getName(), content="Some(\"val\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [ptr_ty])
let fval = mod.addFunction(fty, "load_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
let val = builder.createLoad(i32_ty, ptr)
inspect(val.getValueRepr(), content="%1")
val.setName("val")
inspect(val.getValueRepr(), content="%val")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [ptr_ty])
let fval = mod.addFunction(fty, "load_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
let val = builder.createLoad(i32_ty, ptr)
inspect(val.getName(), content="None")
val.setName("val")
inspect(val.getName(), content="Some(\"val\")")
}pub struct MDString {
str : String
}impl AbstractType for MetadataTypeimpl Type for MetadataTypeimpl Eq for MetadataTypeimpl Hash for MetadataTypeimpl Show for MetadataTypepub struct Module {
context : Context
functions : Map[String, Function]
globals : Map[String, &GlobalValue]
global_strings : Map[String, GlobalConstant]
globalstr_count : Int
srcFileName : String
moduleID : String
dataLayout : DataLayout
}fn Module::addFunction(self : Module, fty : FunctionType, name : String, linkage? : Linkage, visibility? : Visibility, unnamed_addr? : UnnamedAddr, addressSpace? : AddressSpace) -> Function raise LLVMValueErrorfn Module::addGlobalConstant(self : Module, ty : &Type, name : String, value : &Constant, linkage? : Linkage, visibility? : Visibility, unnamed_addr? : UnnamedAddr) -> GlobalConstant raise LLVMValueErrorfn Module::addGlobalVariable(self : Module, ty : &Type, name : String, initializer? : &Constant, linkage? : Linkage, visibility? : Visibility, unnamed_addr? : UnnamedAddr) -> GlobalVariable raise LLVMValueErrorpub enum NumberArrayEnum {
Int8Array(Int8Array)
Int16Array(Int16Array)
Int32Array(Int32Array)
Int64Array(Int64Array)
UInt8Array(UInt8Array)
UInt16Array(UInt16Array)
UInt32Array(UInt32Array)
UInt64Array(UInt64Array)
FloatArray(FloatArray)
DoubleArray(DoubleArray)
}impl Eq for NumberArrayEnumimpl Hash for NumberArrayEnumimpl Show for NumberArrayEnumpub struct PHINode {
uid : UInt64
vty : &Type
users : Array[&User]
name : String?
incomings : Array[(&Value, BasicBlock)]
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block_bb = fval.addBasicBlock(name="block")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block_bb)
inspect(phi, content=" %result = phi i32 [ 10, %entry ], [ 20, %block ]")
assert_true(phi.asValueEnum() is PHINode(_))
}impl Instruction for PHINodetest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_demo")
let entry_bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(entry_bb)
let phi = builder.createPHI(i32_ty)
inspect(phi.getName(), content="None")
phi.setName("result")
inspect(phi.getName(), content="Some(\"result\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_demo")
let entry_bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(entry_bb)
let phi = builder.createPHI(i32_ty)
inspect(phi.getValueRepr(), content="%0")
phi.setName("result")
inspect(phi.getValueRepr(), content="%result")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_demo")
let merge_bb = fval.addBasicBlock(name="merge")
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty)
inspect(phi.getName(), content="None")
phi.setName("result")
inspect(phi.getName(), content="Some(\"result\")")
}fn PHINode::addIncoming(self : PHINode, value : &Value, block : BasicBlock) -> Unit raise LLVMValueErrortest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_add_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block1_bb = fval.addBasicBlock(name="block1")
let block2_bb = fval.addBasicBlock(name="block2")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
let val3 = ctx.getConstInt32(30)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
inspect(phi.getNumIncomingValues(), content="0")
phi.addIncoming(val1, entry_bb)
inspect(phi.getNumIncomingValues(), content="1")
inspect(phi.getIncomingValue(0).unwrap().getValueRepr(), content="10")
inspect(phi.getIncomingBlock(0).unwrap().getValueRepr(), content="%entry")
phi.addIncoming(val2, block1_bb)
phi.addIncoming(val3, block2_bb)
inspect(phi.getNumIncomingValues(), content="3")
let expected = " %result = phi i32 [ 10, %entry ], [ 20, %block1 ], [ 30, %block2 ]"
inspect(phi, content=expected)
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_incoming_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block_bb = fval.addBasicBlock(name="block")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block_bb)
let (value0, block0) = phi.getIncoming(0).unwrap()
inspect(value0.getValueRepr(), content="10")
inspect(block0.getValueRepr(), content="%entry")
let (value1, block1) = phi.getIncoming(1).unwrap()
inspect(value1.getValueRepr(), content="20")
inspect(block1.getValueRepr(), content="%block")
inspect(phi.getIncoming(2), content="None")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_block_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block_bb = fval.addBasicBlock(name="block")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block_bb)
inspect(phi.getIncomingBlock(0).unwrap().getValueRepr(), content="%entry")
inspect(phi.getIncomingBlock(1).unwrap().getValueRepr(), content="%block")
inspect(phi.getIncomingBlock(2), content="None")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_blocks_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block1_bb = fval.addBasicBlock(name="block1")
let block2_bb = fval.addBasicBlock(name="block2")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
let val3 = ctx.getConstInt32(30)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block1_bb)
phi.addIncoming(val3, block2_bb)
let blocks = phi.getIncomingBlocks()
inspect(blocks.length(), content="3")
inspect(blocks[0].getValueRepr(), content="%entry")
inspect(blocks[1].getValueRepr(), content="%block1")
inspect(blocks[2].getValueRepr(), content="%block2")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_value_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block_bb = fval.addBasicBlock(name="block")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block_bb)
inspect(phi.getIncomingValue(0).unwrap().getValueRepr(), content="10")
inspect(phi.getIncomingValue(1).unwrap().getValueRepr(), content="20")
inspect(phi.getIncomingValue(2), content="None")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_values_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block1_bb = fval.addBasicBlock(name="block1")
let block2_bb = fval.addBasicBlock(name="block2")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
let val3 = ctx.getConstInt32(30)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block1_bb)
phi.addIncoming(val3, block2_bb)
let values = phi.getIncomingValues()
inspect(values.length(), content="3")
inspect(values[0].getValueRepr(), content="10")
inspect(values[1].getValueRepr(), content="20")
inspect(values[2].getValueRepr(), content="30")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_incomings_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block1_bb = fval.addBasicBlock(name="block1")
let block2_bb = fval.addBasicBlock(name="block2")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
let val3 = ctx.getConstInt32(30)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
phi.addIncoming(val1, entry_bb)
phi.addIncoming(val2, block1_bb)
phi.addIncoming(val3, block2_bb)
let incomings = phi.getIncomings()
inspect(incomings.length(), content="3")
inspect(incomings[0].0.getValueRepr(), content="10")
inspect(incomings[0].1.getValueRepr(), content="%entry")
inspect(incomings[1].0.getValueRepr(), content="20")
inspect(incomings[2].0.getValueRepr(), content="30")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [])
let fval = mod.addFunction(fty, "phi_num_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let block1_bb = fval.addBasicBlock(name="block1")
let block2_bb = fval.addBasicBlock(name="block2")
let merge_bb = fval.addBasicBlock(name="merge")
let val1 = ctx.getConstInt32(10)
let val2 = ctx.getConstInt32(20)
let val3 = ctx.getConstInt32(30)
builder.setInsertPoint(merge_bb)
let phi = builder.createPHI(i32_ty, name="result")
inspect(phi.getNumIncomingValues(), content="0")
phi.addIncoming(val1, entry_bb)
inspect(phi.getNumIncomingValues(), content="1")
phi.addIncoming(val2, block1_bb)
phi.addIncoming(val3, block2_bb)
inspect(phi.getNumIncomingValues(), content="3")
}pub(all) enum ParamAttr {
Alignment(Int)
AllocAlign
AllocatedPointer
ByVal(&Type)
ByRef(&Type)
NoUndef
Dereferenceable(Int)
DereferenceableOrNull(Int)
ElementType(&Type)
InAlloca(&Type)
Initializes
InReg
NoFPClass
Nest
NoAlias
Captures
NoExt
NoFree
DeadOnUnwind
NonNull
Preallocated(&Type)
Range
ReadNone
ReadOnly
Returned
ImmArg
SExt
StackAlignment(Int)
StructRet
SwiftError
SwiftSelf
SwiftAsync
Writable
WriteOnly
ZExt
}test {
let ctx = Context::new()
inspect(ctx.getPtrTy(), content="ptr")
let addressSpace = AddressSpace::new(0)
let ptr = ctx.getPtrTy(addressSpace~)
inspect(ptr, content="ptr")
let i32ty = ctx.getInt32Ty()
assert_true(PointerType::isLoadableOrStorableType(i32ty))
let voidty = ctx.getVoidTy()
assert_false(PointerType::isLoadableOrStorableType(voidty))
}impl Type for PointerTypeimpl Eq for PointerTypeimpl Hash for PointerTypeimpl Show for PointerTypepub enum PrimitiveTypeEnum {
HalfType(HalfType)
BFloatType(BFloatType)
FloatType(FloatType)
DoubleType(DoubleType)
FP128Type(FP128Type)
Int1Type(Int1Type)
Int8Type(Int8Type)
Int16Type(Int16Type)
Int32Type(Int32Type)
Int64Type(Int64Type)
}impl Eq for PrimitiveTypeEnumimpl Show for PrimitiveTypeEnumpub(all) enum RetAttr {
Alignment(Int)
NoUndef
Dereferenceable(Int)
DereferenceableOrNull(Int)
InReg
NoFPClass
NoAlias
NoExt
NonNull
SExt
StackAlignment(Int)
ZExt
}pub struct ReturnInst {
uid : UInt64
vty : VoidType
retVal : &Value?
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(i32_ty, [i32_ty])
let fval = mod.addFunction(fty, "return_demo")
let bb = fval.addBasicBlock(name="entry")
let arg = fval.getArg(0).unwrap()
builder.setInsertPoint(bb)
let ret = builder.createRet(arg)
inspect(ret, content=" ret i32 %0")
assert_true(ret.asValueEnum() is ReturnInst(_))
let void_fty = ctx.getFunctionType(void_ty, [])
let void_fval = mod.addFunction(void_fty, "void_return_demo")
let void_bb = void_fval.addBasicBlock(name="entry")
builder.setInsertPoint(void_bb)
let void_ret = builder.createRetVoid()
inspect(void_ret, content=" ret void")
}impl Instruction for ReturnInstimpl User for ReturnInstimpl Value for ReturnInstimpl Show for ReturnInsttest {
let ctx = Context::new()
let f32ty = ctx.getFloatTy()
let vecty = ctx.getScalableVectorType(f32ty, 16)
inspect(vecty, content="<vscale x 16 x float>")
assert_eq(vecty.getElementCount(), 16)
inspect(vecty.getElementType(), content="float")
}impl AggregateType for ScalableVectorTypeimpl Type for ScalableVectorTypeimpl Eq for ScalableVectorTypeimpl Hash for ScalableVectorTypeimpl Show for ScalableVectorTypepub struct SelectInst {
uid : UInt64
users : Array[&User]
vty : &Type
condition : &Value
trueValue : &Value
falseValue : &Value
name : String?
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i1_ty, i32_ty, i32_ty])
let fval = mod.addFunction(fty, "select_demo")
let bb = fval.addBasicBlock(name="entry")
let cond = fval.getArg(0).unwrap()
let true_val = fval.getArg(1).unwrap()
let false_val = fval.getArg(2).unwrap()
builder.setInsertPoint(bb)
let select = builder.createSelect(cond, true_val, false_val, name="result")
inspect(select, content=" %result = select i1 %0, i32 %1, i32 %2")
assert_true(select.asValueEnum() is SelectInst(_))
}impl Instruction for SelectInstimpl User for SelectInstimpl Value for SelectInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i1_ty, i32_ty, i32_ty])
let fval = mod.addFunction(fty, "select_demo")
let bb = fval.addBasicBlock(name="entry")
let cond = fval.getArg(0).unwrap()
let true_val = fval.getArg(1).unwrap()
let false_val = fval.getArg(2).unwrap()
builder.setInsertPoint(bb)
let select = builder.createSelect(cond, true_val, false_val)
inspect(select.getName(), content="None")
select.setName("result")
inspect(select.getName(), content="Some(\"result\")")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i1_ty, i32_ty, i32_ty])
let fval = mod.addFunction(fty, "select_demo")
let bb = fval.addBasicBlock(name="entry")
let cond = fval.getArg(0).unwrap()
let true_val = fval.getArg(1).unwrap()
let false_val = fval.getArg(2).unwrap()
builder.setInsertPoint(bb)
let select = builder.createSelect(cond, true_val, false_val)
inspect(select.getValueRepr(), content="%3")
select.setName("result")
inspect(select.getValueRepr(), content="%result")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i1_ty = ctx.getInt1Ty()
let i32_ty = ctx.getInt32Ty()
let fty = ctx.getFunctionType(i32_ty, [i1_ty, i32_ty, i32_ty])
let fval = mod.addFunction(fty, "select_demo")
let bb = fval.addBasicBlock(name="entry")
let cond = fval.getArg(0).unwrap()
let true_val = fval.getArg(1).unwrap()
let false_val = fval.getArg(2).unwrap()
builder.setInsertPoint(bb)
let select = builder.createSelect(cond, true_val, false_val)
inspect(select.getName(), content="None")
select.setName("result")
inspect(select.getName(), content="Some(\"result\")")
}impl Show for SelectInsttype SignedEnumimpl Eq for SignedEnumimpl Hash for SignedEnumimpl Show for SignedEnumpub struct StoreInst {
uid : UInt64
vty : &Type
value : &Value
ptr : &Value
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
isVolatile : Bool
atomicOrdering : AtomicOrdering
align : Align
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [ptr_ty, i32_ty])
let fval = mod.addFunction(fty, "store_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
ptr.setName("arg0")
let value = fval.getArg(1).unwrap()
value.setName("value")
let s = builder.createStore(value, ptr)
inspect(s, content=" store i32 %value, ptr %arg0, align 4")
}impl Instruction for StoreInsttest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [])
let fval = mod.addFunction(fty, "store_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let alloca = builder.createAlloca(ctx.getInt32Ty(), name="ptr")
let const42 = ctx.getConstInt32(42)
let s = builder.createStore(const42, alloca)
inspect(s.getPointerOperand(), content=" %ptr = alloca i32, align 4")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let ptr_ty = ctx.getPtrTy()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [ptr_ty, i32_ty])
let fval = mod.addFunction(fty, "store_an_integer")
let bb = fval.addBasicBlock(name="entry")
builder.setInsertPoint(bb)
let ptr = fval.getArg(0).unwrap()
ptr.setName("arg0")
let val1 = fval.getArg(1).unwrap()
let const_42 = ctx.getConstInt32(42)
let val2 = builder.createNSWAdd(val1, const_42, name="value")
let s = builder.createStore(val2, ptr)
inspect(s.getValueOperand(), content=" %value = add nsw i32 %0, 42")
}test {
let ctx = Context::new()
let i8ty = ctx.getInt8Ty()
let i16ty = ctx.getInt16Ty()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let sty = ctx.getStructType([i32ty, f32ty], name="foo")
inspect(sty.full_info(), content="%foo = type { i32, float }")
let sty = ctx.getStructType([i8ty, i16ty], name="bar", isPacked=true)
inspect(sty.full_info(), content="%bar = type <{ i8, i16 }>")
}impl AggregateType for StructTypeimpl Type for StructTypeimpl Eq for StructTypeimpl Hash for StructTypeimpl Show for StructTypetest {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let foo = ctx.getStructType([i32ty, f32ty])
let bar = ctx.getStructType([i32ty, f32ty], name="bar")
assert_true(foo.isLiteral())
assert_false(bar.isLiteral())
}test {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let f32ty = ctx.getFloatTy()
let foo = ctx.getStructType([], name="foo")
let bar = ctx.getStructType([i32ty, f32ty], name="bar")
assert_true(foo.isOpaque())
assert_false(bar.isOpaque())
}fn StructType::setBody(self : StructType, elements : Array[&Type], isPacked? : Bool) -> Unit raise LLVMTypeErrorpub struct SwitchInst {
uid : UInt64
vty : VoidType
condition : &Value
defaultDest : BasicBlock
cases : Array[(ConstantInt, BasicBlock)]
parent : Function
bb : Ref[BasicBlock?]
prev : Ref[&Instruction?]
next : Ref[&Instruction?]
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i32_ty])
let fval = mod.addFunction(fty, "switch_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let case1_bb = fval.addBasicBlock(name="case1")
let case2_bb = fval.addBasicBlock(name="case2")
let default_bb = fval.addBasicBlock(name="default")
let value = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let switch = builder.createSwitch(value, default_bb)
let case_val1 = ctx.getConstInt32(1)
let case_val2 = ctx.getConstInt32(2)
switch.addCase(case_val1, case1_bb)
switch.addCase(case_val2, case2_bb)
let expect =
#| switch i32 %0, label %default [
#| i32 1, label %case1
#| i32 2, label %case2
#| ]
inspect(switch, content=expect)
assert_true(switch.asValueEnum() is SwitchInst(_))
}impl Instruction for SwitchInstimpl User for SwitchInstimpl Value for SwitchInstimpl Show for SwitchInstfn SwitchInst::addCase(self : SwitchInst, cond : ConstantInt, dest : BasicBlock) -> Unit raise LLVMValueErrortest {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i32_ty])
let fval = mod.addFunction(fty, "switch_addcase_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let case1_bb = fval.addBasicBlock(name="case1")
let case2_bb = fval.addBasicBlock(name="case2")
let case3_bb = fval.addBasicBlock(name="case3")
let default_bb = fval.addBasicBlock(name="default")
let value = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let switch = builder.createSwitch(value, default_bb)
// Add multiple cases
let case_val1 = ctx.getConstInt32(1)
let case_val2 = ctx.getConstInt32(2)
let case_val3 = ctx.getConstInt32(3)
switch.addCase(case_val1, case1_bb)
switch.addCase(case_val2, case2_bb)
switch.addCase(case_val3, case3_bb)
inspect(switch.getNumCases(), content="3")
assert_true(switch.getCase(0).unwrap().0.getValueRepr() == "1")
assert_true(switch.getCase(1).unwrap().0.getValueRepr() == "2")
assert_true(switch.getCase(2).unwrap().0.getValueRepr() == "3")
}test {
let ctx = Context::new()
let mod = ctx.addModule("demo")
let builder = ctx.createBuilder()
let i32_ty = ctx.getInt32Ty()
let void_ty = ctx.getVoidTy()
let fty = ctx.getFunctionType(void_ty, [i32_ty])
let fval = mod.addFunction(fty, "switch_case_demo")
let entry_bb = fval.addBasicBlock(name="entry")
let case1_bb = fval.addBasicBlock(name="case1")
let case2_bb = fval.addBasicBlock(name="case2")
let default_bb = fval.addBasicBlock(name="default")
let value = fval.getArg(0).unwrap()
builder.setInsertPoint(entry_bb)
let switch = builder.createSwitch(value, default_bb)
let case_val1 = ctx.getConstInt32(1)
let case_val2 = ctx.getConstInt32(2)
switch.addCase(case_val1, case1_bb)
switch.addCase(case_val2, case2_bb)
inspect(switch.getNumCases(), content="2")
inspect(switch.getCase(0).unwrap().0.getValueRepr(), content="1")
inspect(switch.getCase(0).unwrap().1.getValueRepr(), content="%case1")
inspect(switch.getCase(1).unwrap().0.getValueRepr(), content="2")
inspect(switch.getCase(1).unwrap().1.getValueRepr(), content="%case2")
inspect(switch.getCase(2), content="None")
}pub enum TypeEnum {
HalfType(HalfType)
BFloatType(BFloatType)
FloatType(FloatType)
DoubleType(DoubleType)
FP128Type(FP128Type)
Int1Type(Int1Type)
Int8Type(Int8Type)
Int16Type(Int16Type)
Int32Type(Int32Type)
Int64Type(Int64Type)
VoidType(VoidType)
LabelType(LabelType)
MetadataType(MetadataType)
TokenType(TokenType)
FunctionType(FunctionType)
StructType(StructType)
ArrayType(ArrayType)
VectorType(VectorType)
ScalableVectorType(ScalableVectorType)
PointerType(PointerType)
}pub struct TypeSize {
// private fields
}impl Eq for UInt16Arrayimpl Hash for UInt16Arrayimpl Show for UInt16Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn UInt16Array::inner(self : UInt16Array) -> Array[UInt16]impl Eq for UInt32Arrayimpl Hash for UInt32Arrayimpl Show for UInt32Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn UInt32Array::inner(self : UInt32Array) -> Array[UInt]impl Eq for UInt64Arrayimpl Hash for UInt64Arrayimpl Show for UInt64Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn UInt64Array::inner(self : UInt64Array) -> Array[UInt64]impl Eq for UInt8Arrayimpl Hash for UInt8Arrayimpl Show for UInt8Array#deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
fn UInt8Array::inner(self : UInt8Array) -> Array[UInt8]type UnSignedEnumimpl Eq for UnSignedEnumimpl Hash for UnSignedEnumimpl Show for UnSignedEnumpub enum UnaryInstEnum {
AllocaInst(AllocaInst)
LoadInst(LoadInst)
ExtractValueInst(ExtractValueInst)
FNegInst(FNegInst)
CastInst(CastInst)
}type UserBasepub enum UserEnum {
LoadInst(LoadInst)
ExtractValueInst(ExtractValueInst)
FNegInst(FNegInst)
CastInst(CastInst)
BinaryInst(BinaryInst)
ICmpInst(ICmpInst)
FCmpInst(FCmpInst)
StoreInst(StoreInst)
GetElementPtrInst(GetElementPtrInst)
SelectInst(SelectInst)
InsertValueInst(InsertValueInst)
PHINode(PHINode)
ReturnInst(ReturnInst)
BranchInst(BranchInst)
SwitchInst(SwitchInst)
CallInst(CallInst)
}type ValueBasepub enum ValueEnum {
Function(Function)
GlobalVariable(GlobalVariable)
GlobalConstant(GlobalConstant)
ConstantInt(ConstantInt)
ConstantFP(ConstantFP)
ConstantPointerNull(ConstantPointerNull)
ConstantArray(ConstantArray)
ConstantVector(ConstantVector)
ConstantString(ConstantString)
ConstantStruct(ConstantStruct)
Argument(Argument)
BasicBlock(BasicBlock)
AllocaInst(AllocaInst)
LoadInst(LoadInst)
ExtractValueInst(ExtractValueInst)
FNegInst(FNegInst)
CastInst(CastInst)
BinaryInst(BinaryInst)
ICmpInst(ICmpInst)
FCmpInst(FCmpInst)
StoreInst(StoreInst)
GetElementPtrInst(GetElementPtrInst)
SelectInst(SelectInst)
InsertValueInst(InsertValueInst)
PHINode(PHINode)
ReturnInst(ReturnInst)
BranchInst(BranchInst)
SwitchInst(SwitchInst)
CallInst(CallInst)
}test {
let ctx = Context::new()
let i32ty = ctx.getInt32Ty()
let vecty = ctx.getFixedVectorType(i32ty, 16)
inspect(vecty, content="<16 x i32>")
assert_eq(vecty.getElementCount(), 16)
inspect(vecty.getElementType(), content="i32")
}impl AggregateType for VectorTypeimpl Type for VectorTypeimpl Eq for VectorTypeimpl Hash for VectorTypeimpl Show for VectorTypefn warning_elimination() -> UnitMoonbit version of LLVM, A Tiny, Friendly Companion to LLVM
Dependencies