Instruction
VPERMILPD
Rearranges doubles within each 128-bit lane, controlled by an immediate or by a vector.
VPERMILPD chooses, for each double of the result, one of the two doubles of the same 128-bit lane of its source. It is the double-precision side of VPERMILPS, whose page covers the two kinds of control and the rule that no element leaves its lane; VPERMPD crosses lanes. With only two candidates per lane, each element needs one selector bit, and the two controls place it differently from the single-precision form.
Bit 1 of each quadword
In the vector form, the bit that chooses is bit 1 of the matching
quadword of the control; bit 0 and the other 62 bits are ignored.
Zen 5’s recorded case vpermilpd ymm7, ymm11, ymm7 shows it with
control quadwords ending in 2Ch, 36h, F2h and 99h: the first and the
last, with bit 1 clear, took the low double of their lane, although
99h has bit 0 set; the other two took the high one. A control vector
of indices 0 and 1, as VPERMILPS would read them, therefore selects the
low double everywhere; indices must be doubled, 0 and 2.
One immediate bit per element
The immediate form gives each element its own bit, not one pattern
repeated per lane: bits 1:0 for an xmm register, 3:0 for ymm and all
eight for zmm. vpermilpd ymm4, ymm4, 0x57 (bits 3:0 are 0111b) took
element 1 into elements 0 and 1, element 3 into element 2 and element
2 into element 3, on Zen 5 as in the manuals. Swapping the two doubles
of every lane is 1 for xmm and 5 for ymm.
In compiled code
GCC 14 at -O2 with -mavx emits the immediate form for one-register
shuffles of doubles within lanes: vpermilpd xmm0, xmm0, 1 for a swap,
5 for the swap in both lanes of a ymm register and 0 to repeat the low
double of each lane. Clang 23 writes the swaps as
VSHUFPD of a register with itself and the repeat as
VMOVDDUP, and uses VPERMILPD when the source comes
from memory, as with VPERMILPS. Both emit the vector form for
_mm256_permutevar_pd. AMD’s Zen 5 guide gives the immediate form a
latency of 1 cycle on all four vector pipes and the vector form 2 cycles
on two.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
VPERMILPD xmm, xmm, m128
VPERMILPD_XMMdq_XMMdq_MEMdq | VEX.128.66.0F38.W0 0D /r | AVX |
VPERMILPD xmm, xmm, xmm
VPERMILPD_XMMdq_XMMdq_XMMdq | VEX.128.66.0F38.W0 0D /r | AVX |
VPERMILPD ymm, ymm, m256
VPERMILPD_YMMqq_YMMqq_MEMqq | VEX.256.66.0F38.W0 0D /r | AVX |
VPERMILPD ymm, ymm, ymm
VPERMILPD_YMMqq_YMMqq_YMMqq | VEX.256.66.0F38.W0 0D /r | AVX |
VPERMILPD xmm, m128, imm8
VPERMILPD_XMMdq_MEMdq_IMMb | VEX.128.66.0F3A.W0 05 /r ib | AVX |
VPERMILPD xmm, xmm, imm8
VPERMILPD_XMMdq_XMMdq_IMMb | VEX.128.66.0F3A.W0 05 /r ib | AVX |
VPERMILPD ymm, m256, imm8
VPERMILPD_YMMqq_MEMqq_IMMb | VEX.256.66.0F3A.W0 05 /r ib | AVX |
VPERMILPD ymm, ymm, imm8
VPERMILPD_YMMqq_YMMqq_IMMb | VEX.256.66.0F3A.W0 05 /r ib | AVX |
VPERMILPD zmm {k}{z}, zmm, imm8
VPERMILPD_ZMMf64_MASKmskw_ZMMf64_IMM8_AVX512 | EVEX.512.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F |
VPERMILPD zmm {k}{z}, m512/m64bcst, imm8
VPERMILPD_ZMMf64_MASKmskw_MEMf64_IMM8_AVX512 | EVEX.512.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F |
VPERMILPD zmm {k}{z}, zmm, zmm
VPERMILPD_ZMMf64_MASKmskw_ZMMf64_ZMMf64_AVX512 | EVEX.512.66.0F38.W1 0D /r | AVX10.1 or AVX512F |
VPERMILPD zmm {k}{z}, zmm, m512/m64bcst
VPERMILPD_ZMMf64_MASKmskw_ZMMf64_MEMf64_AVX512 | EVEX.512.66.0F38.W1 0D /r | AVX10.1 or AVX512F |
VPERMILPD xmm {k}{z}, xmm, imm8
VPERMILPD_XMMf64_MASKmskw_XMMf64_IMM8_AVX512 | EVEX.128.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD xmm {k}{z}, m128/m64bcst, imm8
VPERMILPD_XMMf64_MASKmskw_MEMf64_IMM8_AVX512 | EVEX.128.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD xmm {k}{z}, xmm, xmm
VPERMILPD_XMMf64_MASKmskw_XMMf64_XMMf64_AVX512 | EVEX.128.66.0F38.W1 0D /r | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD xmm {k}{z}, xmm, m128/m64bcst
VPERMILPD_XMMf64_MASKmskw_XMMf64_MEMf64_AVX512 | EVEX.128.66.0F38.W1 0D /r | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD ymm {k}{z}, ymm, imm8
VPERMILPD_YMMf64_MASKmskw_YMMf64_IMM8_AVX512 | EVEX.256.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD ymm {k}{z}, m256/m64bcst, imm8
VPERMILPD_YMMf64_MASKmskw_MEMf64_IMM8_AVX512 | EVEX.256.66.0F3A.W1 05 /r ib | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD ymm {k}{z}, ymm, ymm
VPERMILPD_YMMf64_MASKmskw_YMMf64_YMMf64_AVX512 | EVEX.256.66.0F38.W1 0D /r | AVX10.1 or AVX512F + AVX512VL |
VPERMILPD ymm {k}{z}, ymm, m256/m64bcst
VPERMILPD_YMMf64_MASKmskw_YMMf64_MEMf64_AVX512 | EVEX.256.66.0F38.W1 0D /r | AVX10.1 or AVX512F + AVX512VL |
Latency and throughput
| Model | xmm, xmm, m128xmm {k}{z}, xmm, m128/m64bcst | xmm, xmm, xmm | ymm, ymm, m256ymm {k}{z}, ymm, m256/m64bcst | ymm, ymm, ymmzmm {k}{z}, zmm, zmmxmm {k}{z}, xmm, xmmymm {k}{z}, ymm, ymm | xmm, m128, imm8xmm {k}{z}, m128/m64bcst, imm8 | xmm, xmm, imm8xmm {k}{z}, xmm, imm8ymm {k}{z}, ymm, imm8 | ymm, m256, imm8ymm {k}{z}, m256/m64bcst, imm8 | ymm, ymm, imm8 | zmm {k}{z}, zmm, imm8 | zmm {k}{z}, m512/m64bcst, imm8 | zmm {k}{z}, zmm, m512/m64bcst |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Sandy Bridge, Haswell, Skylake | 7 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | 7 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | |||
| Broadwell | 6 / 1p5 | 1 / 1p5 | 7 / 1p5 | 1 / 1p5 | 6 / 1p5 | 1 / 1p5 | 7 / 1p5 | 1 / 1p5 | |||
| Skylake-SP, Ice Lake | 7 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | 7 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | 1 / 1p5 | 8 / 1p5 | 8 / 1p5 |
| Alder Lake | 8 / 1p5 | 1 / 1p5 | 9 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | 9 / 1p5 | 1 / 1p5 | |||
| Sapphire Rapids | 8 / 1p5 | 1 / 1p5 | 9 / 1p5 | 1 / 1p5 | 8 / 1p5 | 1 / 1p5 | 9 / 1p5 | 1 / 1p5 | 1 / 1p5 | 9 / 1p5 | 9 / 1p5 |
| Lunar Lake | 8 / 0.5V2 V3 | 1 / 0.5V2 V3 | 9 / 0.5V2 V3 | 1 / 0.5V2 V3 | 7 / 2V2 V3 | 1 / 0.5V2 V3 | 9 / 0.5V2 V3 | 1 / 0.5V2 V3 | |||
| Piledriver | 8 / 1.5FPU1 FPXBR | 3 / 1FPU1 FPXBR | 8 / 2FPU1 FPXBR | 3 / 2FPU1 FPXBR | 7 / 1.5FPFMA FPU0 FPU1 | 2 / 1FPFMA FPU0 FPU1 | 7 / 2FPFMA FPU0 FPU1 | 2 / 2FPFMA FPU0 FPU1 | |||
| Zen | 8 / 0.5FPU1 FPU2 | 1 / 0.5FPU1 FPU2 | 8 / 1FPU1 FPU2 | 1 / 1FPU1 FPU2 | 8 / 0.5FPU1 FPU2 | 1 / 0.5FPU1 FPU2 | 8 / 1FPU1 FPU2 | 1 / 1FPU1 FPU2 | |||
| Zen 2 | 10 / 0.5FPU1 FPU2 | 3 / 0.5FPU1 FPU2 | 10 / 0.5FPU1 FPU2 | 3 / 0.5FPU1 FPU2 | 8 / 0.5FPU1 FPU2 | 1 / 0.5FPU1 FPU2 | 8 / 0.5FPU1 FPU2 | 1 / 0.5FPU1 FPU2 | |||
| Zen 3 | 10 / 0.5FP1 FP2 | 3 / 0.5FP1 FP2 | 10 / 0.5FP1 FP2 | 3 / 0.5FP1 FP2 | 8 / 0.5FP1 FP2 | 1 / 0.5FP1 FP2 | 8 / 0.5FP1 FP2 | 1 / 0.5FP1 FP2 | |||
| Zen 4 | 10 / 0.5FP1 FP2 | 3 / 0.5FP1 FP2 | 10 / 0.5FP1 FP2 | 2 / 0.671FP1 FP2 FP3 | 8 / 0.5FP1 FP2 | 1 / 0.5FP1 FP2 | 8 / 0.5FP1 FP2 | 1 / 0.5FP1 FP2 | 1 / 1FP1 FP2 | 8 / 1FP1 FP2 | 10 / 1FP1 FP2 |
| Jaguar | 8 / 2FPA FPM FPU0 FPU1 | 3 / 2FPA FPM FPU0 FPU1 | 9 / 3FPA FPM FPU0 FPU1 | 4 / 3FPA FPM FPU0 FPU1 | 6 / 1FPA FPM FPU0 FPU1 | 1 / 0.5FPA FPM FPU0 FPU1 | 6 / 2FPA FPM FPU0 FPU1 | 1 / 1FPA FPM FPU0 FPU1 | |||
Data flow
Where the elements of the sources go, element 0 on the right; results that depend on a control value are drawn for an example. How to read.
VPERMILPD xmm, xmm, xmm/m128 VPERMILPD ymm, ymm, ymm/m256 VPERMILPD xmm {k}{z}, xmm, xmm/m128/m64bcst VPERMILPD ymm {k}{z}, ymm, ymm/m256/m64bcst VPERMILPD zmm {k}{z}, zmm, zmm/m512/m64bcstExample index vector in xmm3 (element 0 on the right); only bit 1 counts. The ymm and zmm forms repeat this in each 128-bit lane. The EVEX forms write under a mask: where its bit is 0, the element keeps its old value, or zeroes it with {z}.
With the example indices, result doubles 1 to 0: a0, a1.
VPERMILPD xmm, xmm/m128, imm8 VPERMILPD ymm, ymm/m256, imm8 VPERMILPD xmm {k}{z}, xmm/m128/m64bcst, imm8 VPERMILPD ymm {k}{z}, ymm/m256/m64bcst, imm8 VPERMILPD zmm {k}{z}, zmm/m512/m64bcst, imm8Example: imm8 = 0x01 (0000 0001 in binary). The ymm and zmm forms repeat this in each 128-bit lane, with the next bits of imm8. The EVEX forms write under a mask: where its bit is 0, the element keeps its old value, or zeroes it with {z}. With m64bcst, one double from memory stands for every element of xmm2.
With imm8 = 0x01, result doubles 1 to 0: a0, a1.
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
VPERMILPD xmm, xmm, xmm/m128 VPERMILPD ymm, ymm, ymm/m256 VPERMILPD xmm {k}{z}, xmm, xmm/m128/m64bcst VPERMILPD ymm {k}{z}, ymm, ymm/m256/m64bcst VPERMILPD zmm {k}{z}, zmm, zmm/m512/m64bcstfor i in range(VL // 64):
if k1[i]: # 1 without a write mask
x = src3.q[i]
j = i - i % 2 + (x >> 1 & 1)
zmm1.q[i] = zmm2.q[j]
elif zeroing:
zmm1.q[i] = 0
# else: zmm1.q[i] keeps its value
# m64bcst: src3.f64[i] is the m64 for every i
# zmm1 is zeroed from bit VL upRun on AMD Zen 5 (EPYC 9645): 10 cases.
VPERMILPD xmm, xmm/m128, imm8 VPERMILPD ymm, ymm/m256, imm8 VPERMILPD xmm {k}{z}, xmm/m128/m64bcst, imm8 VPERMILPD ymm {k}{z}, ymm/m256/m64bcst, imm8 VPERMILPD zmm {k}{z}, zmm/m512/m64bcst, imm8for i in range(VL // 64):
j = i - i % 2 + (imm8 >> i & 1)
if k1[i]: # 1 without a write mask
zmm1.q[i] = src2.q[j]
elif zeroing:
zmm1.q[i] = 0
# else: zmm1.q[i] keeps its value
# m64bcst: src2.f64[i] is the m64 for every i
# zmm1 is zeroed from bit VL upRun on AMD Zen 5 (EPYC 9645): 10 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
VPERMILPD xmm, xmm, xmm/m128 VPERMILPD ymm, ymm, ymm/m256 | ||
xmm, ymm | explicit | write |
xmm, ymm | explicit | read |
xmm/m128, ymm/m256 | explicit | read |
VPERMILPD xmm, xmm/m128, imm8 VPERMILPD ymm, ymm/m256, imm8 | ||
xmm, ymm | explicit | write |
xmm/m128, ymm/m256 | explicit | read |
imm8 | explicit | read |
VPERMILPD xmm {k}{z}, xmm/m128/m64bcst, imm8 VPERMILPD ymm {k}{z}, ymm/m256/m64bcst, imm8 VPERMILPD zmm {k}{z}, zmm/m512/m64bcst, imm8 | ||
xmm, ymm, zmm | explicit | write (masked) |
{k} | explicit | read (write mask) |
xmm/m128/m64bcst, ymm/m256/m64bcst, zmm/m512/m64bcst | explicit | read |
imm8 | explicit | read |
VPERMILPD xmm {k}{z}, xmm, xmm/m128/m64bcst VPERMILPD ymm {k}{z}, ymm, ymm/m256/m64bcst VPERMILPD zmm {k}{z}, zmm, zmm/m512/m64bcst | ||
xmm, ymm, zmm | explicit | write (masked) |
{k} | explicit | read (write mask) |
xmm, ymm, zmm | explicit | read |
xmm/m128/m64bcst, ymm/m256/m64bcst, zmm/m512/m64bcst | explicit | read |
Flags
None: XED records no flag that the forms test or change.
Exceptions
The exception class is XED's name for the set of exception conditions that a form follows. How to read.
- VEX forms
avx-type-6- EVEX forms
AVX512-E4NF
Attributes
What else XED records about the forms. How to read.
- EVEX forms
- write masking
- EVEX memory forms
- embedded broadcast (tuple Full)
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to VPERMILPD, each with the form it compiles to and the Clang options it needs. The forms come from compiling every intrinsic and decoding the result with Intel XED; all intrinsics A–Z explains the method.
| Intrinsic | Compiles to |
|---|---|
_mm_permutevar_pd
__m128d _mm_permutevar_pd(__m128d __a, __m128i __c) |
|
_mm_mask_permutevar_pd
__m128d _mm_mask_permutevar_pd(__m128d __W, __mmask8 __U, __m128d __A, __m128i __C) |
|
_mm_maskz_permutevar_pd
__m128d _mm_maskz_permutevar_pd(__mmask8 __U, __m128d __A, __m128i __C) |
|
_mm256_permute_pd
__m256d _mm256_permute_pd(__m256d A, const int C) |
|
_mm256_permutevar_pd
__m256d _mm256_permutevar_pd(__m256d __a, __m256i __c) |
|
_mm256_mask_permutevar_pd
__m256d _mm256_mask_permutevar_pd(__m256d __W, __mmask8 __U, __m256d __A, __m256i __C) |
|
_mm256_maskz_permutevar_pd
__m256d _mm256_maskz_permutevar_pd(__mmask8 __U, __m256d __A, __m256i __C) |
|
_mm512_permutevar_pd
__m512d _mm512_permutevar_pd(__m512d __A, __m512i __C) |
|
_mm512_mask_permutevar_pd
__m512d _mm512_mask_permutevar_pd(__m512d __W, __mmask8 __U, __m512d __A, __m512i __C) |
|
_mm512_maskz_permutevar_pd
__m512d _mm512_maskz_permutevar_pd(__mmask8 __U, __m512d __A, __m512i __C) |
|
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
More AVX instructions
- VPAND
- VPANDN
- VPAVGB
- VPAVGW
- VPBLENDVB
- VPBLENDW
- VPCLMULQDQ
- VPCMPEQB
- VPCMPEQD
- VPCMPEQQ
- VPCMPEQW
- VPCMPESTRI
- VPCMPESTRM
- VPCMPGTB
- VPCMPGTD
- VPCMPGTQ
- VPCMPGTW
- VPCMPISTRI
- VPCMPISTRM
- VPERM2F128
- VPERMILPS
- VPEXTRB
- VPEXTRD
- VPEXTRQ
- VPEXTRW
- VPHADDD
- VPHADDSW
- VPHADDW
- VPHMINPOSUW
- VPHSUBD
- VPHSUBSW
- VPHSUBW
- VPINSRB
- VPINSRD
- VPINSRQ
- VPINSRW
- VPMADDUBSW
- VPMADDWD
- VPMAXSB
- VPMAXSD
More AVX10.1 instructions
- VPCMPUW
- VPCMPW
- VPCOMPRESSB
- VPCOMPRESSD
- VPCOMPRESSQ
- VPCOMPRESSW
- VPCONFLICTD
- VPCONFLICTQ
- VPDPBUSD
- VPDPBUSDS
- VPDPWSSD
- VPDPWSSDS
- VPERMB
- VPERMD
- VPERMI2B
- VPERMI2D
- VPERMI2PD
- VPERMI2PS
- VPERMI2Q
- VPERMI2W
- VPERMILPS
- VPERMPD
- VPERMPS
- VPERMQ
- VPERMT2B
- VPERMT2D
- VPERMT2PD
- VPERMT2PS
- VPERMT2Q
- VPERMT2W
- VPERMW
- VPEXPANDB
- VPEXPANDD
- VPEXPANDQ
- VPEXPANDW
- VPEXTRB
- VPEXTRD
- VPEXTRQ
- VPEXTRW
- VPGATHERDD
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - Clang's x86 intrinsic headers, LLVM 23.1.2 (commit
85ac56026243): the intrinsics, their signatures and doc comments, and the Clang of that release, which compiled each of them. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2C, page 5-511 (VPERMILPD)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- Intel Advanced Vector Extensions 10.2 Architecture Specification, revision 7.0 (361050-007, April 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The intrinsics and their signatures come from Clang and the timings from LLVM's scheduling models, both part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.