Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 为什么编译器要重新计算另一个寄存器中已有的值?_Assembly_Rust_X86_Llvm_Compiler Optimization - Fatal编程技术网

Assembly 为什么编译器要重新计算另一个寄存器中已有的值?

Assembly 为什么编译器要重新计算另一个寄存器中已有的值?,assembly,rust,x86,llvm,compiler-optimization,Assembly,Rust,X86,Llvm,Compiler Optimization,我在研究Rust编译器生成的机器代码。下面是一个简单的函数,用于计算切片中所有元素的总和。(在Rust中,片本质上是一个数组,其长度通常只有在运行时才知道。它位于连续的内存区域中,由指向第一个元素和元素数的指针来描述。) fn求和命令(切片:&[i64])->i64{ 设mut和=0; 在片中的n{ 总和+=n; } 总和 } 禁用SSE并启用优化后,rustc 1.46.0的启动方式如下: 示例::求和命令: 测试rsi,rsi 乙脑LBB0_1 lea-rax,[8*rsi-8] mov-

我在研究Rust编译器生成的机器代码。下面是一个简单的函数,用于计算切片中所有元素的总和。(在Rust中,片本质上是一个数组,其长度通常只有在运行时才知道。它位于连续的内存区域中,由指向第一个元素和元素数的指针来描述。)

fn求和命令(切片:&[i64])->i64{
设mut和=0;
在片中的n{
总和+=n;
}
总和
}
禁用SSE并启用优化后,rustc 1.46.0的启动方式如下:

示例::求和命令:
测试rsi,rsi
乙脑LBB0_1
lea-rax,[8*rsi-8]
mov-rdx,rax
shr-rdx,3
添加rdx,1
这里,片中元素N的数量在
rsi
中。如果我的理解正确,代码首先计算8N−8并将其存储在
rax
中。然后使用该结果计算(8N−8) /8+1并将其存储在
rdx
中。假设没有溢出,则
rdx
结果应始终等于在
rsi
中仍然可用的原始值N


为什么编译器要重新计算N的值,而不是使用rsi中已有的值?

是的,很奇怪,看起来它是在计算最后一个元素的字节偏移量,然后将其转换回元素计数。也许有些Rust逻辑使用无符号数学进行计算,使得LLVM后端认为它确实需要保留可能的截断行为。这纯粹是猜测,但可以解释这个遗漏的优化错误。(你可能应该在rustc bug跟踪器上报告。)我认为安全代码不会溢出
rax
。毕竟,它是片中最后一个元素的字节偏移量,应该完全适合64位寄存器。LLVM可能没有足够的信息来证明溢出行为与此无关。无论如何,我认为您需要向Rust或LLVM开发人员提出这个问题,以获得有用的答案。