[AVX-512] Look for vmovdqa64/vblendm elimination / merge-mask folds made possible by inverting a conditional
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
In Zig: ([Godbolt](https://zig.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:16,fontUsePx:'0',j:1,lang:zig,selection:(endColumn:1,endLineNumber:12,positionColumn:1,positionLineNumber:12,selectionStartColumn:1,selectionStartLineNumber:12,startColumn:1,startLineNumber:12),source:'const+V+%3D+@Vector(8,+u64)%3B%0A%0Aexport+fn+foo(y:+u64,+z:+V)+V+%7B%0A++++return+@select(%0A++++++++u64,%0A++++++++z+%3D%3D+@as(V,+@splat(0)),%0A++++++++~@as(V,+@splat(0)),%0A++++++++@as(V,+@splat(y)),%0A++++)%3B%0A%7D%0A%0A'),l:'5',n:'0',o:'Zig+source+%231',t:'0')),k:49.404817415928996,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:ztrunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:20,fontUsePx:'0',j:2,lang:zig,libs:!(),options:'-O+ReleaseFast+-target+x86_64-linux+-mcpu%3Dznver5+-fomit-frame-pointer',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+zig+trunk+(Editor+%231)',t:'0')),header:(),k:50.59518258407102,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',m:100,n:'0',o:'',t:'0')),version:4))
```zig
const V = @Vector(8, u64);
export fn foo(y: u64, z: V) V {
return @select(
u64,
z == @as(V, @splat(0)),
~@as(V, @splat(0)),
@as(V, @splat(y)),
);
}
```
LLVM: ([Godbolt](https://llvm.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:llvm,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'define+internal+%3C8+x+i64%3E+@foo(i64+%250,+%3C8+x+i64%3E+%251)+unnamed_addr+align+1+%7B%0AEntry:%0A++%252+%3D+icmp+eq+%3C8+x+i64%3E+%251,+zeroinitializer%0A++%253+%3D+insertelement+%3C1+x+i64%3E+poison,+i64+%250,+i64+0%0A++%254+%3D+shufflevector+%3C1+x+i64%3E+%253,+%3C1+x+i64%3E+poison,+%3C8+x+i32%3E+zeroinitializer%0A++%255+%3D+select+%3C8+x+i1%3E+%252,+%3C8+x+i64%3E+splat+(i64+-1),+%3C8+x+i64%3E+%254%0A++ret+%3C8+x+i64%3E+%255%0A%7D%0A'),l:'5',n:'0',o:'LLVM+IR+source+%231',t:'0')),k:50.56669572798606,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:llctrunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:llvm,libs:!(),options:'-O3+-mcpu%3Dznver5',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+llc+(trunk)+(Editor+%231)',t:'0')),k:49.43330427201394,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4))
```llvm
define internal <8 x i64> @foo(i64 %0, <8 x i64> %1) unnamed_addr align 1 {
Entry:
%2 = icmp eq <8 x i64> %1, zeroinitializer
%3 = insertelement <1 x i64> poison, i64 %0, i64 0
%4 = shufflevector <1 x i64> %3, <1 x i64> poison, <8 x i32> zeroinitializer
%5 = select <8 x i1> %2, <8 x i64> splat (i64 -1), <8 x i64> %4
ret <8 x i64> %5
}
```
Compiles to:
```asm
foo:
vptestnmq k1, zmm0, zmm0
vpbroadcastq zmm0, rdi
vpternlogd zmm1, zmm1, zmm1, 255
vmovdqa64 zmm0 {k1}, zmm1
ret
```
Should be:
```asm
foo:
vptestmq k1, zmm0, zmm0
vpternlogd zmm0, zmm0, zmm0, 255
vpbroadcastq zmm0 {k1}, rdi
ret
```
Contributor guide
Research direction
Reproduce the Zig and LLVM IR examples with llc -O3 -mcpu=znver5 and compare the generated AVX-512 assembly with the desired sequence. Trace the x86 backend's handling of conditional vector moves and merge masks; done means the redundant vmovdqa64/vblendm pattern is eliminated and a regression test covers the improved code generation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- zig
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100