4 ms·
The behavior with "m" is quite strange. In theory, it should produce a memory operand pointing directly to where the function argument was passed on the stack,
by comex 8y ago
The behavior with "m" is quite strange. In theory, it should produce a memory operand pointing directly to where the function argument was passed on the stack, rather than copying it to registers and then back onto the stack. I can reproduce this with Rust nightly:
https://play.rust-lang.org/?version=nightly&mode=release https://play.rust-lang.org/?version=nightly&mode=release
However, Clang appears to do the right thing with equivalent C code:
https://godbolt.org/g/B1sjfS https://godbolt.org/g/B1sjfS
This is strange because Rust and Clang both use LLVM for their backend.
Looking at the LLVM IR produced, Rust's IR straightforwardly corresponds to the source code: a load instruction (to evaluate `self_t[0]`) whose result is passed to an asm instruction:
%0 = getelementptr inbounds %U256, %U256* %self, i64 0, i32 0, i64 0
%1 = load i64, i64* %0, align 8
tail call void asm sideeffect "mulq $0", "m,~{dirflag},~{fpsr},~{flags}"(i64 %1) #1, !srcloc !0
But Clang's omits the load, and transforms the "m" constraint to "* m" (without the space, bah HN formatting):
%2 = getelementptr inbounds %struct.U256, %struct.U256* %0, i64 0, i32 0, i64 0, !dbg !24
call void asm sideeffect "mulq $0", "*m,~{dirflag},~{fpsr},~{flags}"(i64* nonnull %2) #2, !dbg !26, !srcloc !27
Hmm… seems to be related to this Rust bug: https://github.com/rust-lang/rust/issues/16383 https://github.com/rust-lang/rust/issues/16383