When I got a Operator by iterating a Value's User, how can I got the relevant Instruction?

Hi,

I am using IR to do some dataflow analysis, and I want to get the source location related to the dataflow. In my thought, when I iterate the Users of a Value, there should be an corresponding instruction, then I could get source location from dbg info.

However, in some cases, I got some Operators as the Users of a Value, such as GEPOperator, BitCastOperator, etc.
My question is, how could I got the corresponding instruction that use this Operator as Operand?

For example, when I got the GEPOperator as follows, how could I get the LoadInst?

%39 = load i32, i32* getelementptr inbounds (%struct.TTT, %struct.TTT* @ttt, i32 0, i32 2), align 8, !dbg !971

Sincerely,
Shulin

%39 is the LoadInst, while getelementptr is its second operand. It is
inlined because it is an llvm::Constant, not an instruction. Constants
do not participate in use/user-chains and hence there is no link from
GEP to the LoadInst that is using it. The constant GEP object may be
used by an arbitrary number of other instructions, other constants in
the same or other functions.

Node that there "GEPOperator" can represent either a GetElementPtrInst
(i.e. an instruction) or a GEP constant expression (derived from
ConstantExpr)

Michael

Hi Michael,

Thank you very much!
I have a further question: if I want to get the dataflow of a target Value, is there any way to handle these situations when iterate the Users?Or only by iterator all the instructions and their operands?

Sincerely,
Shulin

Michael Kruse <llvmdev@meinersbur.de> 于2021年6月18日周五 上午5:11写道:

How did you choose where you started from? An Instruction can only be used by another Instruction, but it seems you’ve started from a Constant which can be used by ConstantExprs.

Hi Craig,

I started from GlobalVaribles, so there are situations that I met the ConstantExprs, i.e. some Operators.

Craig Topper <craig.topper@gmail.com> 于2021年6月18日周五 上午8:37写道:

I see so you want to see where the GlobalVariable is accesssed. You should be able to get the Users of the ConstantExpr as well, those will either be another ConstantExpr or an Instruction. In your example, one of the Users of the GEPOperator should be the LoadInst.

Hi Craig,

I have tried to visit the Users of current GEPOperator, but the results are not what I am looking for.
In detail, when I tried to get the Users of GEPOperator of the LoadInst, i.e. getelementptr inbounds (%struct.TTT, %struct.TTT* @ttt, i32 0, i32 2) ,
the results are turned out to be Users of GlobalVariable @ttt, i.e. something like
i8* bitcast (%struct.TTT* @ttt to i8*), or i32* getelementptr inbounds (%struct.TTT, %struct.TTT* @ttt, i32 0, i32 1).

I am not sure what happened here. Is that the def-use chain of structural global variables always contains the whole information related to the global variable?

Sincerely,
Shulin

Craig Topper <craig.topper@gmail.com> 于2021年6月18日周五 上午10:14写道:

Can you share your code?

Sure!

The following snippet is the main function I implemented to visit the Users of GlobalVariables.


for(Value::user_iterator i=gv->user_begin(), e=gv->user_end(); i!=e; i++)
{
    User* cur_user = *i;
    cur_user->print(llvm::outs());
    llvm::outs()<<"\n";

    if(Instruction* inst = dyn_cast<Instruction>(cur_user))
    {
        // record source location info
    }
    else if(GEPOperator* gepo = dyn_cast<GEPOperator>(cur_user))
    {
        llvm::outs()<<"It is a GEPOperator.\n";

        for(aute it=gepo->user_begin(); it!=gepo->uesr_end(); ++it)
        {
            User* user = *it;
            llvm::outs()<<"One of the User:";
            user->print(llvm::outs());
            llvm::outs()<<"\n";
        }
    }
}

And the source file of test case is, the “ttt.field_b” in the main() is presented as a GEPOperator in the generated IR file.


struct TTT{
    int field_a;
    int field_b;
    int field_c;
};

struct TTT ttt;

int main()
{
    ...
    int b = a - ttt.field_b;
    ...
}

Craig Topper <craig.topper@gmail.com> 于2021年6月18日周五 下午12:55写道:

dataflow.cpp (2.34 KB)