Cast a function parameter to GEP

Hi all,
I’m still working on the Interpreter class and I would like to understand why an operand cannot be cast to GetElementPtrInst.

My code is something like:

void MyInterpreter::visitCallInst(CallInst& I)
{
for(int i = 0; i < I.getNumArgOperands(); i++) {
operand = I.getOperand(i);

if(GetElementPtrInst* CI = dyn_cast(operand)) {
errs() << “GEP\n”;
} else {
operand->dump();
}

}

The specific output is:

i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str1, i32 0, i32 0)

and str1 is @.str1 = private unnamed_addr constant [7 x i8] c"1.2.34\00", align 1

I think it does not work because str1 is a “private constant”. Is there a way to solve it?

Thanks

Hi Alberto,

i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str1, i32 0, i32 0)

Because all of its inputs are Constants, this is actually a
GetElementPtrConstantExpr instead of a GetElementPtrInst (the easiest
way to tell on sight without context is the extra parens, which the
instruction variant never has).

The main practical difference between the two is that instances of
Constant don't live in a BasicBlock independently, but are referenced
directly by each user. When printing the IR this is shown by
"inlining" them into the parent Instruction.

LLVM has a GEPOperator class to help deal with this issue; it can be
used to access the common features of Instructions and Constants.
There are similar Operators for other operations because this is quite
a common situation.

I think it does not work because str1 is a "private constant". Is there a way to solve it?

Broadly true, but the same would apply to any global, not just ones
declared constant.

Cheers.

Tim.

Thanks Tim,
I’ll try to solve my problem ASAP, if I cannot maybe I’ll some other clarifications.

Thanks again

Sorry Tim,
I now need to find the value of the constant expression and I found online a solution like: string value = cast(cast(CallInstruction->getOperand(0))->getInitializer())->getAsCString();

This one works but I feel the GEPOperator should be used based on your comments, so I tried to cast the operator and get the value but I’m not able to do it.

I cast using GEPOperator *op = dyn_cast(CI->getOperand(0));

Could you tell me if it is correct and how to extract the value please?

Thanks

I now need to find the value of the constant expression and I found online a solution like: string value = cast<ConstantDataArray>(cast<GlobalVariable>(CallInstruction->getOperand(0))->getInitializer())->getAsCString();

This one works but I feel the GEPOperator should be used based on your comments, so I tried to cast the operator and get the value but I'm not able to do it.

If that one works it sounds like you don't have any kind of GEP at
that point. Otherwise the cast to GlobalVariable would fail. Have you
tried calling Module::dump while that code is executing to see what
you're really dealing with?

I cast using GEPOperator *op = dyn_cast<GEPOperator>(CI->getOperand(0));

That looks right to me if you have a GEP. Once you've got that you'd
have to carefully check the operands of the GEP to make sure no-one is
doing anything tricksy like

    printf(LocalVariable); //
cast<GlobalVariable>(MyGEP->getPointerOperand) will fail so use
dyn_cast and check the result.
    printf(&"MwahahahaHello world\n"[9]); // The GEP will have
non-zero index operands. They may not even be constant.

Cheers.

Tim.

Thanks Tim,
I’ll keep using that notation for getting the value of str1 for now.

Thanks again for your help