请教下各位,这个是编译器优化是程序问题还是编译器的问题. 实在是想不出来 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Panic
V2EX    编程

请教下各位,这个是编译器优化是程序问题还是编译器的问题. 实在是想不出来

  •  
  •   Panic 2018-07-19 19:51:58 +08:00 3088 次点击
    这是一个创建于 2716 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先叙述下我的问题,编译器是 64bit 编译器,主要代码如下:

     #define _BIT(n) (((unsigned )(1)) << (n)) void __write_icr(int idx, unsigned short value, int irq) { printk("icr_dump %d %d %d %p %p %p\n", irq, idx, value, &idx, &value, &irq); } int main() { for(int i = 1; i < 63; i++){ __write_icr(i>>4, _BIT( (i & 0x1F) ), i); } return 0; } 

    我省略了其他无关代码, 主要就是 main 函数里调用 __write_icr 函数。 注意 __write_icr 的第二个参数是 unsigned short 类型.

    我提取了编译的中间文件,main 函数里的循环对应汇编如下:

    .L31: add x19, x19, 1 cmp x19, 2 bne .L33 mov w19, 1 .loc 1 371 0 mov w20, w19 .L34: mov w2, w19 lsl w1, w20, w19 asr w0, w19, 4 bl __write_icr .LVL89: add w19, w19, 1 cmp w19, 63 bne .L34 mov w0, 64 

    不知道为什么,(i & 0x1F) 这个操作被编译器忽略掉了, 导致后续传到 __write_icr 的数据不对。

    但如果我吧 __write_icr 第二个类型修改为 unsigned int value, 编译出来就感觉是正确的。

     .L31: add x19, x19, 1 cmp x19, 2 bne .L33 mov w19, 1 .loc 1 371 0 mov w20, w19 .L34: and w1, w19, 15 mov w2, w19 lsl w1, w20, w1 asr w0, w19, 4 bl __write_icr .LVL89: add w19, w19, 1 cmp w19, 63 bne .L34 mov w0, 64 

    其中会有这句 (and w1, w19, 15), 对应着 (i & 0x1F)。 试了很多次,原因就是使用 short 类型时这句话时这个与操作被编译器优化掉了,这个是正常的吗,还是我自己理解太浅了。。。

    请各位大神帮忙指点下

    第 1 条附言    2018-07-20 08:35:01 +08:00
    (i & 0x1F) 其实是 (i & 0x0F), 这个是我后来调试改的,但问题还是上面描述的问题,f 对应的就是汇编里的 15
    3 条回复    2018-07-23 14:13:56 +08:00
    billlee
        1
    billlee  
       2018-07-19 22:56:03 +08:00   1
    不知道你这是什么架构。但我知道 x86 上的 shl, 本来就只会用 cl 中的低 5 位。所以 x86 的编译器开优化的时候一定会把那个 & 0x1f 优化掉。
    billlee
        2
    billlee  
       2018-07-19 23:20:07 +08:00   1
    不对,肯定还有哪里遇到 undefined behaviour 了

    https://gist.github.com/BillLeecn/846d96ec6a5f360d9b962e53a2acf56a

    这代码在 gcc -O0 下输出 0 1, -O1 下输出 0 0
    Panic
        3
    Panic  
    OP
       2018-07-23 14:13:56 +08:00
    @billlee 谢了, 现在搞明白了, 确实是 编译器的 bug, 找了好几天最终定位了, 之前这里贴的应该没到定位点。
    这个问题是 arm64 平台专用且遗留的问题, 在普通 gcc 和 arm 平台上都是没问题的。15 年就被修复了, 我这边厂家提供的编译器正好是有问题的。

    对应的说明和 patch 在这里: https://gcc.gnu.org/bugzilla/show_bug.cgi?format=multiple&id=64304
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1022 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 18:27 PVG 02:27 LAX 10:27 JFK 13:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86