LLVM: передача alloca в качестве аргумента функции

#llvm #llvm-ir

#llvm #llvm-ir

Вопрос:

Мне нужен ИК-код LLVM, эквивалентный

 double x = 4.93;
printf("hello world: %f", x);
  

В моем ИК-коде LLVM, который я получил от godbolt, и после доработки кода он станет чем-то вроде

 %x = alloca double, align 8
store double 4.930000e 00, double* %x, align 8
%1 = load double, double* %x, align 8
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i32 0, i32 0), double %1)
  

Ошибки нет. Пока проблем нет.


Но для меня это %1 выглядит излишним. Однако, похоже, я не могу удалить этот носитель. Следующий код

 %x = alloca double, align 8
store double 4.930000e 00, double* %x, align 8
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i32 0, i32 0), double %x)
  

приводит к ошибке

 llvm-as-9: test.ll:26:113: error: '%x' defined with type 'double*' but expected 'double'
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i32 0, i32 0), double %x)
                                                                                                                ^
  

Теперь мне интересно, действительно ли возможно то, что я делаю для удаления %1 ?

Ответ №1:

alloca Инструкция возвращает указатель, поэтому в вашем коде %x имеет double* тип. Вы должны load из a double* получить double .

В вашем случае должна быть возможность создать double константу со 4.930000e 00 значением и напрямую использовать это значение в качестве printf аргумента.

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