gpt4 book ai didi

c - gcc 内联 asm 语句得到优化 - 错误的约束?

转载 作者:太空宇宙 更新时间:2023-11-03 23:54:19 24 4
gpt4 key购买 nike

我在处理 gcc 内联 asm 语句时遇到问题; gcc 似乎认为结果是一个常数(它不是)并且优化了语句。我认为我正确地使用了操作数约束,但希望就此事提出第二意见。如果问题不在我对约束的使用中,我将尝试为 gcc 错误报告隔离一个测试用例,但这可能很困难,因为即使周围代码的细微变化也会导致问题消失。

有问题的内联汇编是

static inline void
ularith_div_2ul_ul_ul_r (unsigned long *r, unsigned long a1,
const unsigned long a2, const unsigned long b)
{
ASSERT(a2 < b); /* Or there will be quotient overflow */
__asm__(
"# ularith_div_2ul_ul_ul_r: divq %0 %1 %2 %3\n\t"
"divq %3"
: "+a" (a1), "=d" (*r)
: "1" (a2), "rm" (b)
: "cc");
}

这是一个单词除数的两个单词被除数的一个非常普通的余数。请注意,输入的高位字 a2 和余数输出 *r 通过“1”约束绑定(bind)到同一寄存器 %rdx。

从周围的代码中,ularith_div_2ul_ul_ul_r() 被有效地调用,就好像被

if (s == 1)
modpp[0].one = 0;
else
ularith_div_2ul_ul_ul_r(&modpp[0].one, 0UL, 1UL, s);

所以输入的高位字 a2 是常量 1UL。gcc -S -fverbose_asm 的结果 asm 输出如下所示:

(earlier:)
xorl %r8d, %r8d # cstore.863
(then:)
cmpq $1, -208(%rbp) #, %sfp
movl $1, %eax #, tmp841
movq %rsi, -184(%rbp) # prephitmp.966, MEM[(struct __modulusredcul_t *)&modpp][0].invm
cmovne -208(%rbp), %rcx # prephitmp.966,, %sfp, prephitmp.966
cmovne %rax, %r8 # cstore.863,, tmp841, cstore.863
movq %r8, -176(%rbp) # cstore.863, MEM[(struct __modulusredcul_t *)&modpp][0].one

效果是 ularith_div_2ul_ul_ul_r() 调用的结果被假定为常量 1; divq 永远不会出现在输出中。

各种改动让问题消失;不同的编译器标志、不同的代码上下文或标记 asm block __asm__ __volatile__ (...)。然后输出正确包含 divq 指令:

#APP
# ularith_div_2ul_ul_ul_r: divq %rax %rdx %rdx -208(%rbp) # a1, tmp590, tmp590, %sfp
divq -208(%rbp) # %sfp
#NO_APP

那么,我想问这里的内联汇编人员:我是不是在约束方面做错了什么?

最佳答案

该错误仅影响 Ubuntu 版本的 gcc;据我们所知,普通的 GNU gcc 没有受到影响。该错误已报告给 Ubuntu 启动板并得到确认:Bug #1029454

关于c - gcc 内联 asm 语句得到优化 - 错误的约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11585117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com