You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I semi regularly get asked, what even is there to do in the toolchain ?
Thus this issue track all the ideas that probably help performance of programs in the new Intel APX instruction set, so I can point at a list of stuff to do:
add an intel APX builder
decide on intel APX syntax for GOAMD64
eGPR, change the number of GP registers from 16 to 32
encoding is backward compatible, very entropically inneficient
more registers means less memory operations in complex code
more space for fixed registers (we currently only have g in GP) ?
NDD (new data destination), allows some general purpose int instruction who currently output in the first argument operand to have a proper 3 operand encoding where the sources are untouched and it writes the data into a new destination register
IMO NDD ADD (and others in the same situation) shouldn't be it's own Op different than legacy ADD to avoid duplication in rules, we can handle this by removing resultInArg0 for all of theses if GOAMD64 allows for APX and using the assembler or obj to use "legacy" ADD if the destination is equal to one of the argument, and NDD ADD otherwise
maybe this would mean add a new generator flag like apx3operands or resultInArg0IfNotUsingAPX ?
ZU flag, replace the partial result merging behavior, with a zeroing of all the bits the legacy instruction would have left unset (/ result merged).
available for IMUL with opcodes 0x69 and 0x6B in map 0 and SETcc instructions
all SETcc should be replaced with SETcc.zu as it removes result merging costs (altho I can't measure them on my AMD CPU so maybe it's just an intel skill issue ?) and zero extension cost
(I have a CL for implementing this without APX and results were underwhelming: https://go-review.googlesource.com/c/go/+/731620)
NF flag, allows instructions that traditionally set flags regardless of it being useful, to not set flags
we currently act like most of theses instructions do not set flags (only clobber them for flagalloc purposes) so no hard interactions here
I have an idea of a late pass that would remove some CMP and TEST instructions by finding previous instructions that already set the required flags in the dependency chain, this would interact with that but not much.
It's not clear what are the gains from NF, on current non APX CPUs there is no measurable cost to setting flags with let's say an ADD and never using them.
Is it just that it would allow flagalloc to do a better job since it could turn-off useless flags clobbers ? But if yes is that worth the APX encoding overhead ?
new CCMPcc instruction
looks very interesting for complex && and || chains (where the arguments do not have side effects).
it takes in a condition (like CMOV does)
if the condition is true it execute the CMP and store the results in the flags
if the condition is false it sets the OSZC flags from an immediate
new CTESTcc instruction
identical to CCMPcc but execute TEST when the condition is true rather than CMP
new CFCMOVcc instruction, allows to conditionally read and or and/or write to a memory location without branches nor sideeffects if the condition is false
identical to CMOVcc except when a memory operand is used.
for example sake let's compare CMOVcc m64, r64 with CFCMOVcc m64, r64 CMOVcc is basically equal to that pseudo-code if value := *ptr; cc(flags) { result = value } CFCMOVcc is basically equal to that pseudo-code if cc(flags) { result = *ptr }
Looks promising for removing even more branches.
along of conditional loads this allows for conditional stores
looks architecturally tricky to integrate into the branchelim pass and generic op, it's not a simple thing that wont touch anything outside of the amd64 code.
new atomic instructions, I havn't looked into the details
POP2, PUSH2, mirrors the pair pops and pair push instructions in arm64
new JMPABS instruction, jump with a 64bits immediate, remove the need for trampolines if jumping more than +-2GiB away
Tbh I don't know if anyone even has a text segment big enough, it looks to me like it's more useful for dynamic linking purposes and most go binaries are statically linked so I don't know what use this could be.
I semi regularly get asked, what even is there to do in the toolchain ?
Thus this issue track all the ideas that probably help performance of programs in the new Intel APX instruction set, so I can point at a list of stuff to do:
GOAMD64resultInArg0for all of theses if GOAMD64 allows for APX and using the assembler or obj to use "legacy" ADD if the destination is equal to one of the argument, and NDD ADD otherwiseapx3operandsorresultInArg0IfNotUsingAPX?(I have a CL for implementing this without APX and results were underwhelming: https://go-review.googlesource.com/c/go/+/731620)
CCMPccinstruction&&and||chains (where the arguments do not have side effects).CTESTccinstructionCCMPccbut executeTESTwhen the condition is true rather thanCMPCFCMOVccinstruction, allows to conditionally read and or and/or write to a memory location without branches nor sideeffects if the condition is falseCMOVccexcept when a memory operand is used.for example sake let's compare
CMOVcc m64, r64withCFCMOVcc m64, r64CMOVccis basically equal to that pseudo-codeif value := *ptr; cc(flags) { result = value }CFCMOVccis basically equal to that pseudo-codeif cc(flags) { result = *ptr }Looks promising for removing even more branches.
JMPABSinstruction, jump with a 64bits immediate, remove the need for trampolines if jumping more than +-2GiB away