Repository: rust
Issue: fragile codegen for autovectorized code (x86_64)
Labels: I-slow,A-codegen,C-bug

Using ```rustc --crate-type=lib  -C opt-level=3 -C target-cpu=skylake --emit asm lib.rs``` I tried this code:

```rust
pub fn count_match_good(cs: &[u8], gs: &[u8]) -> usize {
    let cs = &cs[..32];
    let gs = &gs[..32];
    cs.iter().zip(gs.iter())
        .filter(|(&c, &g)| (c == b'C') & (g == b'G'))
        .count()
}

pub fn count_match_bad(xs: &[u8]) -> usize {
    let cs = &xs[..32];
    let gs = &xs[1..][..32];
    cs.iter().zip(gs.iter())
        .filter(|(&c, &g)| (c == b'C') & (g == b'G'))
        .count()
}
```

I expected both functions to generate similar assembler: two vector comparisons, one vector and, and a popcnt (and a few bounds checks). What I got was a bit different.

```count_match_good``` actually generated the code I was expecting:

```asm
.LCPI0_0:
	.zero	32,67
.LCPI0_1:
	.zero	32,71
	.section	.text._ZN3lib16count_match_good17haddcacd7c4588d66E,"ax",@progbits
	.globl	_ZN3lib16count_match_good17haddcacd7c4588d66E
	.p2align	4, 0x90
	.type	_ZN3lib16count_match_good17haddcacd7c4588d66E,@function
_ZN3lib16count_match_good17haddcacd7c4588d66E:
	.cfi_startproc
	pushq	%rax
	.cfi_def_cfa_offset 16
	cmpq	$31, %rsi
	jbe	.LBB0_3
	cmpq	$32, %rcx
	jb	.LBB0_2
	vmovdqu	(%rdi), %ymm0
	vpcmpeqb	.LCPI0_0(%rip), %ymm0, %ymm0
	vmovdqu	(%rdx), %ymm1
	vpcmpeqb	.LCPI0_1(%rip), %ymm1, %ymm1
	vpand	%ymm1, %ymm0, %ymm0
	vpmovmskb	%ymm0, %eax
	popcntl	%eax, %eax
	popq	%rcx
	.cfi_def_cfa_offset 8
	vzeroupper
	retq
.LBB0_3:
	.cfi_def_cfa_offset 16
	leaq	.L__unnamed_1(%rip), %rdx
	movl	$32, %edi
	callq	*_ZN4core5slice5index24slice_end_index_len_fail17h954ac87ccda54c62E@GOTPCREL(%rip)
	ud2
.LBB0_2:
	leaq	.L__unnamed_2(%rip), %rdx
	movl	$32, %edi
	movq	%rcx, %rsi
	callq	*_ZN4core5slice5index24slice_end_index_len_fail17h954ac87ccda54c62E@GOTPCREL(%rip)
	ud2
.Lfunc_end0:
	.size	_ZN3lib16count_match_good17haddcacd7c4588d66E, .Lfunc_end0-_ZN3lib16count_match_good17haddcacd7c4588d66E
	.cfi_endproc
```

But ```count_match_bad``` was quite a bit different:

