[PATCH 06/10] serpent: reduce CTR bulk counter carry handling to 16 bits

Jussi Kivilinna jussi.kivilinna at iki.fi
Fri Jul 24 20:50:13 CEST 2026


* cipher/serpent.c (serpent_setkey): Assign ctr16be_enc bulk op.
(_gcry_serpent_ctr_enc): Use cipher_block_add_be16.
* cipher/serpent-avx2-amd64.S (inc_le128): Remove.
(_gcry_serpent_avx2_ctr_enc): Add to low 16 counter bits only, drop
full-width overflow path.
* cipher/serpent-sse2-amd64.S (_gcry_serpent_sse2_ctr_enc): Add to low
16 counter bits only, drop full-width overflow path.
* cipher/serpent-avx512-x86.c (ctr_generate): Do 16-bit big-endian
counter addition, add carry slow path with vpaddw/vpshufb.
* cipher/serpent-armv7-neon.S (_gcry_serpent_neon_ctr_enc): Drop 64-bit
counter overflow path.
* cipher/Makefile.am (avx512f_cflags): Add -mavx512bw.
* configure.ac: Add -mavx512bw and _mm512_shuffle_epi8 to AVX512
intrinsics check.
--

Serpent CTR keystream generators did full 128-bit counter increment
with separate 64-bit overflow path. Under ctr16be_enc contract generic
ctr code splits work at low 16-bit overflow, so bulk function adds only
to low 16 counter bits. Drop overflow paths, use 16-bit stepping.

AVX512 slow path now does 16-bit vector addition and byte shuffle
(vpaddw, vpshufb), which need AVX512BW. Add -mavx512bw to AVX512
intrinsics build flags and probe _mm512_shuffle_epi8 in configure.

Moves serpent off transitional ctr_enc alias.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/Makefile.am          |   2 +-
 cipher/serpent-armv7-neon.S |  39 -------------
 cipher/serpent-avx2-amd64.S |  71 +++++-------------------
 cipher/serpent-avx512-x86.c | 108 ++++++++++++++++--------------------
 cipher/serpent-sse2-amd64.S |  67 +++++-----------------
 cipher/serpent.c            |   4 +-
 configure.ac                |   3 +-
 7 files changed, 80 insertions(+), 214 deletions(-)

diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 8f54ea47..021a7ab6 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -357,7 +357,7 @@ rijndael-vp-aarch64.lo: $(srcdir)/rijndael-vp-aarch64.c Makefile
 	`echo $(LTCOMPILE) $(aarch64_simd_cflags) -c $< | $(instrumentation_munging) `
 
 if ENABLE_X86_AVX512_INTRINSICS_EXTRA_CFLAGS
-avx512f_cflags = -mavx512f
+avx512f_cflags = -mavx512f -mavx512bw
 else
 avx512f_cflags =
 endif
diff --git a/cipher/serpent-armv7-neon.S b/cipher/serpent-armv7-neon.S
index 4179ba2c..c8b9660b 100644
--- a/cipher/serpent-armv7-neon.S
+++ b/cipher/serpent-armv7-neon.S
@@ -702,10 +702,6 @@ _gcry_serpent_neon_ctr_enc:
 	vmov RB3d0, RT0d0;
 	vmov RT2d0, RT0d0;
 
-	/* check need for handling 64-bit overflow and carry */
-	beq .Ldo_ctr_carry;
-
-.Lctr_carry_done:
 	/* le => be */
 	vrev64.u8 RA1, RA1;
 	vrev64.u8 RA2, RA2;
@@ -757,41 +753,6 @@ _gcry_serpent_neon_ctr_enc:
 	veor RB3, RB3;
 
 	pop {r4,pc};
