Index: llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -94,6 +94,14 @@ "indirect indicates indirect jumps."), cl::location(X86AlignBranchKindLoc)); +cl::opt X86AlignBranchWithin32BBoundaries( + "x86-branches-within-32B-boundaries", cl::init(false), + cl::desc( + "Align selected instructions to mitigate negative performance impact " + "of Intel's micro code update for errata skx102. May break " + "assumptions about labels corresponding to particular instructions, " + "and should be used with caution.")); + class X86ELFObjectWriter : public MCELFObjectTargetWriter { public: X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, @@ -119,8 +127,21 @@ X86AsmBackend(const Target &T, const MCSubtargetInfo &STI) : MCAsmBackend(support::little), STI(STI), MCII(T.createMCInstrInfo()) { - AlignBoundary = assumeAligned(X86AlignBranchBoundary); - AlignBranchType = X86AlignBranchKindLoc; + if (X86AlignBranchWithin32BBoundaries) { + // At the moment, this defaults to aligning fused branches, unconditional + // jumps, and (unfused) conditional jumps with nops. Both the + // instructions aligned and the alignment method (nop vs prefix) may + // change in the future. + AlignBoundary = assumeAligned(32);; + AlignBranchType.addKind(X86::AlignBranchFused); + AlignBranchType.addKind(X86::AlignBranchJcc); + AlignBranchType.addKind(X86::AlignBranchJmp); + } + // Allow overriding defaults set by master flag + if (X86AlignBranchBoundary.getNumOccurrences()) + AlignBoundary = assumeAligned(X86AlignBranchBoundary); + if (X86AlignBranch.getNumOccurrences()) + AlignBranchType = X86AlignBranchKindLoc; } bool allowAutoPadding() const override; Index: llvm/test/MC/X86/align-branch-64-1a.s =================================================================== --- llvm/test/MC/X86/align-branch-64-1a.s +++ llvm/test/MC/X86/align-branch-64-1a.s @@ -2,10 +2,14 @@ # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t1 # RUN: FileCheck --input-file=%t1 %s +# Check that -x86-branches-within-32B-boundaries matches the above command line +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t2 +# RUN: cmp %t1 %t2 + # Check no branches is aligned with option --x86-align-branch-boundary=0 -# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t2 -# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t3 -# RUN: cmp %t2 %t3 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t3 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %p/Inputs/align-branch-64-1.s | llvm-objdump -d - > %t4 +# RUN: cmp %t3 %t4 # CHECK: 0000000000000000 foo: # CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1