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.

Порядок наследования выглядит следующим образом: Значение‹-Пользователь‹-Константа, так что это не должно быть проблемой, но это так. Использование приведения к 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);

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

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

Итак, я беру значение для сохранения, в данном случае «10» из первой строки кода.


person user2765828    schedule 31.03.2014    source источник
comment
Исходный код, выдающий первую указанную ошибку, прост: не могли бы вы предоставить более крупный фрагмент, в том числе то, как вы создаете old_value и new_value?   -  person Oak    schedule 31.03.2014


Ответы (1)


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

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

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

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

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

person Oak    schedule 31.03.2014
comment
Отредактировано. Проблема регистрации была точкой исходного [сообщения] (http://http://stackoverflow.com/questions/22647180/llvm-front-end-register-class-error-opencl-gpu-target). Однако, учитывая ваш последний пункт, я не понимаю, почему эта проблема вообще существует. - person user2765828; 31.03.2014