Как создать встроенную инструкцию GetElementPtr?

У меня есть такой фрагмент кода (systemFun определяется как i32 @system(i8*)):

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

который генерирует следующий LLVM IR:

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

Однако, когда я компилирую этот код C с помощью Clang:

system("echo haha");

Генерируется следующий LLVM IR:

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

Я хотел бы сгенерировать последний код, где результат getelementptr используется непосредственно в вызове функции, без присвоения временной переменной %1.

Я попытался опустить NameStr и InsertAtEnd (returnBB — это BasicBlock), но он генерирует код вроде

call i32 @system(i8* <badref>)

Пожалуйста, скажите мне, как достичь моей цели.


person iBug    schedule 28.10.2019    source источник


Ответы (1)


«Встроенная» версия представляет собой ConstantExpr, сгенерированный с помощью ConstantExpr::getGetElementPtr(), другой - инструкция.

Класс ConstantExpr — это лучший формат для глобальных переменных, потому что он обязательно не требует процессорного времени во время выполнения, но инструкция работает для всех типов указателей, даже если они не являются постоянными. (Указатель на глобальную переменную является константой.)

person arnt    schedule 28.10.2019