为什么Clang优化这个代码? [英] Why is Clang optimizing this code out?

查看:203
本文介绍了为什么Clang优化这个代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码的目的是找到表示0和1之间的值的32位浮点位模式的总数。在我看来这应该可以工作,但由于某种原因,Clang的汇编输出基本上是相当于 return 0;



我使用Clang 3.3和Clang 3.4.1编译,使用 -std = c ++ 1y -Wall -Wextra -pedantic -O2 -std = c ++ 1y -Wall -Wextra -pedantic -O3



Clang 3.4使用-O2和-O3优化所有内容。



Clang 3.3仅优化一切都离开了-O3。



通过优化一切我的意思是这是程序的汇编输出:

  main:#@main 
xorl%eax,%eax
ret



  #include< limits> 
#include< cstring>
#include< cstdint>

template< class TO,class FROM>
inline TO punning_cast(const FROM& input)
{
TO out;
std :: memcpy(& out,& input,sizeof(TO));
return out;
}

int main()
{
uint32_t i = std :: numeric_limits< uint32_t> :: min
uint32_t count = 0;

while(1)
{
float n = punning_cast< float>(i);
if(n> = 0.0f&& n< = 1.0f)
count ++;
if(i == std :: numeric_limits< uint32_t> :: max())
break;
i ++;
}

return count;
}


解决方案

这里有一个更简单的测试用例指出这是一个编译器错误:



http://coliru.stacked-crooked.com/a/58b3f9b4edd8e373

  #include< cstdint> 

int main()
{
uint32_t i = 0;
uint32_t count = 1;

while(1)
{
if(i <5)
count + = 1;

if(i == 0xFFFFFFFF)
break;
i ++;
}

return count; //应该返回6
}

程序集显示它输出1,而不是6 。它不认为它是一个无限循环,在这种情况下程序集不从main返回。


The purpose of the code is to find the total number of 32-bit floating point bit patterns which represent values between 0 and 1. It seems to me this should work, but for some reason the assembly output from Clang is basically the equivalent of return 0;.

I compiled this with Clang 3.3 and Clang 3.4.1, using -std=c++1y -Wall -Wextra -pedantic -O2 and -std=c++1y -Wall -Wextra -pedantic -O3

Clang 3.4 optimizes everything away with -O2 and -O3.

Clang 3.3 only optimizes everything away with -O3.

By "optimizes everything away" I mean that this is the assembly output of the program:

main:                                   # @main
    xorl    %eax, %eax
    ret

#include <limits>
#include <cstring>
#include <cstdint>

template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
    TO out;
    std::memcpy(&out, &input, sizeof(TO));
    return out;
}

int main()
{
    uint32_t i = std::numeric_limits<uint32_t>::min();
    uint32_t count = 0;

    while (1)
    {
        float n = punning_cast<float>(i);
        if(n >= 0.0f && n <= 1.0f)
            count++;
        if (i == std::numeric_limits<uint32_t>::max())
            break;
        i++;
    }

    return count;
}

解决方案

Here's a simpler test case which points out that it's a compiler bug:

http://coliru.stacked-crooked.com/a/58b3f9b4edd8e373

#include <cstdint>

int main()
{
    uint32_t i = 0;
    uint32_t count = 1;

    while (1)
    {
        if( i < 5 )
            count+=1;

        if (i == 0xFFFFFFFF)
            break;
        i++;
    }

    return count; // should return 6
}

The assembly shows that it outputs 1, instead of 6. It doesn't think it's an infinite loop either, in which case the assembly doesn't return from main.

这篇关于为什么Clang优化这个代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