-
-.Ldo_ctr_carry:
-	cmp r4, #-8;
-	blo .Lctr_carry_done;
-	beq .Lcarry_RT2;
-
-	cmp r4, #-6;
-	blo .Lcarry_RB3;
-	beq .Lcarry_RB2;
-
-	cmp r4, #-4;
-	blo .Lcarry_RB1;
-	beq .Lcarry_RB0;
-
-	cmp r4, #-2;
-	blo .Lcarry_RA3;
-	beq .Lcarry_RA2;
-
-	vsub.u64 RA1d0, RT1d0;
-.Lcarry_RA2:
-	vsub.u64 RA2d0, RT1d0;
-.Lcarry_RA3:
-	vsub.u64 RA3d0, RT1d0;
-.Lcarry_RB0:
-	vsub.u64 RB0d0, RT1d0;
-.Lcarry_RB1:
-	vsub.u64 RB1d0, RT1d0;
-.Lcarry_RB2:
-	vsub.u64 RB2d0, RT1d0;
-.Lcarry_RB3:
-	vsub.u64 RB3d0, RT1d0;
-.Lcarry_RT2:
-	vsub.u64 RT2d0, RT1d0;
-
-	b .Lctr_carry_done;
 .size _gcry_serpent_neon_ctr_enc,.-_gcry_serpent_neon_ctr_enc;
 
 .align 3
diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S
index 7aba235f..a419eb29 100644
--- a/cipher/serpent-avx2-amd64.S
+++ b/cipher/serpent-avx2-amd64.S
@@ -633,12 +633,6 @@ _gcry_serpent_avx2_blk16:
 	CFI_ENDPROC();
 ELF(.size _gcry_serpent_avx2_blk16,.-_gcry_serpent_avx2_blk16;)
 
-#define inc_le128(x, minus_one, tmp) \
-	vpcmpeqq minus_one, x, tmp; \
-	vpsubq minus_one, x, x; \
-	vpslldq $8, tmp, tmp; \
-	vpsubq tmp, x, x;
-
 .align 16
 .globl _gcry_serpent_avx2_ctr_enc
 ELF(.type   _gcry_serpent_avx2_ctr_enc, at function;)
@@ -651,79 +645,40 @@ _gcry_serpent_avx2_ctr_enc:
 	 */
 	CFI_STARTPROC();
 
-	movq 8(%rcx), %rax;
-	bswapq %rax;
-
 	vzeroupper;
 
 	vbroadcasti128 .Lbswap128_mask rRIP, RTMP3;
 	vpcmpeqd RNOT, RNOT, RNOT;
-	vpsrldq $8, RNOT, RNOT;   /* ab: -1:0 ; cd: -1:0 */
-	vpaddq RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
+	vpsrldq $14, RNOT, RNOT;   /* ab: -1:0 ; cd: -1:0 */
+	vpaddw RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
 
 	/* load IV and byteswap */
 	vmovdqu (%rcx), RTMP4x;
 	vpshufb RTMP3x, RTMP4x, RTMP4x;
 	vmovdqa RTMP4x, RTMP0x;
-	inc_le128(RTMP4x, RNOTx, RTMP1x);
+	vpsubw RNOTx, RTMP4x, RTMP4x;
 	vinserti128 $1, RTMP4x, RTMP0, RTMP0;
 	vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
 
-	/* check need for handling 64-bit overflow and carry */
-	cmpq $(0xffffffffffffffff - 16), %rax;
-	ja .Lhandle_ctr_carry;
-
 	/* construct IVs */
-	vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
 	vpshufb RTMP3, RTMP0, RA1;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
 	vpshufb RTMP3, RTMP0, RA2;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
 	vpshufb RTMP3, RTMP0, RA3;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
 	vpshufb RTMP3, RTMP0, RB0;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
 	vpshufb RTMP3, RTMP0, RB1;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
 	vpshufb RTMP3, RTMP0, RB2;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+	vpsubw RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
 	vpshufb RTMP3, RTMP0, RB3;
-	vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
-	vpshufb RTMP3x, RTMP0x, RTMP0x;
-
-	jmp .Lctr_carry_done;
 
-.Lhandle_ctr_carry:
-	/* construct IVs */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RA1; /* +3 ; +2 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RA2; /* +5 ; +4 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RA3; /* +7 ; +6 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RB0; /* +9 ; +8 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RB1; /* +11 ; +10 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RB2; /* +13 ; +12 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vpshufb RTMP3, RTMP0, RB3; /* +15 ; +14 */
-	inc_le128(RTMP0, RNOT, RTMP1);
-	vextracti128 $1, RTMP0, RTMP0x;
-	vpshufb RTMP3x, RTMP0x, RTMP0x; /* +16 */
-
-.align 4
-.Lctr_carry_done:
-	/* store new IV */
-	vmovdqu RTMP0x, (%rcx);
+	/* Update IV */
+	addb $16, 15(%rcx);
+	adcb $0, 14(%rcx);
 
 	call __serpent_enc_blk16;
 
