Skip to content

[X86][MC,Driver] Support -msse2avx to encode SSE instruction with VEX prefix #96860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b4a534a
[X86][MC] Added support for -msse2avx option in llvm-mc
JaydeepChauhan14 Jun 27, 2024
5d47f63
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jun 28, 2024
95021b6
Addressd review comments
JaydeepChauhan14 Jun 28, 2024
acf5a7d
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jun 28, 2024
0bf7123
Added support for intel syntax
JaydeepChauhan14 Jun 28, 2024
f725a31
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jun 28, 2024
8f2a402
Moved replaceSSE2AVXOpcode inside X86AsmParser::processInstruction
JaydeepChauhan14 Jun 28, 2024
5c3cfe0
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jun 29, 2024
c901194
Addressed review comments
JaydeepChauhan14 Jun 29, 2024
5069ffe
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 1, 2024
3623d8d
Added support for instructions BLENDVPD,BLENDVPS,PBLENDVB
JaydeepChauhan14 Jul 1, 2024
aeefdfa
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 2, 2024
6ca47cd
Added test for blendvpd instruction
JaydeepChauhan14 Jul 2, 2024
528e1f9
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 3, 2024
b0cca0e
Changed SSE2AVX option to bool and sync intel test
JaydeepChauhan14 Jul 3, 2024
568899c
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 8, 2024
b62d52d
Added -msse2avx as clang and -x86-sse2avx as llvm-mc options
JaydeepChauhan14 Jul 8, 2024
04266aa
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 10, 2024
7faad7f
Removed -mno-sse2avx option
JaydeepChauhan14 Jul 10, 2024
1250e44
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 11, 2024
0133d40
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 11, 2024
772da90
Addressed review comments
JaydeepChauhan14 Jul 11, 2024
8792643
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 11, 2024
b08971d
Addressed review comments
JaydeepChauhan14 Jul 11, 2024
f80b80d
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 11, 2024
d6916eb
Added mapping of BLENDVPD, BLENDVPS ,PBLENDVB in X86ManualInstrMappin…
JaydeepChauhan14 Jul 11, 2024
5210873
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 12, 2024
800ae6b
Addressed review comments
JaydeepChauhan14 Jul 12, 2024
481d338
Merge branch 'main' into added_msse2avx_option
JaydeepChauhan14 Jul 15, 2024
7d067cc
Addressed review comments
JaydeepChauhan14 Jul 15, 2024
41f0cba
Removed extra space in testcase
JaydeepChauhan14 Jul 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ VALUE_CODEGENOPT(Name, Bits, Default)
CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel
CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(SSE2AVX , 1, 0) ///< -msse2avx
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5179,6 +5179,13 @@ def mvx : Flag<["-"], "mvx">, Group<m_Group>;
def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
} // let Flags = [TargetSpecific]

let Flags = [TargetSpecific] in {
def msse2avx : Flag<["-"], "msse2avx">, Group<m_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Specify that the assembler should encode SSE instructions with VEX prefix">,
MarshallingInfoFlag<CodeGenOpts<"SSE2AVX">>;
} // let Flags = [TargetSpecific]

