加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 为什么没有clang / llvm优化这个?

发布时间:2020-12-16 07:17:45 所属栏目:百科 来源:网络整理
导读:用clang 3.9编译这段代码时: constexpr bool is_small(long long v) { return v 0x4000000000000000;}int foo();int f(int a) { if (is_small(a)) return a; else return foo();} 它产生相当于int f(int a)的汇编{return a;因为它确定is_small(a)将永远为真
用clang 3.9编译这段代码时:

constexpr bool is_small(long long v) {
  return v < 0x4000000000000000;
}
int foo();
int f(int a) {
  if (is_small(a)) return a;
  else return foo();
}

它产生相当于int f(int a)的汇编{return a;因为它确定is_small(a)将永远为真,因为a是一个int,它(在我的平台上)总是小于0x4000000000000000.

当我将is_small更改为:

constexpr bool is_small(long long v) {
  return v >= -0x4000000000000000;
}

正如预期的那样,完全相同.

但是,当我更改is_small以检查两个条件时:

constexpr bool is_small(long long v) {
  return v < 0x4000000000000000 && v >= -0x4000000000000000;
}

clang没有优化if和返回foo()部分.

(这是关于Godbolt的上述片段,可以玩:https://godbolt.org/g/fnoE9A)

为什么会这样?它清楚地得出结论,个别条件总是正确的,为什么这不延伸到两者的逻辑结合?

解决方法

没有充分的理由,这是LLVM缺少的优化.提交 https://llvm.org/bugs/show_bug.cgi?id=30794以确保它得到修复.

基本上LLVM首先在内联它并优化f()中的使用之前优化is_small.在优化is_small时,它正在转变比较v< 0x4000000000000000&& v> = -0x4000000000000000到v 0x4000000000000000> -1.内联后,优化器无法识别这种新形式,允许在f()中不断折叠代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读