[X86] VEX/EVEX prefix doesn't work for inline assembly.

For now, we lost the encoding information if we using inline assembly.
The encoding for the inline assembly will keep default even if we add
the vex/evex prefix.

Differential Revision: https://reviews.llvm.org/D90009
This commit is contained in:
Liu, Chen3 2020-10-23 11:32:19 +08:00
parent 63ba82ed00
commit 180548c5c7
4 changed files with 66 additions and 13 deletions

View File

@ -0,0 +1,25 @@
// RUN:%clang_cc1 %s -ferror-limit 0 -triple=x86_64-pc -target-feature +avx512f -target-feature +avx2 -target-feature +avx512vl -S -o - | FileCheck %s -check-prefix CHECK
// This test is to check if the prefix in inline assembly is correctly
// preserved.
void check_inline_prefix(void) {
__asm__ (
// CHECK: vcvtps2pd %xmm0, %xmm1
// CHECK: {vex} vcvtps2pd %xmm0, %xmm1
// CHECK: {vex2} vcvtps2pd %xmm0, %xmm1
// CHECK: {vex3} vcvtps2pd %xmm0, %xmm1
// CHECK: {evex} vcvtps2pd %xmm0, %xmm1
// CHECK: movl $1, (%rax)
// CHECK: {disp8} movl $1, (%rax)
// CHECK: {disp32} movl $1, (%rax)
"vcvtps2pd %xmm0, %xmm1\n\t"
"{vex} vcvtps2pd %xmm0, %xmm1\n\t"
"{vex2} vcvtps2pd %xmm0, %xmm1\n\t"
"{vex3} vcvtps2pd %xmm0, %xmm1\n\t"
"{evex} vcvtps2pd %xmm0, %xmm1\n\t"
"movl $1, (%rax)\n\t"
"{disp8} movl $1, (%rax)\n\t"
"{disp32} movl $1, (%rax)\n\t"
);
}

View File

@ -83,6 +83,7 @@ class X86AsmParser : public MCTargetAsmParser {
enum VEXEncoding {
VEXEncoding_Default,
VEXEncoding_VEX,
VEXEncoding_VEX2,
VEXEncoding_VEX3,
VEXEncoding_EVEX,
};
@ -2818,8 +2819,10 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
return Error(Parser.getTok().getLoc(), "Expected '}'");
Parser.Lex(); // Eat curly.
if (Prefix == "vex" || Prefix == "vex2")
if (Prefix == "vex")
ForcedVEXEncoding = VEXEncoding_VEX;
else if (Prefix == "vex2")
ForcedVEXEncoding = VEXEncoding_VEX2;
else if (Prefix == "vex3")
ForcedVEXEncoding = VEXEncoding_VEX3;
else if (Prefix == "evex")
@ -3837,6 +3840,7 @@ unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
return Match_Unsupported;
if ((ForcedVEXEncoding == VEXEncoding_VEX ||
ForcedVEXEncoding == VEXEncoding_VEX2 ||
ForcedVEXEncoding == VEXEncoding_VEX3) &&
(MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
return Match_Unsupported;
@ -3879,10 +3883,16 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
MCInst Inst;
// If VEX3 encoding is forced, we need to pass the USE_VEX3 flag to the
// encoder.
if (ForcedVEXEncoding == VEXEncoding_VEX3)
// If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
// encoder and printer.
if (ForcedVEXEncoding == VEXEncoding_VEX)
Prefixes |= X86::IP_USE_VEX;
else if (ForcedVEXEncoding == VEXEncoding_VEX2)
Prefixes |= X86::IP_USE_VEX2;
else if (ForcedVEXEncoding == VEXEncoding_VEX3)
Prefixes |= X86::IP_USE_VEX3;
else if (ForcedVEXEncoding == VEXEncoding_EVEX)
Prefixes |= X86::IP_USE_EVEX;
// Set encoded flags for {disp8} and {disp32}.
if (ForcedDispEncoding == DispEncoding_Disp8)

View File

@ -55,15 +55,18 @@ namespace X86 {
/// The constants to describe instr prefixes if there are
enum IPREFIXES {
IP_NO_PREFIX = 0,
IP_HAS_OP_SIZE = 1,
IP_HAS_AD_SIZE = 2,
IP_HAS_REPEAT_NE = 4,
IP_HAS_REPEAT = 8,
IP_HAS_LOCK = 16,
IP_HAS_NOTRACK = 32,
IP_USE_VEX3 = 64,
IP_USE_DISP8 = 128,
IP_USE_DISP32 = 256,
IP_HAS_OP_SIZE = 1U << 0,
IP_HAS_AD_SIZE = 1U << 1,
IP_HAS_REPEAT_NE = 1U << 2,
IP_HAS_REPEAT = 1U << 3,
IP_HAS_LOCK = 1U << 4,
IP_HAS_NOTRACK = 1U << 5,
IP_USE_VEX = 1U << 6,
IP_USE_VEX2 = 1U << 7,
IP_USE_VEX3 = 1U << 8,
IP_USE_EVEX = 1U << 9,
IP_USE_DISP8 = 1U << 10,
IP_USE_DISP32 = 1U << 11,
};
enum OperandType : unsigned {

View File

@ -346,6 +346,21 @@ void X86InstPrinterCommon::printInstFlags(const MCInst *MI, raw_ostream &O) {
O << "\trepne\t";
else if (Flags & X86::IP_HAS_REPEAT)
O << "\trep\t";
// These all require a pseudo prefix
if (Flags & X86::IP_USE_VEX)
O << "\t{vex}";
else if (Flags & X86::IP_USE_VEX2)
O << "\t{vex2}";
else if (Flags & X86::IP_USE_VEX3)
O << "\t{vex3}";
else if (Flags & X86::IP_USE_EVEX)
O << "\t{evex}";
if (Flags & X86::IP_USE_DISP8)
O << "\t{disp8}";
else if (Flags & X86::IP_USE_DISP32)
O << "\t{disp32}";
}
void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,