LLVM преобразовывает константу в значение

Я использую пользовательский проход LLVM, где, если я сталкиваюсь с хранилищем, куда компилятор преобразует значение в константу; например, есть явное хранилище:

X[gidx] = 10;

Тогда LLVM сгенерирует эту ошибку:

aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.

Порядок наследования выглядит следующим образом: Value<-User <-Constant, поэтому это не должно быть проблемой, но это так. Использование приведения к ConstantInt или ConstantFP не влияет на эту ошибку. Итак, я попробовал это раздутое решение:

Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
    Instruction *allocInst = builder.CreateAlloca(old_value->getType());
    builder.CreateStore(old_value, allocInst);
    new_value = builder.CreateLoad(allocResultInst);
}

Тем не менее, это решение создает свои собственные ошибки реестра, когда речь идет о другом типе, поэтому я бы хотел этого избежать.

Кто-нибудь знает, как преобразовать константу в значение? Это должна быть простая проблема, которую я не вижу. Я работаю на ядрах Ubuntu 12.04, LLVM 3, AMD GPU, OpenCL.

Спасибо заранее

РЕДАКТИРОВАТЬ:

Исходный код, который производит первую из перечисленных ошибок, просто:

builder.CreateStore(old_value, store_addr);

EDIT2:

Это old_value объявлено как Value *old_value = current_instruction->getOperand(0);

Поэтому я беру значение, которое нужно сохранить, в данном случае "10" из первой строки кода.

1 ответ

Вы не предоставили код, вызвавший это первое утверждение, но его формулировка довольно ясна: вы пытаетесь создать хранилище, в котором операнд значения и операнд указателя не согласуются по своим типам. Было бы полезно, если бы вы предоставили код, который сгенерировал эту ошибку.

Ваше второе, так называемое "раздутое" решение, является правильным способом хранения old_value в стек, а затем загрузите его снова. Ты пишешь:

Однако это решение создает свои собственные ошибки регистра, когда задействованы разные типы

Эти "ошибки регистрации" - реальная проблема, к которой вы должны обратиться.

В любом случае вся предпосылка "преобразования константы в значение" ошибочна - как вы правильно заметили, все константы являются значениями. Нет смысла сохранять значение в стеке с единственной целью его повторной загрузки, и действительно, стандартный проход LLVM "mem2reg" полностью удалит такую ​​последовательность, заменив все виды использования нагрузки исходным значением.

Другие вопросы по тегам