From 180548c5c7848f82ceac5d6a3528a8cb14c20fed Mon Sep 17 00:00:00 2001 From: "Liu, Chen3" Date: Fri, 23 Oct 2020 11:32:19 +0800 Subject: [PATCH] [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 --- clang/test/CodeGen/X86/att-inline-asm-prefix.c | 25 ++++++++++++++++++++++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 18 ++++++++++++---- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 21 ++++++++++-------- .../X86/MCTargetDesc/X86InstPrinterCommon.cpp | 15 +++++++++++++ 4 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 clang/test/CodeGen/X86/att-inline-asm-prefix.c diff --git a/clang/test/CodeGen/X86/att-inline-asm-prefix.c b/clang/test/CodeGen/X86/att-inline-asm-prefix.c new file mode 100644 index 0000000..9bd0d93 --- /dev/null +++ b/clang/test/CodeGen/X86/att-inline-asm-prefix.c @@ -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" + ); +} diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index f13f9cb..122702a 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -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) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index b6e8d48..8b8fccf 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -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 { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp index e7b476c..96f81fa 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp @@ -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, -- 2.7.4