llvm / llvm/llvm-project

[Intel] Broadcasting u64 from Vector of u64's should avoid `vshufps`/`vshufd` in favor of `vpermpd`/`vpermq`

Open
#195,566 3 comments 0 reactions 1 assignee Claimed by @RKSimon View on GitHub
backend:X86
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This issue is the opposite of https://github.com/llvm/llvm-project/issues/191763

[Zig Godbolt](https://zig.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:21,fontUsePx:'0',j:1,lang:zig,selection:(endColumn:27,endLineNumber:1,positionColumn:27,positionLineNumber:1,selectionStartColumn:27,selectionStartLineNumber:1,startColumn:27,startLineNumber:1),source:'export+fn+foo(x:+@Vector(4,+u64))+@Vector(8,+u64)+%7B%0A++++return+@splat(x%5B1%5D)%3B%0A%7D%0A%0Aexport+fn+bar(x:+@Vector(32,+u8))+@Vector(8,+u64)+%7B%0A++++return+@splat(@as(@Vector(4,+u64),+@bitCast(x))%5B1%5D)%3B%0A%7D'),l:'5',n:'0',o:'Zig+source+%231',t:'0')),k:44.228888164329966,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:ztrunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:21,fontUsePx:'0',j:1,lang:zig,libs:!(),options:'-O+ReleaseFast+-mcpu%3Dznver5+-target+x86_64-linux+-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:55.77111183567004,l:'4',m:53.74917053749171,n:'0',o:'',s:0,t:'0'),(g:!((h:ir,i:('-fno-discard-value-names':'0',compilerName:'zig+trunk',demangle-symbols:'0',editorid:1,filter-attributes:'0',filter-comments:'0',filter-debug-info:'0',filter-declarations:'1',filter-instruction-metadata:'0',filter-library-functions:'1',fontScale:14,fontUsePx:'0',j:1,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),show-optimized:'0',treeid:0,wrap:'1'),l:'5',n:'0',o:'LLVM+IR+Viewer+zig+trunk+(Editor+%231,+Compiler+%231)',t:'0')),header:(),l:'4',m:46.25082946250829,n:'0',o:'',s:0,t:'0')),k:55.77111183567004,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
[LLVM Godbolt](https://llvm.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:llvm,selection:(endColumn:2,endLineNumber:6,positionColumn:1,positionLineNumber:1,selectionStartColumn:2,selectionStartLineNumber:6,startColumn:1,startLineNumber:1),source:'define+%3C8+x+i64%3E+@foo(%3C32+x+i8%3E+%250)+unnamed_addr+align+1+%7B%0AEntry:%0A++%251+%3D+bitcast+%3C32+x+i8%3E+%250+to+%3C4+x+i64%3E%0A++%252+%3D+shufflevector+%3C4+x+i64%3E+%251,+%3C4+x+i64%3E+poison,+%3C8+x+i32%3E+%3Ci32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1%3E%0A++ret+%3C8+x+i64%3E+%252%0A%7D%0A%0Adefine+%3C8+x+i64%3E+@bar(%3C4+x+i64%3E+%250)+unnamed_addr+align+1+%7B%0AEntry:%0A++%251+%3D+shufflevector+%3C4+x+i64%3E+%250,+%3C4+x+i64%3E+poison,+%3C8+x+i32%3E+%3Ci32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1,+i32+1%3E%0A++ret+%3C8+x+i64%3E+%251%0A%7D%0A'),l:'5',n:'0',o:'LLVM+IR+source+%231',t:'0')),k:51.74168297455969,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:12,endLineNumber:10,positionColumn:12,positionLineNumber:10,selectionStartColumn:12,selectionStartLineNumber:10,startColumn:12,startLineNumber:10),source:1),l:'5',n:'0',o:'+llc+(trunk)+(Editor+%231)',t:'0')),k:48.25831702544031,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

```llvm
define <8 x i64> @bar(<4 x i64> %0) unnamed_addr align 1 {
Entry:
%1 = shufflevector <4 x i64> %0, <4 x i64> poison, <8 x i32>
ret <8 x i64> %1
}
```

Gives us:

```asm
bar: # @bar
vshufps xmm0, xmm0, xmm0, 238 # xmm0 = xmm0[2,3,2,3]
vbroadcastsd zmm0, xmm0
ret
```

Should be:

```asm
.LCPI0_0:
.quad 1 # 0x1
foo: # @foo
vbroadcastsd zmm1, qword ptr [rip + .LCPI0_0] # zmm1 = [1,1,1,1,1,1,1,1]
vpermpd zmm0, zmm1, zmm0
ret
```

According to @RKSimon, [we prefer the latter to avoid port 5 contention](https://github.com/llvm/llvm-project/issues/191763#issuecomment-4303382648) ([LLVM-mca](https://llvm.godbolt.org/#z:OYLghAFBqd5TKALEBjA9gEwKYFFMCWALugE4A0BIEAZgQDbYB2AhgLbYgDkAjF%2BTXRMiAZVQtGIHgBYBQogFUAztgAKAD24AGfgCsp5eiyahjEgJ5KCS8isaoiBIdWaYAwunoBXNkwOuAGQImbAA5HwAjbFIQAGZyAAd0K0chD29fAySUpyYgkPC2KJj4u2wHXJEiFlIidJ8/Hltse1SmKpqifLDI6Ljbatr6zKalQa7gnqK%2B2IBKW3QvUlROLgBqDc2NgDcI0nQWTHExpUwtgC82Nia1gEcAdzIzhKJSNYBSAFYAIVICBI%2BACZvmsAHQBNyqACSWgA%2BlovgARIGxNaXa4fWLIr7fJp48j4wlI95aACCWy22wS0TYCTO6MB5DRVxu6IRZK483o3E%2B/D8XB05HQ3FJrHolmsayUi2W2BRfHIRG0nPmAGsQJ8tIZuNJ%2BGwNVr%2BYLhVx%2BEoQFqlQLOeQ4LAUBgcPhiGRKNQ6IxWBxuArBMIxBJODI5MJlGpNNbyPpGUYTCAzOKrDYyhVnBBXMNGuRApNCsV%2BtliLlM1lkkWhN08zNmq1KuMS6MWuU2h1apXeiUBp0G1227mO3F5tKlituBTNtslEgvDQEko1uoroyF1ctSu2GvAbEABzjinvLfrrSY5GLjc4xnxS/Esl7ta7faHY5EU4XJdMs%2BAkmkm3cri88gjX4E1RQsJMpRlFYUUBfgrR0WZ5iQbBDj6CAuR1PUDUA5UhW4M0LUVZUEPIdVpB4UEADZt0%2BT5pE%2BABOeitC0WIeAAdhjbhYj5HCTVgojbUQO0EHgCAHXQWkGGiN0IAwSTGBieh6G2NgAFo2HEV4vCYVUBAYIhonNCAIhwiJghqcwfX4MzWFIcwAHkIl0ZsrPIOSOGEeymHFHCcAiLxgDcCR6HNXh%2BBwNhjGASRI0IUhmwIbZsFCwVsHUcovAM1zggMv9BXoAg9gsjwcBw14CH1MLyCS0gImSbBEWwSKTAKuNrXmGgjGAJQADUCGwe57OpflfXkANJGDP1FBUDQcP0JpY1MMUJRsAqInNSB5nQF5clC9TUASLx3ixdRtwo1SKOkVTtl1IUar%2BHANrQmsErTDNPAafwmEwdtphiJpCzaHtAdyX780bWshFbOoPpGF7U3acYwb6UZ61hrMxk6ZH/qHSCg3Q/8eMjE01iUlT9pYNYIC0nTZip50SDeA9WNmfj2sQ5CcBiZ71U1bUuFu/U%2BaA3DTVsAi4JtYSxLQCSEikigqFkuWFZAMm1I0lgad0j0DNIIyTMjGyLNc427Mc5yHFc9zmCILyfNi7B/MC4LQoVCKopiwU4oSpKUv4NKMqyqqcpaHC1tIYqsFWQVysqhUarqlRGua6LglAdqBC63r%2BsG4bXKm8ag1kKaw1myN9HiRb42WpNDEKp6tp2oQ9o0w7jsRYBI6YYhohYeXMCUYD7oIR74CHJsEZcb6exzAoBwBssgfR0scgrfs/oMFMWzRjIMcnnesY38Hexhvet6R4%2BUdxkd8f5gCRZJ9WKap7W6YgBmyHlVnCPZ8gkJQtzNUWE/y3UfnhcWloiIExguQIWhpeIQMlvMaWQlxLyWkkrOS8sFJq2UhrTSpBtI630oZaghtBRm0slVKhFsXJVRtp5by1DvZOwCkFJSbtwpNU9jHcKBB4oVD9jhQOqBMqrAVKHPK/AI5R1KpGOOrlE71RTp7dOAlOosG6n1AaQ1mAFzGuICaJd5BlwjIKaMhgoo1zAtYeu61x5CmbkwVuB0jonTOhdK6N1h7RAeslRx29cjT3cCvLc2ZvrYwLEvYsK9F5rzyFfTsQSoa70%2BuElJiMj7z03qUNJcNMZ9hyfmOYCxb4gEBATB%2BiD1jP01q/IhtN6aEEZtBH%2ByCOaAOoMAvmoDMLCxqfhKBmdpboJwZg6g2DVZ1MIcQvS9A9YG1MuZOypsVkOScvQhUjC7bMN8mwl2nDXIexanw8gPshEBMjKI8R2VhBh0jLIuyJUzmKKqso5OPCWrqMzpo7Ruc9EjX4IXIxxcQzTXDHNEAshq4JhWvYxuTi2iuPbliLuxhe6RwHkPO6fjR4BM2vDNoITZ6RKSavcsTBgYxPXsUlGRK6zdjiQy1J2Spgn0KWfT6qM2VVhxmU2UFSqlE2NGOGZlNqaNNVO/T%2BTMtyVLZvBTpXNukkRARhbCxMIHmmGUq/msD4GatFWLDparPjblBKxaQdFpDMUYlRQE9F%2BbcSNcBJB0D9UirdSaj1NUrDOGkEAA%3D%3D%3D)):
> For intel targets the shufps+vbroadcastsd is likely to be port5 bound - so the vpermpd approach is going to be better - we assume this for x86-64-v4 generic as well.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.