diff --git a/cipher/serpent-avx512-x86.c b/cipher/serpent-avx512-x86.c
index 5b5c2483..dfbe2432 100644
--- a/cipher/serpent-avx512-x86.c
+++ b/cipher/serpent-avx512-x86.c
@@ -618,74 +618,62 @@ ctr_generate(unsigned char *ctr, __m512i vin[8])
 					       4LL << 56, 0,
 					       4LL << 56, 0,
 					       4LL << 56, 0);
-      const __m512i add4567 = _mm512_add_epi32(add0123, add4444);
-      const __m512i add8888 = _mm512_add_epi32(add4444, add4444);
+      const __m512i add4567 = _mm512_add_epi8(add0123, add4444);
+      const __m512i add8888 = _mm512_add_epi8(add4444, add4444);
 
       // Fast path without carry handling.
       __m512i vctr =
 	_mm512_broadcast_i32x4(_mm_loadu_si128((const void *)ctr));
 
-      cipher_block_add(ctr, 32, blocksize);
-      vin[0] = _mm512_add_epi32(vctr, add0123);
-      vin[1] = _mm512_add_epi32(vctr, add4567);
-      vin[2] = _mm512_add_epi32(vin[0], add8888);
-      vin[3] = _mm512_add_epi32(vin[1], add8888);
-      vin[4] = _mm512_add_epi32(vin[2], add8888);
-      vin[5] = _mm512_add_epi32(vin[3], add8888);
-      vin[6] = _mm512_add_epi32(vin[4], add8888);
-      vin[7] = _mm512_add_epi32(vin[5], add8888);
+      cipher_block_add_be16(ctr, 32, blocksize);
+      vin[0] = _mm512_add_epi8(vctr, add0123);
+      vin[1] = _mm512_add_epi8(vctr, add4567);
+      vin[2] = _mm512_add_epi8(vin[0], add8888);
+      vin[3] = _mm512_add_epi8(vin[1], add8888);
+      vin[4] = _mm512_add_epi8(vin[2], add8888);
+      vin[5] = _mm512_add_epi8(vin[3], add8888);
+      vin[6] = _mm512_add_epi8(vin[4], add8888);
+      vin[7] = _mm512_add_epi8(vin[5], add8888);
     }
   else
     {
-      // Slow path.
-      u32 blocks[4][blocksize / sizeof(u32)];
-
-      cipher_block_cpy(blocks[0], ctr, blocksize);
-      cipher_block_cpy(blocks[1], ctr, blocksize);
-      cipher_block_cpy(blocks[2], ctr, blocksize);
-      cipher_block_cpy(blocks[3], ctr, blocksize);
-      cipher_block_add(ctr, 32, blocksize);
-      cipher_block_add(blocks[1], 1, blocksize);
-      cipher_block_add(blocks[2], 2, blocksize);
-      cipher_block_add(blocks[3], 3, blocksize);
-      vin[0] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[1] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[2] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[3] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[4] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[5] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[6] = _mm512_loadu_epi32 (blocks);
-      cipher_block_add(blocks[0], 4, blocksize);
-      cipher_block_add(blocks[1], 4, blocksize);
-      cipher_block_add(blocks[2], 4, blocksize);
-      cipher_block_add(blocks[3], 4, blocksize);
-      vin[7] = _mm512_loadu_epi32 (blocks);
-
-      wipememory(blocks, sizeof(blocks));
+      const __m512i add0123 = _mm512_set_epi64(0, 3,
+					       0, 2,
+					       0, 1,
+					       0, 0);
+      const __m512i add4444 = _mm512_set_epi64(0, 4,
+					       0, 4,
+					       0, 4,
+					       0, 4);
+      const __m512i add4567 = _mm512_add_epi16(add0123, add4444);
+      const __m512i add8888 = _mm512_add_epi16(add4444, add4444);
+      static const unsigned char bswap_mask[16] __attribute__ ((aligned (16))) =
+	{ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+      const __m512i vbswap =
+	_mm512_broadcast_i32x4(_mm_loadu_si128((const void *)bswap_mask));
+
+      // Slow path with 16-bit carry.
+      __m512i vctr =
+	_mm512_broadcast_i32x4(_mm_loadu_si128((const void *)ctr));
+
+      cipher_block_add_be16(ctr, 32, blocksize);
+      vctr = _mm512_shuffle_epi8(vctr, vbswap);
+      vin[0] = _mm512_add_epi16(vctr, add0123);
+      vin[1] = _mm512_add_epi16(vctr, add4567);
+      vin[2] = _mm512_add_epi16(vin[0], add8888);
+      vin[3] = _mm512_add_epi16(vin[1], add8888);
+      vin[4] = _mm512_add_epi16(vin[2], add8888);
+      vin[5] = _mm512_add_epi16(vin[3], add8888);
+      vin[6] = _mm512_add_epi16(vin[4], add8888);
+      vin[7] = _mm512_add_epi16(vin[5], add8888);
+      vin[0] = _mm512_shuffle_epi8(vin[0], vbswap);
+      vin[1] = _mm512_shuffle_epi8(vin[1], vbswap);
+      vin[2] = _mm512_shuffle_epi8(vin[2], vbswap);
+      vin[3] = _mm512_shuffle_epi8(vin[3], vbswap);
+      vin[4] = _mm512_shuffle_epi8(vin[4], vbswap);
+      vin[5] = _mm512_shuffle_epi8(vin[5], vbswap);
+      vin[6] = _mm512_shuffle_epi8(vin[6], vbswap);
+      vin[7] = _mm512_shuffle_epi8(vin[7], vbswap);
     }
 }
 
diff --git a/cipher/serpent-sse2-amd64.S b/cipher/serpent-sse2-amd64.S
index 885c2bf1..93912935 100644
--- a/cipher/serpent-sse2-amd64.S
+++ b/cipher/serpent-sse2-amd64.S
@@ -688,68 +688,27 @@ _gcry_serpent_sse2_ctr_enc:
 	pbswap(RTMP0, RTMP1); /* be => le */
 
 	pcmpeqd RNOT, RNOT;
-	psrldq $8, RNOT; /* low: -1, high: 0 */
+	psrldq $14, RNOT; /* low: -1, high: 0 */
 	movdqa RNOT, RTMP2;
-	paddq RTMP2, RTMP2; /* low: -2, high: 0 */
+	paddw RTMP2, RTMP2; /* low: -2, high: 0 */
 
 	/* construct IVs */
 	movdqa RTMP0, RTMP1;
-	psubq RNOT, RTMP0; /* +1 */
+	psubw RNOT, RTMP0; /* +1 */
 	movdqa RTMP0, RA1;
-	psubq RTMP2, RTMP1; /* +2 */
+	psubw RTMP2, RTMP1; /* +2 */
 	movdqa RTMP1, RA2;
-	psubq RTMP2, RTMP0; /* +3 */
+	psubw RTMP2, RTMP0; /* +3 */
 	movdqa RTMP0, RA3;
-	psubq RTMP2, RTMP1; /* +4 */
+	psubw RTMP2, RTMP1; /* +4 */
 	movdqa RTMP1, RB0;
-	psubq RTMP2, RTMP0; /* +5 */
+	psubw RTMP2, RTMP0; /* +5 */
 	movdqa RTMP0, RB1;
-	psubq RTMP2, RTMP1; /* +6 */
+	psubw RTMP2, RTMP1; /* +6 */
 	movdqa RTMP1, RB2;
-	psubq RTMP2, RTMP0; /* +7 */
+	psubw RTMP2, RTMP0; /* +7 */
 	movdqa RTMP0, RB3;
