iBug
iBug

Reputation: 37237

How to generate an inline GetElementPtr instruction?

I have some piece of code like this (systemFun is defined as i32 @system(i8*)):

auto cmdPtr = GetElementPtrInst::CreateInBounds(
        ArrayType::get(TYPE8, 1 + cmdCStr.size()),
        cmdStr, ArrayRef<Value*>(indexList, 2), "", returnBB);
builder.CreateCall(systemFun, {cmdPtr});

which generates the following LLVM IR:

%1 = getelementptr inbounds [10 x i8], [10 x i8]* @cmd, i32 0, i32 0
%2 = call i32 @system(i8* %1)

However, when I compile this C code using Clang:

system("echo haha");

The following LLVM IR is generated:

call i32 @system(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @cmd, i32 0, i32 0))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I would like to generate the latter code, where the result of getelementptr is used directly in the function call, without being assigned to a temporary variable %1.

I tried omitting NameStr and InsertAtEnd (returnBB is a BasicBlock), but it generates code like

call i32 @system(i8* <badref>)

Please kindly tell me how to achieve my goal.

Upvotes: 2

Views: 992

Answers (1)

arnt
arnt

Reputation: 9685

The "inline" version is a ConstantExpr, generated using ConstantExpr::getGetElementPtr(), the other one is an instruction.

The ConstantExpr class is the best format to use for global variables because it neccessarily takes no CPU time at runtime, but the instruction works for all kinds of pointers, even if not constant. (A pointer to a global variable is constant.)

Upvotes: 4

Related Questions