summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/asm.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-11-04 10:39:04 +0000
committerbors <bors@rust-lang.org>2022-11-04 10:39:04 +0000
commit47c008e440e59d793c2883f7dd712481dc965045 (patch)
treede68e6352bb1f38909bc4a1a129d177aa31b37f5 /compiler/rustc_codegen_llvm/src/asm.rs
parent2efb0cd4b2240c878c36112a5ec207837c15928a (diff)
parent6bfe7f01dce5a9c4d1711dc3f30a1f9c13d9eecb (diff)
downloadrust-47c008e440e59d793c2883f7dd712481dc965045.tar.gz
rust-47c008e440e59d793c2883f7dd712481dc965045.zip
Auto merge of #103098 - Amanieu:asm-tied-fixed, r=bjorn3
asm: Match clang behavior for inlateout fixed register operands

We have 2 options for representing LLVM constraints for `inlateout` operands on a fixed register (e.g. `r0`): `={r0},0` or `={r0},{r0}`.

This PR changes the behavior to the latter, which matches the behavior of Clang since https://reviews.llvm.org/D87279.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/asm.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs13
1 files changed, 11 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 017513721b7..88a4f62d93d 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -130,7 +130,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     op_idx.insert(idx, constraints.len());
                     constraints.push(reg_to_llvm(reg, Some(&value.layout)));
                 }
-                InlineAsmOperandRef::InOut { reg, late: _, in_value, out_place: _ } => {
+                InlineAsmOperandRef::InOut { reg, late, in_value, out_place: _ } => {
                     let value = llvm_fixup_input(
                         self,
                         in_value.immediate(),
@@ -138,7 +138,16 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                         &in_value.layout,
                     );
                     inputs.push(value);
-                    constraints.push(format!("{}", op_idx[&idx]));
+
+                    // In the case of fixed registers, we have the choice of
+                    // either using a tied operand or duplicating the constraint.
+                    // We prefer the latter because it matches the behavior of
+                    // Clang.
+                    if late && matches!(reg, InlineAsmRegOrRegClass::Reg(_)) {
+                        constraints.push(format!("{}", reg_to_llvm(reg, Some(&in_value.layout))));
+                    } else {
+                        constraints.push(format!("{}", op_idx[&idx]));
+                    }
                 }
                 InlineAsmOperandRef::SymFn { instance } => {
                     inputs.push(self.cx.get_fn(instance));