[x86/asm] Make variants work when converting at&t inline asm input to intel asm output

`asm` always has AT&T-style input (`asm inteldialect` has Intel-style asm
input), so EmitGCCInlineAsmStr() always has to pick the same variant since it
cares about the input asm string, not the output asm string.

For PowerPC, that default variant is 1. For other targets, it's 0.

Without this, the included test case errors out with

    error: unknown use of instruction mnemonic without a size suffix
             mov rax, rbx

since it picks the intel branch and then tries to interpret it as AT&T
when selecting intel-style output with `-x86-asm-syntax=intel`.

Differential Revision: https://reviews.llvm.org/D113894
This commit is contained in:
Nico Weber 2021-11-15 10:05:12 -05:00
parent e76e572989
commit 103cc914d6
4 changed files with 31 additions and 1 deletions

View File

@ -485,6 +485,10 @@ public:
virtual bool useIPRA() const {
return false;
}
/// The default variant to use in unqualified `asm` instructions.
/// If this returns 0, `asm "$(foo$|bar$)"` will evaluate to `asm "foo"`.
virtual int unqualifiedInlineAsmVariant() const { return 0; }
};
/// Helper method for getting the code model, returning Default if

View File

@ -276,7 +276,7 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
int CurVariant = -1; // The number of the {.|.|.} region we are in.
const char *LastEmitted = AsmStr; // One past the last character emitted.
unsigned NumOperands = MI->getNumOperands();
int AsmPrinterVariant = MAI->getAssemblerDialect();
int AsmPrinterVariant = MMI->getTarget().unqualifiedInlineAsmVariant();
if (MAI->getEmitGNUAsmStartIndentationMarker())
OS << '\t';

View File

@ -68,6 +68,8 @@ public:
}
bool isLittleEndian() const;
int unqualifiedInlineAsmVariant() const override { return 1; }
};
} // end namespace llvm

View File

@ -0,0 +1,24 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -o - \
; RUN: | FileCheck --check-prefix=OUTPUT_ATT %s
; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -x86-asm-syntax=intel -o - \
; RUN: | FileCheck --check-prefix=OUTPUT_INTEL %s
define void @f() {
; OUTPUT_ATT-LABEL: f:
; OUTPUT_ATT: # %bb.0:
; OUTPUT_ATT-NEXT: #APP
; OUTPUT_ATT-NEXT: movq %rbx, %rax
; OUTPUT_ATT-NEXT: #NO_APP
; OUTPUT_ATT-NEXT: retq
;
; OUTPUT_INTEL-LABEL: f:
; OUTPUT_INTEL: # %bb.0:
; OUTPUT_INTEL-NEXT: #APP
; OUTPUT_INTEL-NEXT: mov rax, rbx
; OUTPUT_INTEL-NEXT: #NO_APP
; OUTPUT_INTEL-NEXT: ret
call void asm sideeffect "$(movq %rbx, %rax $|mov rax, rbx$)", "~{dirflag},~{fpsr},~{flags}"()
ret void
}