Сначала прохладная история чисто поржать и излить нервы, т.к. все равно чую придется в мейл-листе спрашивать
сижу пишу бэк к LLVM. у железки CMP отсутствует, флаги выставляются через SUB. соответственно бранч выглядит как sub + br_cc
. Начинаю замечать что бранчи периодически оттупают. смотрю дебаг. в момент когда происходит сравнение с числом, в частности с нулем, LLVM увидев строку sub r0, r0, 0
с умным видом подмечает «норкоман чтоле?» и нафиг удаляет эту инструкцию. бьюсь с этой падлой уже часа четыре, хоть бы хрен.
ну и собственно вопрос, можт кто знает. как правильно реализовать в LLVM бранч (BR_CC
) используя sub и отдельный статус-регистр (imp-def). пока сделал так:
- есть кастомный lowering, который сначала берет
ISD::SUB
илиISD::FSUB
в зависимости от типа регистра/переменной. - результат скармливается в кастомный
MyISD::BCC
в качестве третьего аргумента помимо адреса и условия. - собственно в InstrInfo.td есть 4 строки с бранчем для 4 типов регистров.
косяк в том что во время оптимизации бранчей в insertBranch требуется добавить аргумент-регистр, что в отдельных случаях нафиг все ломает. да и вообще это довольно странно выглядит. ну и вылазят вот такие занятные «оптимизации» типа описанной выше.
пытался подсунуть в паттерн imp-def статус-регистр, который выставляется вычитанием, но поскольку этот регистр идет вторым аргументом LLVM начинает пытаться заюзать COPY на него, что чревато (делается через жопу в 3 шага минимум) и вообще делать смысла не имеет в данном случае.
пытался поставить glue на вычитание, но стандартный SUB этого дела не имеет, как и chain. смотрел другие варианты - народ юзает glue, но лепит хренову кучу кастомных ISD.
не, можно конечно расписать кастомные ISD и паттерны на каждый тип данных, но это сейчас их 5 штук, а если залезть в вектор - там все 15 будут. хотелось бы оставить просто ISD::SUB
, поскольку он в любом случае расписан для всех типов.
p.s. код если что лежит тут, ветка bugfixes.