LLVM генерирует неэффективный ИК - PullRequest
0 голосов
/ 08 мая 2018

Я играл с LLVM и пытался скомпилировать простой код C ++, используя его

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int test = rand();
  if (test % 2)
    test += 522;
  else
    test *= 333;
  printf("test %d\n", test);
}

Особенно, чтобы проверить, как LLVM относится к ветвям кода Результат, который я получил, очень странный, он дает действительный результат при выполнении, но выглядит неэффективно

; Function Attrs: nounwind
define i32 @main() local_unnamed_addr #0 {
  %1 = tail call i32 @rand() #3
  %2 = and i32 %1, 1
  %3 = icmp eq i32 %2, 0
  %4 = add nsw i32 %1, 522
  %5 = mul nsw i32 %1, 333
  %6 = select i1 %3, i32 %5, i32 %4
  %7 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i32 %6)
  ret i32 0
}

Похоже, что он выполняет оба пути, даже если только один из них необходим Мой вопрос: не должен ли LLVM в этом случае генерировать ярлыки и почему? Спасибо

P.S. Я использую http://ellcc.org/demo/index.cgi для этого теста

1 Ответ

0 голосов
/ 08 мая 2018

Ветви могут быть дорогими, поэтому генерация кода без ветвей за счет одной ненужной инструкции add или mul, как правило, будет быстрее на практике.

Если вы сделаете ветви вашей if длиннее, вы увидите, что в конечном итоге она станет правильной веткой вместо select.

Компилятор, как правило, хорошо понимает, какой вариант быстрее и в каком случае, поэтому я бы ему поверил, если у вас нет конкретных тестов, показывающих, что версия с select медленнее, чем версия, которая разветвляется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...