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 --- /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 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -83,6 +83,7 @@ enum VEXEncoding { VEXEncoding_Default, VEXEncoding_VEX, + VEXEncoding_VEX2, VEXEncoding_VEX3, VEXEncoding_EVEX, }; @@ -2818,8 +2819,10 @@ 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 @@ 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 @@ 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 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -55,15 +55,18 @@ /// 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 --- a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp @@ -346,6 +346,21 @@ 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,