```asm
	.p2align	4
.LCPI1_0:
	.byte	0
	.byte	1
	.byte	2
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
.LCPI1_4:
	.byte	1
	.byte	0
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.section	.rodata.cst32,"aM",@progbits,32
	.p2align	5
.LCPI1_1:
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	0
	.byte	0
	.byte	0
	.byte	0
	.zero	1
	.zero	1
	.zero	1
	.zero	1
	.zero	1
	.zero	1
	.zero	1
.LCPI1_2:
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	255
	.byte	0
	.byte	0
	.byte	0
	.byte	0
	.byte	0
	.byte	0
	.byte	0
.LCPI1_3:
	.byte	71
	.byte	71
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
	.byte	67
.LCPI1_5:
	.byte	67
	.byte	67
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.byte	71
	.section	.text._ZN3lib15count_match_bad17h34fbcdcf3635493dE,"ax",@progbits
	.globl	_ZN3lib15count_match_bad17h34fbcdcf3635493dE
	.p2align	4, 0x90
	.type	_ZN3lib15count_match_bad17h34fbcdcf3635493dE,@function
_ZN3lib15count_match_bad17h34fbcdcf3635493dE:
	.cfi_startproc
	pushq	%rax
	.cfi_def_cfa_offset 16
	cmpq	$31, %rsi
	jbe	.LBB1_1
	decq	%rsi
	cmpq	$32, %rsi
	jb	.LBB1_5
	vmovdqu	3(%rdi), %xmm0
	movzwl	(%rdi), %eax
	vmovd	%eax, %xmm1
	movzbl	2(%rdi), %eax
	vpinsrb	$0, %eax, %xmm1, %xmm2
	vpinsrb	$2, %eax, %xmm2, %xmm2
	vpshufb	.LCPI1_0(%rip), %xmm2, %xmm2
	vpslldq	$3, %xmm0, %xmm3
	vpsrldq	$13, %xmm0, %xmm4
	movzbl	19(%rdi), %eax
	vpinsrb	$3, %eax, %xmm4, %xmm4
	movzbl	20(%rdi), %ecx
	vpinsrb	$4, %ecx, %xmm4, %xmm4
	vpor	%xmm2, %xmm3, %xmm2
	vinserti128	$1, %xmm4, %ymm2, %ymm2
	vmovd	21(%rdi), %xmm3
	vpbroadcastd	%xmm3, %ymm3
	vpslldq	$5, %xmm3, %xmm4
	vinserti128	$1, %xmm4, %ymm0, %ymm4
	vmovdqa	.LCPI1_1(%rip), %ymm5
	vpblendvb	%ymm5, %ymm2, %ymm4, %ymm2
	vmovq	25(%rdi), %xmm4
	vpbroadcastq	%xmm4, %ymm4
	vpslldq	$9, %xmm4, %xmm5
	vinserti128	$1, %xmm5, %ymm0, %ymm5
	vmovdqa	.LCPI1_2(%rip), %ymm6
	vpblendvb	%ymm6, %ymm2, %ymm5, %ymm2
	vpcmpeqb	.LCPI1_3(%rip), %ymm2, %ymm2
	vpslldq	$2, %xmm0, %xmm5
	vpshufb	.LCPI1_4(%rip), %xmm1, %xmm1
	vpor	%xmm1, %xmm5, %xmm1
	vpsrldq	$14, %xmm0, %xmm0
	vpinsrb	$2, %eax, %xmm0, %xmm0
	vpinsrb	$3, %ecx, %xmm0, %xmm0
	vinserti128	$1, %xmm0, %ymm1, %ymm0
	vpblendd	$32, %ymm3, %ymm0, %ymm0
	vpblendd	$192, %ymm4, %ymm0, %ymm0
	vpcmpeqb	.LCPI1_5(%rip), %ymm0, %ymm0
	vpand	%ymm0, %ymm2, %ymm0
	vpmovmskb	%ymm0, %eax
	popcntl	%eax, %eax
	popq	%rcx
	.cfi_def_cfa_offset 8
	vzeroupper
	retq
.LBB1_1:
	.cfi_def_cfa_offset 16
	leaq	.L__unnamed_3(%rip), %rdx
	jmp	.LBB1_2
.LBB1_5:
	leaq	.L__unnamed_4(%rip), %rdx
.LBB1_2:
	movl	$32, %edi
	callq	*_ZN4core5slice5index24slice_end_index_len_fail17h954ac87ccda54c62E@GOTPCREL(%rip)
	ud2
.Lfunc_end1:
	.size	_ZN3lib15count_match_bad17h34fbcdcf3635493dE, .Lfunc_end1-_ZN3lib15count_match_bad17h34fbcdcf3635493dE
	.cfi_endproc
```

This is a minimal reproducible example for my Real Problem (which is a loop over chunks of a ```&[u8]```, summing ```count_match```). Code corresponding to ```count_match_bad``` is notably slower than that corresponding to ```count_match_good```.

[Godbolt link](https://godbolt.org/z/W3qha884Y)

### Meta

`rustc --version --verbose`:
```
rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-unknown-linux-gnu
release: 1.69.0
LLVM version: 15.0.7
```

This also exists in nightly as of 
```
rustc 1.71.0-nightly (7f94b314c 2023-04-23)
binary: rustc
commit-hash: 7f94b314cead7059a71a265a8b64905ef2511796
commit-date: 2023-04-23
host: x86_64-unknown-linux-gnu
release: 1.71.0-nightly
LLVM version: 16.0.2
```