defm zvector : BoolFOption<"zvector",
LangOpts<"ZVector">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2545,6 +2545,13 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
switch (C.getDefaultToolChain().getArch()) {
default:
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
if (Value == "-msse2avx") {
CmdArgs.push_back("-msse2avx");
continue;
}
break;
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
if (Value == "--no-type-check") {
Expand Down
7 changes: 7 additions & 0 deletions clang/test/Driver/msse2avx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: %clang -### -c -march=x86-64 -Xassembler -msse2avx %s 2>&1 | FileCheck %s
// RUN: %clang -### -c -march=x86-64 -x assembler -Xassembler -msse2avx %s 2>&1 | FileCheck %s

// CHECK: "-msse2avx"

// RUN: not %clang -### -c --target=aarch64 -march=armv8a -msse2avx %s 2>&1 | FileCheck --check-prefix=ERR %s
// ERR: error: unsupported option '-msse2avx' for target 'aarch64'
5 changes: 5 additions & 0 deletions clang/tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned RelaxELFRelocations : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SSE2AVX : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned Dwarf64 : 1;
unsigned DwarfVersion;
std::string DwarfDebugFlags;
Expand Down Expand Up @@ -197,6 +199,7 @@ struct AssemblerInvocation {
ShowInst = 0;
ShowEncoding = 0;
RelaxAll = 0;
SSE2AVX = 0;
NoExecStack = 0;
FatalWarnings = 0;
NoWarn = 0;
Expand Down Expand Up @@ -288,6 +291,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
}

Opts.RelaxELFRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
Opts.SSE2AVX = Args.hasArg(OPT_msse2avx);
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
Expand Down Expand Up @@ -437,6 +441,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
MCOptions.Crel = Opts.Crel;
MCOptions.X86RelaxRelocations = Opts.RelaxELFRelocations;
MCOptions.X86Sse2Avx = Opts.SSE2AVX;
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;

Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/MC/MCTargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class MCTargetOptions {
// ELF.
bool X86RelaxRelocations = true;

bool X86Sse2Avx = false;

EmitDwarfUnwindType EmitDwarfUnwind;

int DwarfVersion = 0;
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ bool getCrel();

bool getX86RelaxRelocations();

bool getX86Sse2Avx();

std::string getABIName();

std::string getAsSecureLogFile();
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ MCOPT(bool, NoTypeCheck)
MCOPT(bool, SaveTempLabels)
MCOPT(bool, Crel)
MCOPT(bool, X86RelaxRelocations)
MCOPT(bool, X86Sse2Avx)
MCOPT(std::string, ABIName)
MCOPT(std::string, AsSecureLogFile)

Expand Down Expand Up @@ -140,6 +141,11 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
cl::init(true));
MCBINDOPT(X86RelaxRelocations);

static cl::opt<bool> X86Sse2Avx(
"x86-sse2avx", cl::desc("Specify that the assembler should encode SSE "
"instructions with VEX prefix"));
MCBINDOPT(X86Sse2Avx);

static cl::opt<std::string> ABIName(
"target-abi", cl::Hidden,
cl::desc("The name of the ABI to be targeted from the backend."),
Expand Down Expand Up @@ -169,6 +175,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
Options.MCSaveTempLabels = getSaveTempLabels();
Options.Crel = getCrel();
Options.X86RelaxRelocations = getX86RelaxRelocations();
Options.X86Sse2Avx = getX86Sse2Avx();
Options.EmitDwarfUnwind = getEmitDwarfUnwind();
Options.EmitCompactUnwindNonCanonical = getEmitCompactUnwindNonCanonical();
Options.AsSecureLogFile = getAsSecureLogFile();
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ static bool checkScale(unsigned Scale, StringRef &ErrMsg) {

namespace {

// Including the generated SSE2AVX compression tables.
#define GET_X86_SSE2AVX_TABLE
#include "X86GenInstrMapping.inc"

static const char OpPrecedence[] = {
0, // IC_OR
1, // IC_XOR
Expand Down Expand Up @@ -3745,7 +3749,27 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
return false;
}

static bool convertSSEToAVX(MCInst &Inst) {
ArrayRef<X86TableEntry> Table{X86SSE2AVXTable};
unsigned Opcode = Inst.getOpcode();
const auto I = llvm::lower_bound(Table, Opcode);
if (I == Table.end() || I->OldOpc != Opcode)
return false;

Inst.setOpcode(I->NewOpc);
// AVX variant of BLENDVPD/BLENDVPS/PBLENDVB instructions has more
// operand compare to SSE variant, which is added below
if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
X86::isPBLENDVB(Opcode))
Inst.addOperand(Inst.getOperand(2));

return true;
}

bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
if (MCOptions.X86Sse2Avx && convertSSEToAVX(Inst))
return true;

if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
X86::optimizeInstFromVEX3ToVEX2(Inst, MII.get(Inst.getOpcode())))
return true;
Expand Down
89 changes: 89 additions & 0 deletions llvm/test/MC/AsmParser/sse2avx-att.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# RUN: llvm-mc -triple x86_64 -x86-sse2avx %s | FileCheck %s
# RUN: llvm-mc -triple=x86_64 -output-asm-variant=1 %s | llvm-mc -triple=x86_64 -x86-asm-syntax=intel -x86-sse2avx
.text
# CHECK: vmovsd -352(%rbp), %xmm0
movsd -352(%rbp), %xmm0 # xmm0 = mem[0],zero
# CHECK-NEXT: vunpcklpd %xmm1, %xmm0, %xmm0 # xmm0 = xmm0[0],xmm1[0]
unpcklpd %xmm1, %xmm0 # xmm0 = xmm0[0],xmm1[0]
# CHECK-NEXT: vmovapd %xmm0, -368(%rbp)
movapd %xmm0, -368(%rbp)
# CHECK-NEXT: vmovapd -368(%rbp), %xmm0
movapd -368(%rbp), %xmm0
# CHECK-NEXT: vmovsd -376(%rbp), %xmm1
movsd -376(%rbp), %xmm1 # xmm1 = mem[0],zero
# CHECK-NEXT: vmovsd -384(%rbp), %xmm0
movsd -384(%rbp), %xmm0 # xmm0 = mem[0],zero
# CHECK-NEXT: vunpcklpd %xmm1, %xmm0, %xmm0 # xmm0 = xmm0[0],xmm1[0]
unpcklpd %xmm1, %xmm0 # xmm0 = xmm0[0],xmm1[0]
# CHECK-NEXT: vaddpd %xmm1, %xmm0, %xmm0
addpd %xmm1, %xmm0
# CHECK-NEXT: vmovapd %xmm0, -464(%rbp)
movapd %xmm0, -464(%rbp)
# CHECK-NEXT: vmovaps -304(%rbp), %xmm1
movaps -304(%rbp), %xmm1
# CHECK-NEXT: vpandn %xmm1, %xmm0, %xmm0
pandn %xmm1, %xmm0
# CHECK-NEXT: vmovaps %xmm0, -480(%rbp)
movaps %xmm0, -480(%rbp)
# CHECK-NEXT: vmovss -220(%rbp), %xmm1
movss -220(%rbp), %xmm1 # xmm1 = mem[0],zero,zero,zero
# CHECK-NEXT: vinsertps $16, %xmm1, %xmm0, %xmm0 # xmm0 = xmm0[0],xmm1[0],xmm0[2,3]
insertps $16, %xmm1, %xmm0 # xmm0 = xmm0[0],xmm1[0],xmm0[2,3]
# CHECK-NEXT: vmovaps %xmm0, -496(%rbp)
movaps %xmm0, -496(%rbp)
# CHECK-NEXT: vmovss -256(%rbp), %xmm0
movss -256(%rbp), %xmm0 # xmm0 = mem[0],zero,zero,zero
# CHECK-NEXT: vmovaps -192(%rbp), %xmm0
movaps -192(%rbp), %xmm0
# CHECK-NEXT: vdivss %xmm1, %xmm0, %xmm0
divss %xmm1, %xmm0
# CHECK-NEXT: vmovaps %xmm0, -192(%rbp)
movaps %xmm0, -192(%rbp)
# CHECK-NEXT: vmovd -128(%rbp), %xmm0
movd -128(%rbp), %xmm0 # xmm0 = mem[0],zero,zero,zero
# CHECK-NEXT: vpinsrd $1, %edx, %xmm0, %xmm0
pinsrd $1, %edx, %xmm0
# CHECK-NEXT: vmovaps %xmm0, -144(%rbp)
movaps %xmm0, -144(%rbp)
# CHECK-NEXT: vmovd -160(%rbp), %xmm0
movd -160(%rbp), %xmm0 # xmm0 = mem[0],zero,zero,zero
# CHECK-NEXT: vpblendw $170, %xmm1, %xmm0, %xmm0 # xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7]
pblendw $170, %xmm1, %xmm0 # xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7]
# CHECK-NEXT: vmovdqa %xmm0, -576(%rbp)
movdqa %xmm0, -576(%rbp)
# CHECK-NEXT: vphsubw %xmm1, %xmm0, %xmm0
phsubw %xmm1, %xmm0
# CHECK-NEXT: vmovdqa %xmm0, -592(%rbp)
movdqa %xmm0, -592(%rbp)
# CHECK-NEXT: vmovaps -496(%rbp), %xmm0
movaps -496(%rbp), %xmm0
# CHECK-NEXT: vroundps $8, %xmm0, %xmm0
roundps $8, %xmm0, %xmm0
# CHECK-NEXT: vmovaps %xmm0, -608(%rbp)
movaps %xmm0, -608(%rbp)
# CHECK-NEXT: vmovapd -432(%rbp), %xmm0
movapd -432(%rbp), %xmm0
# CHECK-NEXT: vpxor %xmm1, %xmm0, %xmm0
pxor %xmm1, %xmm0
# CHECK-NEXT: vmovaps %xmm0, -640(%rbp)
movaps %xmm0, -640(%rbp)
# CHECK-NEXT: vmovapd -32(%rbp), %xmm0
movapd -32(%rbp), %xmm0
# CHECK-NEXT: vmovupd %xmm0, (%rax)
movupd %xmm0, (%rax)
# CHECK-NEXT: vmovsd -656(%rbp), %xmm0
movsd -656(%rbp), %xmm0 # xmm0 = mem[0],zero
# CHECK-NEXT: extrq $16, $8, %xmm0 # xmm0 = xmm0[2],zero,zero,zero,zero,zero,zero,zero,xmm0[u,u,u,u,u,u,u,u]
extrq $16, $8, %xmm0
# CHECK-NEXT: insertq $16, $8, %xmm1, %xmm0 # xmm0 = xmm0[0,1],xmm1[0],xmm0[3,4,5,6,7,u,u,u,u,u,u,u,u]
insertq $16, $8, %xmm1, %xmm0
# CHECK-NEXT: pshufw $1, %mm0, %mm2 # mm2 = mm0[1,0,0,0]
pshufw $1, %mm0, %mm2
# CHECK-NEXT: vpblendvb %xmm2, %xmm2, %xmm1, %xmm1
pblendvb %xmm0, %xmm2, %xmm1
# CHECK-NEXT: vblendvps %xmm0, %xmm0, %xmm2, %xmm2
blendvps %xmm0, %xmm0, %xmm2
# CHECK-NEXT: vblendvpd %xmm0, %xmm0, %xmm2, %xmm2
blendvpd %xmm0, %xmm0, %xmm2
# CHECK-NEXT: vblendvpd %xmm0, %xmm0, %xmm2, %xmm2
blendvpd %xmm0, %xmm2
35 changes: 35 additions & 0 deletions llvm/utils/TableGen/X86InstrMappingEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class X86InstrMappingEmitter {
raw_ostream &OS);
void emitND2NonNDTable(ArrayRef<const CodeGenInstruction *> Insts,
raw_ostream &OS);
void emitSSE2AVXTable(ArrayRef<const CodeGenInstruction *> Insts,
raw_ostream &OS);

// Prints the definition of class X86TableEntry.
void printClassDef(raw_ostream &OS);
Expand Down Expand Up @@ -335,6 +337,38 @@ void X86InstrMappingEmitter::emitND2NonNDTable(
printTable(Table, "X86ND2NonNDTable", "GET_X86_ND2NONND_TABLE", OS);
}

void X86InstrMappingEmitter::emitSSE2AVXTable(
ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {

const std::map<StringRef, StringRef> ManualMap = {
#define ENTRY_SSE2AVX(OLD, NEW) {#OLD, #NEW},
#include "X86ManualInstrMapping.def"
};

std::vector<Entry> Table;
for (const CodeGenInstruction *Inst : Insts) {
const Record *Rec = Inst->TheDef;
StringRef Name = Rec->getName();
if (!isInteresting(Rec))
continue;
if (ManualMap.find(Name) != ManualMap.end()) {
auto *NewRec = Records.getDef(ManualMap.at(Rec->getName()));
assert(NewRec && "Instruction not found!");
auto &NewInst = Target.getInstruction(NewRec);
Table.push_back(std::pair(Inst, &NewInst));
continue;
}

std::string NewName = ("V" + Name).str();
auto *AVXRec = Records.getDef(NewName);
if (!AVXRec)
continue;
auto &AVXInst = Target.getInstruction(AVXRec);
Table.push_back(std::pair(Inst, &AVXInst));
}
printTable(Table, "X86SSE2AVXTable", "GET_X86_SSE2AVX_TABLE", OS);
}

void X86InstrMappingEmitter::run(raw_ostream &OS) {
emitSourceFileHeader("X86 instruction mapping", OS);

Expand All @@ -344,6 +378,7 @@ void X86InstrMappingEmitter::run(raw_ostream &OS) {
emitCompressEVEXTable(Insts, OS);
emitNFTransformTable(Insts, OS);
emitND2NonNDTable(Insts, OS);
emitSSE2AVXTable(Insts, OS);
}
} // namespace

Expand Down
11 changes: 11 additions & 0 deletions llvm/utils/TableGen/X86ManualInstrMapping.def
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,14 @@ NOCOMP_ND(CFCMOV64rr_ND)
ENTRY_ND(MOVBE32rr, BSWAP32r)
ENTRY_ND(MOVBE64rr, BSWAP64r)
#undef ENTRY_ND

#ifndef ENTRY_SSE2AVX
#define ENTRY_SSE2AVX(OLD, NEW)
#endif
ENTRY_SSE2AVX(BLENDVPDrm0, VBLENDVPDrmr)
ENTRY_SSE2AVX(BLENDVPDrr0, VBLENDVPDrrr)
ENTRY_SSE2AVX(BLENDVPSrm0, VBLENDVPSrmr)
ENTRY_SSE2AVX(BLENDVPSrr0, VBLENDVPSrrr)
ENTRY_SSE2AVX(PBLENDVBrm0, VPBLENDVBrmr)
ENTRY_SSE2AVX(PBLENDVBrr0, VPBLENDVBrrr)
#undef ENTRY_SSE2AVX