Как мне использовать векторные инструкции RISC-V (RVV) в LLVM IR?

#llvm #llvm-ir #riscv

#llvm #llvm-ir #riscv

Вопрос:

В этой презентации Крупп и Эспаса дают обзор векторного расширения RISC-V (RVV), а на слайде 16 они показывают образцы LLVM IR, которые используют векторные инструкции через встроенные функции, такие как:

 %vl = call i32 @llvm.riscv.vsetvl(i32 8)
  

На момент обсуждения (апрель 2019 г.) Поддержка LLVM для расширения V была разработана из дерева в https://github.com/hanna-kruppe/rvv-llvm . Однако этот репозиторий сейчас заархивирован, и файл README указывает, что он устарел, поскольку поддержка расширения RISC-V V теперь разрабатывается вверх по потоку. Я предполагаю, что это означает, что функции теперь доступны из LLVM master по адресу https://github.com/llvm/llvm-project .

Однако, когда я извлекаю текущий мастер, собираю его и пытаюсь скомпилировать пример кода с llc помощью (указав цель с --mtriple=riscv32-unkown-none-rv32imv помощью), я получаю следующую ошибку:

 error: ../llvm-project/build/bin/llc: test.ll:4:18: error: use of undefined value '@llvm.riscv.vsetvl'
  

Кажется, что расширение V доступно, поскольку llc -march=riscv32 -mattr=help перечисляет его:

 Available features for this target:
...
  experimental-v           - 'V' (Vector Instructions).
  

Должен ли я явно включать целевые функции, помеченные как экспериментальные? Присутствуют ли эти векторные встроенные функции, показанные на слайдах, даже в вышестоящей версии? Если да, то как мне их использовать? Если нет, то как мне затем использовать векторные инструкции в LLVM IR?


Продолжение: в этом посте Эли Фридман объясняет, что встроенные функции, зависящие от цели, должны быть определены в include/llvm/IR/IntrinsicsRISCV.td , и действительно, в архивированном репозитории вне дерева этот файл содержит некоторые встроенные функции, зависящие от вектора, которые отсутствуют в вышестоящей версии. Если эти встроенные компоненты не были перенесены вверх по потоку, каков тогда правильный способ использования векторных инструкций RISC-V?

Комментарии:

1. Есть ли какие-либо обновления по этой теме с прошлого года?

2. @fabian Да, поддержка встроенных векторных функций была объединена в то же время и может быть использована путем включения расширения V: llc -mtriple riscv32 -mattr= experimental-v -o test.S test.ll

3. спасибо за быстрый ответ. Я пришел из riscv-gnu-toolchain, желая вместо этого использовать LLVM. Итак, я несколько новичок в LLVM. Можете ли вы указать мне некоторые ресурсы о том, как настроить набор инструментов RISC-V с векторной поддержкой rvv1.0 (встроенная или встроенная сборка)? Я хочу перейти с C / C на RISC-V binary / elf.

Ответ №1:

В riscv32 и riscv64 определены только две тройки llvm/include/llvm/ADT/Triple.h riscv.

По умолчанию HasStdExtV флаг, соответствующий experimental-v in , инициализирован значением false in llvm/lib/Target/RISCV/RISCVSubtarget.h , если вы хотите использовать это расширение, вам необходимо включить эту функцию.

Clangs, похоже, также поддерживает эту функцию. В clang/lib/Driver/ToolChains/Arch/RISCV.cpp вы можете увидеть эту v функцию поддержки march и создать experimental-v для llc.

В include/llvm/IR/IntrinsicsRISCV.td разделе «Расширение вектора» ничего нет, однако вы можете найти описание инструкций из стандартного векторного расширения «V» llvm/lib/Target/RISCV/RISCVInstrInfoV.td . Он все еще экспериментальный. В clang также можно обнаружить, что, даже если поддерживается расширение v, по умолчанию вы можете видеть // Currently LLVM supports only "mafdc". в clang/lib/Driver/ToolChains/Arch/RISCV.cpp

Комментарии:

1. Большое спасибо, что указали на это, теперь я явно включаю расширение V с -mtriple=riscv32 -mattr= experimental-v помощью in llc и с -menable-experimental-extensions -march=rv32imv0p9 помощью in clang . Тем не менее, кажется, что расширение фактически не может быть использовано, поскольку отсутствие встроенных функций означает, что векторные инструкции не могут быть использованы в LLVM IR. Если нет другого способа, который не включает встроенные функции?

2. @kassiopeia как насчет встроенного ассемблера или написания вашей векторной функции на языке ассемблера (т.Е. компиляции .s файла с помощью clang в качестве отдельной единицы перевода)? Возможно, это уже поддерживается LLVM / clang.

3. @maxschlepzig Я спросил в списке рассылки разработчиков LLVM, и мне сказали, что в настоящее время существует только поддержка MC layer (т. Е. Уровня сборки) для инструкций RISC-V V, так что да, я могу использовать векторные инструкции в коде на ассемблере. Тем не менее, я надеялся использовать функции распределения регистров и планирования инструкций LLVM, что в настоящее время невозможно.

Ответ №2:

Я спросил в списке рассылки разработчика LLVM: в настоящее время (ноябрь 2020 г.) для расширения RISC-V V в LLVM поддерживается только уровень MC (т. Е. Уровень сборки) (так что сейчас встроенных функций нет).

Однако есть RFC и исправление, которые добавляют начальную поддержку встроенных функций векторной загрузки, хранения и добавления целых чисел, а также необходимую инфраструктуру для генерации vsetvl[i] инструкций.