LLVM Discussion Forums

How can I get the real value of an operand in LLVM

First,I have an Add operation in my program.Like this

#include <iostream>
using namespace std;
int main() {
    int a = 10;
    int b = 10;
    int c = a + b;
    cout << c;
    return 0;
}

And then I want to write a pass to confusion the Add instruction,I can get the Operand(0) of this expression in LLVM, but its kind is the *Value, so I change it to ConstantInt, and then I use the "getSExtValue()"function to get the operand(0), and its kinds is int64_t. But it have a Segmentation fault in this instruction–>getSExtValue.

for example:

    BinaryOperator *op, *firstAddOp, *secAddOp = NULL;
    ConstantInt *op1 = static_cast<ConstantInt *>(bo->getOperand(0));
    ConstantInt *op2 = static_cast<ConstantInt *>(bo->getOperand(0));
    
    int64_t op1_realValue = op1->getSExtValue();
    int64_t op2_realValue = op2->getSExtValue();

In this code, *bo stand for the add instruction. *op1 is a ConstantInt operand(0).it will appear a fault in this instruciton–>getSExtValue。the fault info like this:

Stack dump:
0.      Program arguments: opt -load ./libInstructionConfusion.so -substitution ../../InstructionConfusion/test/TessAdd.ll -o Test.ll 
1.      Running pass 'Function Pass Manager' on module '../../InstructionConfusion/test/TessAdd.ll'.
2.      Running pass 'operators substitution' on function '@main'
 #0 0x000055b02d295e8a llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/local/bin/opt+0x1547e8a)
 #1 0x000055b02d293a74 llvm::sys::RunSignalHandlers() (/usr/local/bin/opt+0x1545a74)
 #2 0x000055b02d293bc3 SignalHandler(int) (/usr/local/bin/opt+0x1545bc3)
 #3 0x00007f9f65f628a0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x128a0)
 #4 0x00007f9f64e0cad7 llvm::APInt::getWord(unsigned int) const /usr/local/include/llvm/ADT/APInt.h:163:0
 #5 0x00007f9f64e0cb67 llvm::APInt::operator[](unsigned int) const /usr/local/include/llvm/ADT/APInt.h:1139:0
 #6 0x00007f9f64e0cb06 llvm::APInt::isNegative() const /usr/local/include/llvm/ADT/APInt.h:363:0
 #7 0x00007f9f64e0cbcf llvm::APInt::getMinSignedBits() const /usr/local/include/llvm/ADT/APInt.h:1610:0
 #8 0x00007f9f64e0cc48 llvm::APInt::getSExtValue() const /usr/local/include/llvm/ADT/APInt.h:1635:0
 #9 0x00007f9f64e0cde6 llvm::ConstantInt::getSExtValue() const /usr/local/include/llvm/IR/Constants.h:158:0
#10 0x00007f9f64e0c116 (anonymous namespace)::Substitution::AddInstOpSplit(llvm::BinaryOperator*) /home/me/Documents/Obfus/InstructionConfusion/src/Substitution.cpp:229:0
#11 0x00007f9f64e0bb91 (anonymous namespace)::Substitution::substitute(llvm::Function*) /home/me/Documents/Obfus/InstructionConfusion/src/Substitution.cpp:117:0
#12 0x00007f9f64e0ba79 (anonymous namespace)::Substitution::runOnFunction(llvm::Function&) /home/me/Documents/Obfus/InstructionConfusion/src/Substitution.cpp:101:0
#13 0x000055b02cb5c03f llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/bin/opt+0xe0e03f)
#14 0x000055b02cb5c811 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/opt+0xe0e811)
#15 0x000055b02cb5cc11 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/bin/opt+0xe0ec11)
#16 0x000055b02c10dd7d main (/usr/local/bin/opt+0x3bfd7d)
#17 0x00007f9f6503db97 __libc_start_main /build/glibc-2ORdQG/glibc-2.27/csu/../csu/libc-start.c:344:0
#18 0x000055b02c171cda _start (/usr/local/bin/opt+0x423cda)
Segmentation fault (core dumped)

So how can i do? how can i get the operand value and its kind is int64_t
Please give me some suggestions, i will be greatly appreciated.

Please see this llvm-dev thread. Similar problem with plenty of good points.

When do you want this value to be checked? At run-time or at compile-time?