diff options
| author | bors <bors@rust-lang.org> | 2022-11-04 10:39:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-11-04 10:39:04 +0000 |
| commit | 47c008e440e59d793c2883f7dd712481dc965045 (patch) | |
| tree | de68e6352bb1f38909bc4a1a129d177aa31b37f5 /compiler/rustc_codegen_llvm/src/asm.rs | |
| parent | 2efb0cd4b2240c878c36112a5ec207837c15928a (diff) | |
| parent | 6bfe7f01dce5a9c4d1711dc3f30a1f9c13d9eecb (diff) | |
| download | rust-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.rs | 13 |
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)); |
