LLVM生成无效的IR

时间:2018-05-08 11:59:53

标签: c++ optimization llvm

我在玩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
}

看起来即使只有一个是needen,它也会执行两种方式 我的问题是:在这种情况下,LLVM不应该生成标签吗?为什么? 谢谢

P.S。我正在使用http://ellcc.org/demo/index.cgi进行此测试

1 个答案:

答案 0 :(得分:4)

分支可能很昂贵,因此以一条不必要的addmul指令为代价生成没有分支的代码通常会在实践中更快。

如果你使if的分支更长,你会发现它最终会变成一个合适的分支,而不是select

在这种情况下,编译器倾向于很好地理解哪个选项更快,所以除非你有特定的基准测试表明版本select比版本慢,否则我会信任它。分支。