簡體   English   中英

為什么clang -O3會出現這種行為?

[英]Why this behavior on clang -O3?

這是一個計算整數除數的短程序。 該程序確實正常工作。 但問題是,在Clang C ++編譯器(版本3.3,主干180686)的當前主干的-O3優化標志下,程序的行為發生了變化,結果不再正確。

這是代碼:

#include <iostream>

constexpr unsigned long divisors(unsigned long n, unsigned long c)
{
    // This is supposed to sum 1 anytime a divisor shows up
    // in the recursion
    return !c ? 0 : !(n % c) + divisors(n, c - 1);
}

int main()
{
    // Here I print the number of divisors of 9 numbers! (from 1 to 9)
    for (unsigned long i = 1; i < 10; ++i)
        std::cout << i << " has " << divisors(i, i) << " divisors" << std::endl;
}

正確的行為

這是使用的編譯命令,以及程序在正常情況下顯示的正確和預期輸出:

clang++ -O2 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
./sample 
1 has 1 divisors
2 has 2 divisors
3 has 2 divisors
4 has 3 divisors
5 has 2 divisors
6 has 4 divisors
7 has 2 divisors
8 has 4 divisors
9 has 3 divisors

行為不正確

這是用於生成提供錯誤輸出的二進制文件的命令行。 請注意,唯一的變化是優化標志( -O2-O3 。)

clang++ -O3 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
./sample 
1 has 1 divisors
2 has 2 divisors
3 has 2 divisors
4 has 1 divisors
5 has 2 divisors
6 has 3 divisors
7 has 2 divisors
8 has 2 divisors
9 has 2 divisors

編輯

我已經更新到了trunk,clang 3.4版(trunk 183073)。 這種行為不再重現,應該已經以某種方式修復了。 誰知道它是什么問題,如果有一個實際驗證和修復,請隨時提供答案。 如果沒有驗證,則可能發生回歸。

看起來你被llvm中這個bug咬了一口 你可以通過禁用循環矢量化器來解決它,或者(正如你已經發現的那樣),通過更新到比r181286更新的版本的llvm構建來解決它。

如果您查看差異,您將看到已添加測試用例作為修復的一部分。 這應該可以防止這個問題在未來再次出現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM