Skip to content

Commit 381bf9b

Browse files
authored
Merge pull request #55 from saethlin/main
2 parents 868b04c + 98f95e2 commit 381bf9b

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

.github/actions/test/action.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ inputs:
1616
required: false
1717
type: string
1818

19+
rustdocflags:
20+
default: ""
21+
required: false
22+
type: string
23+
1924
target:
2025
default: ""
2126
required: false
@@ -43,6 +48,7 @@ runs:
4348
uses: actions-rs/cargo@v1
4449
env:
4550
RUSTFLAGS: "${{ env.RUSTFLAGS }} ${{ inputs.rustflags }}"
51+
RUSTDOCFLAGS: "${{ env.RUSTDOCFLAGS }} ${{ inputs.rustdocflags }}"
4652
with:
4753
command: test
4854
args: >-

.github/workflows/ci.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,17 @@ jobs:
6666
with:
6767
rustflags: "-C target-feature=${{ matrix.target_feature }}"
6868
target: "${{ matrix.target }}"
69+
70+
sanitizers:
71+
runs-on: ubuntu-latest
72+
73+
steps:
74+
- name: Check out code
75+
uses: actions/checkout@v3
76+
77+
- name: Run tests
78+
uses: ./.github/actions/test
79+
with:
80+
toolchain: nightly
81+
rustflags: "-Z sanitizer=address"
82+
rustdocflags: "-Z sanitizer=address"

src/simd.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ trait PackedCompareControl {
2828
fn needle_len(&self) -> i32;
2929
}
3030

31+
#[inline]
32+
#[target_feature(enable = "sse4.2")]
33+
unsafe fn find_small<C, const CONTROL_BYTE: i32>(packed: PackedCompare<C, CONTROL_BYTE>, haystack: &[u8]) -> Option<usize>
34+
where
35+
C: PackedCompareControl,
36+
{
37+
let mut tail = [0u8; 16];
38+
core::ptr::copy_nonoverlapping(haystack.as_ptr(), tail.as_mut_ptr(), haystack.len());
39+
let haystack = &tail[..haystack.len()];
40+
debug_assert!(haystack.len() < ::std::i32::MAX as usize);
41+
packed.cmpestri(haystack.as_ptr(), haystack.len() as i32)
42+
}
43+
3144
/// The PCMPxSTRx instructions always read 16 bytes worth of
3245
/// data. Although the instructions handle unaligned memory access
3346
/// just fine, they might attempt to read off the end of a page
@@ -49,6 +62,10 @@ where
4962
return None;
5063
}
5164

65+
if haystack.len() < 16 {
66+
return find_small(packed, haystack);
67+
}
68+
5269
let mut offset = 0;
5370

5471
if let Some(misaligned) = Misalignment::new(haystack) {
@@ -89,12 +106,7 @@ where
89106
return None;
90107
}
91108

92-
// By this point, the haystack's length must be less than 16
93-
// bytes. It is thus reasonable to truncate it into an i32.
94-
debug_assert!(haystack.len() < ::std::i32::MAX as usize);
95-
packed
96-
.cmpestri(haystack.as_ptr(), haystack.len() as i32)
97-
.map(|loc| offset + loc)
109+
find_small(packed, haystack).map(|loc| loc + offset)
98110
}
99111

100112
struct PackedCompare<T, const CONTROL_BYTE: i32>(T);

0 commit comments

Comments
 (0)