-	psubq RTMP2, RTMP1; /* +8 */
-
-	/* check need for handling 64-bit overflow and carry */
-	cmpl $0xffffffff, 8(%rcx);
-	jne .Lno_ctr_carry;
-
-	movl 12(%rcx), %eax;
-	bswapl %eax;
-	cmpl $-8, %eax;
-	jb .Lno_ctr_carry;
-	pslldq $8, RNOT; /* low: 0, high: -1 */
-	je .Lcarry_RTMP0;
-
-	cmpl $-6, %eax;
-	jb .Lcarry_RB3;
-	je .Lcarry_RB2;
-
-	cmpl $-4, %eax;
-	jb .Lcarry_RB1;
-	je .Lcarry_RB0;
-
-	cmpl $-2, %eax;
-	jb .Lcarry_RA3;
-	je .Lcarry_RA2;
-
-	psubq RNOT, RA1;
-.Lcarry_RA2:
-	psubq RNOT, RA2;
-.Lcarry_RA3:
-	psubq RNOT, RA3;
-.Lcarry_RB0:
-	psubq RNOT, RB0;
-.Lcarry_RB1:
-	psubq RNOT, RB1;
-.Lcarry_RB2:
-	psubq RNOT, RB2;
-.Lcarry_RB3:
-	psubq RNOT, RB3;
-.Lcarry_RTMP0:
-	psubq RNOT, RTMP1;
-
-.Lno_ctr_carry:
+
 	/* le => be */
 	pbswap(RA1, RTMP0);
 	pbswap(RA2, RTMP0);
@@ -759,8 +718,10 @@ _gcry_serpent_sse2_ctr_enc:
 	pbswap(RB2, RTMP0);
 	pbswap(RB3, RTMP0);
 	pbswap(RTMP1, RTMP0);
-	/* store new IV */
-	movdqu RTMP1, (%rcx);
+
+	/* Update IV */
+	addb $8, 15(%rcx);
+	adcb $0, 14(%rcx);
 
 	call __serpent_enc_blk8;
 
diff --git a/cipher/serpent.c b/cipher/serpent.c
index 72a2287d..37e0c63a 100644
--- a/cipher/serpent.c
+++ b/cipher/serpent.c
@@ -854,7 +854,7 @@ serpent_setkey (void *ctx,
   memset (bulk_ops, 0, sizeof(*bulk_ops));
   bulk_ops->cbc_dec = _gcry_serpent_cbc_dec;
   bulk_ops->cfb_dec = _gcry_serpent_cfb_dec;
-  bulk_ops->ctr_enc = _gcry_serpent_ctr_enc;
+  bulk_ops->ctr16be_enc = _gcry_serpent_ctr_enc;
   bulk_ops->ocb_crypt = _gcry_serpent_ocb_crypt;
   bulk_ops->ocb_auth = _gcry_serpent_ocb_auth;
   bulk_ops->xts_crypt = _gcry_serpent_xts_crypt;
@@ -1126,7 +1126,7 @@ _gcry_serpent_ctr_enc(void *context, unsigned char *ctr,
       outbuf += sizeof(serpent_block_t);
       inbuf  += sizeof(serpent_block_t);
       /* Increment the counter.  */
-      cipher_block_add(ctr, 1, sizeof(serpent_block_t));
+      cipher_block_add_be16(ctr, 1, sizeof(serpent_block_t));
     }
 
   wipememory(tmpbuf, sizeof(tmpbuf));
diff --git a/configure.ac b/configure.ac
index 604f063e..631ed81e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1834,7 +1834,7 @@ fi
 # Check whether compiler supports x86/AVX512 intrinsics
 #
 _gcc_cflags_save=$CFLAGS
-CFLAGS="$CFLAGS -mavx512f"
+CFLAGS="$CFLAGS -mavx512f -mavx512bw"
 
 AC_CACHE_CHECK([whether compiler supports x86/AVX512 intrinsics],
       [gcry_cv_cc_x86_avx512_intrinsics],
@@ -1851,6 +1851,7 @@ AC_CACHE_CHECK([whether compiler supports x86/AVX512 intrinsics],
             x = _mm512_loadu_epi32 (in); /* check the GCC bug 90980. */
 	    x = _mm512_maskz_loadu_epi32(_cvtu32_mask16(0xfff0), in)
 		  ^ _mm512_castsi128_si512(y);
+	    x = _mm512_shuffle_epi8(x, x);
 	    asm volatile ("vinserti32x4 \$3, %0, %%zmm6, %%zmm6;\n\t"
 			  "vpxord %%zmm6, %%zmm6, %%zmm6"
 			  ::"x"(y),"r"(in):"memory","xmm6");
-- 
2.53.0




More information about the Gcrypt-devel mailing list