16 : actx(ctx.getAstContext()), ctx(&ctx) {
21 : actx(actx), ctx(nullptr) {
26 llvm::Argument* argument = llvm::dyn_cast_or_null<llvm::Argument>(value);
27 llvm::CallInst* call = llvm::dyn_cast_or_null<llvm::CallInst>(value);
28 llvm::ConstantInt* constant = llvm::dyn_cast_or_null<llvm::ConstantInt>(value);
29 llvm::ICmpInst* icmp = llvm::dyn_cast_or_null<llvm::ICmpInst>(value);
30 llvm::Instruction* instruction = llvm::dyn_cast_or_null<llvm::Instruction>(value);
32 if (instruction !=
nullptr) {
35 if (call !=
nullptr) {
36 if (call->getCalledFunction()->getName().find(
"llvm.bswap.i") != std::string::npos) {
37 return this->actx->bswap(this->do_convert(call->getOperand(0)));
40 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
43 switch (instruction->getOpcode()) {
45 case llvm::Instruction::AShr: {
46 auto LHS = this->do_convert(instruction->getOperand(0));
47 auto RHS = this->do_convert(instruction->getOperand(1));
48 return this->actx->bvashr(LHS, RHS);
51 case llvm::Instruction::Add: {
52 auto LHS = this->do_convert(instruction->getOperand(0));
53 auto RHS = this->do_convert(instruction->getOperand(1));
54 return this->actx->bvadd(LHS, RHS);
57 case llvm::Instruction::And: {
58 auto LHS = this->do_convert(instruction->getOperand(0));
59 auto RHS = this->do_convert(instruction->getOperand(1));
61 if (LHS->isLogical() && RHS->isLogical()) {
62 return this->actx->ite(this->actx->land(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
64 return this->actx->bvand(LHS, RHS);
67 case llvm::Instruction::ICmp: {
69 auto LHS = this->do_convert(instruction->getOperand(0));
70 auto RHS = this->do_convert(instruction->getOperand(1));
71 if (icmp !=
nullptr) {
72 switch (icmp->getPredicate()) {
73 case llvm::ICmpInst::ICMP_EQ:
return this->actx->equal(LHS, RHS);
74 case llvm::ICmpInst::ICMP_NE:
return this->actx->distinct(LHS, RHS);
75 case llvm::ICmpInst::ICMP_UGE:
return this->actx->bvuge(LHS, RHS);
76 case llvm::ICmpInst::ICMP_UGT:
return this->actx->bvugt(LHS, RHS);
77 case llvm::ICmpInst::ICMP_ULE:
return this->actx->bvule(LHS, RHS);
78 case llvm::ICmpInst::ICMP_ULT:
return this->actx->bvult(LHS, RHS);
79 case llvm::ICmpInst::ICMP_SGE:
return this->actx->bvsge(LHS, RHS);
80 case llvm::ICmpInst::ICMP_SGT:
return this->actx->bvsgt(LHS, RHS);
81 case llvm::ICmpInst::ICMP_SLE:
return this->actx->bvsle(LHS, RHS);
82 case llvm::ICmpInst::ICMP_SLT:
return this->actx->bvslt(LHS, RHS);
91 case llvm::Instruction::LShr: {
92 auto LHS = this->do_convert(instruction->getOperand(0));
93 auto RHS = this->do_convert(instruction->getOperand(1));
94 return this->actx->bvlshr(LHS, RHS);
97 case llvm::Instruction::Mul: {
98 auto LHS = this->do_convert(instruction->getOperand(0));
99 auto RHS = this->do_convert(instruction->getOperand(1));
100 return this->actx->bvmul(LHS, RHS);
103 case llvm::Instruction::Or: {
104 auto LHS = this->do_convert(instruction->getOperand(0));
105 auto RHS = this->do_convert(instruction->getOperand(1));
107 if (LHS->isLogical() && RHS->isLogical()) {
108 return this->actx->ite(this->actx->lor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
110 return this->actx->bvor(LHS, RHS);
113 case llvm::Instruction::Ret:
114 return this->do_convert(instruction->getOperand(0));
116 case llvm::Instruction::SDiv: {
117 auto LHS = this->do_convert(instruction->getOperand(0));
118 auto RHS = this->do_convert(instruction->getOperand(1));
119 return this->actx->bvsdiv(LHS, RHS);
122 case llvm::Instruction::SExt: {
124 auto size = instruction->getType()->getIntegerBitWidth();
125 auto node = this->do_convert(instruction->getOperand(0));
127 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
128 return this->actx->sx(size - csze, node);
131 case llvm::Instruction::SRem: {
132 auto LHS = this->do_convert(instruction->getOperand(0));
133 auto RHS = this->do_convert(instruction->getOperand(1));
134 return this->actx->bvsrem(LHS, RHS);
137 case llvm::Instruction::Select: {
138 auto nif = this->do_convert(instruction->getOperand(0));
139 auto nthen = this->do_convert(instruction->getOperand(1));
140 auto nelse = this->do_convert(instruction->getOperand(2));
147 if (nif->isLogical() ==
false) {
148 nif = this->actx->equal(nif, this->actx->bvtrue());
151 return this->actx->ite(nif, nthen, nelse);
154 case llvm::Instruction::Shl: {
155 auto LHS = this->do_convert(instruction->getOperand(0));
156 auto RHS = this->do_convert(instruction->getOperand(1));
157 return this->actx->bvshl(LHS, RHS);
160 case llvm::Instruction::Sub: {
161 auto LHS = this->do_convert(instruction->getOperand(0));
162 auto RHS = this->do_convert(instruction->getOperand(1));
163 return this->actx->bvsub(LHS, RHS);
166 case llvm::Instruction::Trunc: {
167 auto size = instruction->getType()->getIntegerBitWidth();
168 auto node = this->do_convert(instruction->getOperand(0));
169 return this->actx->extract(size - 1, 0, node);
172 case llvm::Instruction::UDiv: {
173 auto LHS = this->do_convert(instruction->getOperand(0));
174 auto RHS = this->do_convert(instruction->getOperand(1));
175 return this->actx->bvudiv(LHS, RHS);
178 case llvm::Instruction::URem: {
179 auto LHS = this->do_convert(instruction->getOperand(0));
180 auto RHS = this->do_convert(instruction->getOperand(1));
181 return this->actx->bvurem(LHS, RHS);
184 case llvm::Instruction::Xor: {
185 auto LHS = this->do_convert(instruction->getOperand(0));
186 auto RHS = this->do_convert(instruction->getOperand(1));
188 if (LHS->isLogical() && RHS->isLogical()) {
189 return this->actx->ite(this->actx->lxor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
191 return this->actx->bvxor(LHS, RHS);
194 case llvm::Instruction::ZExt: {
196 auto size = instruction->getType()->getIntegerBitWidth();
197 auto node = this->do_convert(instruction->getOperand(0));
199 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
200 return this->actx->zx(size - csze, node);
203 case llvm::Instruction::Load: {
205 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
208 case llvm::Instruction::PHI: {
210 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
217 else if (constant !=
nullptr) {
218 return this->actx->bv(constant->getLimitedValue(), constant->getBitWidth());
220 else if (argument !=
nullptr) {
221 return this->var(argument->getName().data(), argument->getType()->getScalarSizeInBits());
230 auto it = this->symvars.find(name);
231 if (it != this->symvars.end())
236 if (this->ctx ==
nullptr)
237 node = this->actx->getVariableNode(name);
241 symvars[name] = node;
248 llvm::Function* function = llvmModule->getFunction(fname);
249 if (function ==
nullptr) {
254 llvm::BasicBlock& entryBlock = function->getEntryBlock();
257 llvm::Instruction* returnInstruction = entryBlock.getTerminator();
260 return this->do_convert(returnInstruction);
265 return this->do_convert(instruction);
This is the main Triton Context class.
TRITON_EXPORT triton::engines::symbolic::SharedSymbolicVariable newSymbolicVariable(triton::uint32 varSize, const std::string &alias="")
[symbolic api] - Returns a new symbolic variable.
TRITON_EXPORT triton::ast::SharedAbstractNode convert(llvm::Module *llvmModule, const char *fname="__triton")
Converts a given function from an LLVM module to a Triton AST.
TRITON_EXPORT LLVMToTriton(triton::Context &ctx)
Constructor.
The exception class used by all AST lifting (e.g z3 <-> triton).
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
std::uint32_t uint32
unisgned 32-bits