diff options
| author | Amanieu d'Antras <amanieu@gmail.com> | 2022-10-15 22:46:59 +0100 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2022-10-15 23:42:11 +0100 |
| commit | 6bfe7f01dce5a9c4d1711dc3f30a1f9c13d9eecb (patch) | |
| tree | 71454c677701112bf233909b10969fd099ed457c | |
| parent | 6b3ede3f7bc502eba7bbd202b4b9312d812adcd7 (diff) | |
| download | rust-6bfe7f01dce5a9c4d1711dc3f30a1f9c13d9eecb.tar.gz rust-6bfe7f01dce5a9c4d1711dc3f30a1f9c13d9eecb.zip | |
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.
| -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 e723187ff1f..0254f982948 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)); |
