Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed translating declaration due to error: Unsupported vector default initializer: Int x 4, kind: Some(Function { is_extern: true, is_inline: true, is_implicit: false, typ: CTypeId(10934), name: "MyGetIP_comp", parameters: [CDeclId(23294)], body: Some(CStmtId(23293)) })' #44

Closed
d33tah opened this issue Mar 28, 2019 · 10 comments
Assignees
Labels
bug Something isn't working

Comments

@d33tah
Copy link

d33tah commented Mar 28, 2019

I used the following input:

a.zip

Here's the result:

[19:27:38]  d33tah@d33tah-laptop:/tmp(101) > /home/d33tah/workspace/src/c2rust/target/release/c2rust transpile compile_commands.json --fail-on-error
Transpiling a.c
thread 'main' panicked at 'Failed translating declaration due to error: Unsupported vector default initializer: Int x 4, kind: Some(Function { is_extern: true, is_inline: true, is_implicit: false, typ: CTypeId(10934), name: "MyGetIP_comp", parameters: [CDeclId(23294)], body: Some(CStmtId(23293)) })', c2rust-transpile/src/translator/mod.rs:305:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Are there any plans to add support for this feature?

@TheDan64
Copy link
Contributor

It seems like the call to _mm_extract_epi32 is the issue here; but what's weird about it is that it seems to call into code for zero initializing an undefined variable. In any case, I expect that it should be fixable.

Behind that one, though, is an even stranger error: Subscript applied to non-pointer, kind: Some(Function { is_global: true, is_inline: true, is_implicit: false, is_extern: false, typ: CTypeId(10566), name: "MyGetIP_comp", parameters: [CDeclId(10568)], body: Some(CStmtId(10567)), attrs: {} })

and that also seems to be coming from the _mm_extract_epi32(prod, 0); call... Weird.

@TheDan64 TheDan64 self-assigned this Mar 28, 2019
@TheDan64 TheDan64 added the bug Something isn't working label Mar 28, 2019
@TheDan64
Copy link
Contributor

Also, are you using LLVM 6 or 7? A bunch of SIMD functions got moved to builtins in 7

@d33tah
Copy link
Author

d33tah commented Mar 28, 2019

@TheDan64

[21:47:45]  d33tah@d33tah-laptop:/home/d33tah(0) > dpkg -l | rg -i llvm
ii  libllvm6.0:amd64                                            1:6.0-1ubuntu2                                              amd64        Modular compiler and toolchain technologies, runtime library
ri  libllvm6.0:i386                                             1:6.0-1ubuntu2                                              i386         Modular compiler and toolchain technologies, runtime library
ii  libllvm7:amd64                                              1:7-3~ubuntu0.18.04.1                                       amd64        Modular compiler and toolchain technologies, runtime library
ii  libllvm7:i386                                               1:7-3~ubuntu0.18.04.1                                       i386         Modular compiler and toolchain technologies, runtime library
ii  libomp-dev                                                  5.0.1-1                                                     amd64        LLVM OpenMP runtime - dev package
ii  libomp5:amd64                                               5.0.1-1                                                     amd64        LLVM OpenMP runtime
ii  llvm-6.0                                                    1:6.0-1ubuntu2                                              amd64        Modular compiler and toolchain technologies
ii  llvm-6.0-dev                                                1:6.0-1ubuntu2                                              amd64        Modular compiler and toolchain technologies, libraries and headers
ii  llvm-6.0-runtime                                            1:6.0-1ubuntu2                                              amd64        Modular compiler and toolchain technologies, IR interpreter
ii  mono-llvm-support                                           5.16.1.0-0xamarin1+ubuntu1804b1                             amd64        Mono runtime - SGen
ii  mono-llvm-tools                                             3.6.0+mono201805011452-0xamarin1+ubuntu1804b1               amd64        opt and llc for Mono llvm mode

@TheDan64
Copy link
Contributor

Thanks, the problem seems to be the definition of _mm_extract_epi32 is not a function but an awkward macro in LLVM 6 & 7:

#define _mm_extract_epi32(X, N) (__extension__                         \
                                 ({ __v4si __a = (__v4si)(__m128i)(X); \
                                    (int)__a[(N) & 3];}))

The problem is twofold:

  1. They instantiate a variable of a builtin type __v4si. This might be mockable with __m128i since they should be equivalent
  2. They index the builtin type, which, I don't believe rust supports on their simd types like __m128i.

I'm going to see if it's possible for us to correctly translate this as is however it will nonetheless not be very pretty and wont be able to use the rust function _mm_extract_epi32

OTOH, this will be much easier and nicer to support in LLVM 8 one day as it's just a builtin:

#define _mm_extract_epi32(X, N) \
   (int)__builtin_ia32_vec_ext_v4si((__v4si)(__m128i)(X), (int)(N))

And that's easy enough to translate to the rust function.

I'm not sure if this is helpful but a correct translation of MyGetIP_comp would look like this:

#[cfg ( target_arch = "x86" )]
pub use std::arch::x86::{__m128i, _mm_sub_epi8, _mm_cmpeq_epi8,
                         _mm_loadu_si128, _mm_set_epi8, _mm_set1_epi8,
                         _mm_setzero_si128, _mm_store_si128,
                         _mm_movemask_epi8, _mm_lddqu_si128, _mm_hadd_epi16,
                         _mm_maddubs_epi16, _mm_shuffle_epi8, _mm_extract_epi32};
#[cfg ( target_arch = "x86_64" )]
pub use std::arch::x86_64::{__m128i, _mm_sub_epi8, _mm_cmpeq_epi8,
                            _mm_loadu_si128, _mm_set_epi8, _mm_set1_epi8,
                            _mm_setzero_si128, _mm_store_si128,
                            _mm_movemask_epi8, _mm_lddqu_si128,
                            _mm_hadd_epi16, _mm_maddubs_epi16,
                            _mm_shuffle_epi8, _mm_extract_epi32};
#[inline]
unsafe extern "C" fn MyGetIP_comp(mut str: *const libc::c_char) -> UINT32 {
    //"192.167.1.3"
    let mut input: __m128i = _mm_lddqu_si128(str as *const __m128i);
    let mut zm: uint64_t =
        _mm_movemask_epi8(_mm_cmpeq_epi8(input, _mm_setzero_si128())) as
            uint64_t;
    zm ^= zm.wrapping_sub(1i32 as libc::c_ulong);
    input = _mm_sub_epi8(input, _mm_set1_epi8('0' as i32 as libc::c_char));
    //...X...X.X.XX...  (signs)
    let mut cmp: __m128i = input;
    //6792 - magic index
    let mut mask: uint64_t = _mm_movemask_epi8(cmp) as uint64_t;
    mask &= zm;
    let mut hashmask: uint64_t =
        perfecthash(mask as libc::c_uint) as uint64_t;
    //10 -1 -1 -1 8 -1 -1 -1 6 5 4 -1 2 1 0 -1
    let mut shuf: __m128i =
        *(TBL.as_ptr() as *const __m128i).offset(hashmask as isize);
    //3 0 0 0 | 1 0 0 0 | 7 6 1 0 | 2 9 1 0
    let mut arr: __m128i = _mm_shuffle_epi8(input, shuf);
    let mut coeffs: __m128i =
        _mm_set_epi8(0i32 as libc::c_char, 100i32 as libc::c_char,
                     10i32 as libc::c_char, 1i32 as libc::c_char,
                     0i32 as libc::c_char, 100i32 as libc::c_char,
                     10i32 as libc::c_char, 1i32 as libc::c_char,
                     0i32 as libc::c_char, 100i32 as libc::c_char,
                     10i32 as libc::c_char, 1i32 as libc::c_char,
                     0i32 as libc::c_char, 100i32 as libc::c_char,
                     10i32 as libc::c_char, 1i32 as libc::c_char);
    //3 0 | 1 0 | 67 100 | 92 100
    let mut prod: __m128i = _mm_maddubs_epi16(coeffs, arr);
    prod = _mm_hadd_epi16(prod, prod);
    let mut imm: __m128i =
        _mm_set_epi8(-1i32 as libc::c_char, -1i32 as libc::c_char,
                     -1i32 as libc::c_char, -1i32 as libc::c_char,
                     -1i32 as libc::c_char, -1i32 as libc::c_char,
                     -1i32 as libc::c_char, -1i32 as libc::c_char,
                     -1i32 as libc::c_char, -1i32 as libc::c_char,
                     -1i32 as libc::c_char, -1i32 as libc::c_char,
                     6i32 as libc::c_char, 4i32 as libc::c_char,
                     2i32 as libc::c_char, 0i32 as libc::c_char);
    prod = _mm_shuffle_epi8(prod, imm);
    return _mm_extract_epi32(prod, 0) as UINT32;
}

@d33tah
Copy link
Author

d33tah commented Mar 29, 2019

@TheDan64 awesome, thanks! I actually needed this translated code.

@TheDan64
Copy link
Contributor

No problem! Also it seems like _mm_extract_epi32 is a builtin as of clang 7, not 8. The builtin still needs to be supported on our end, but, translating with 7 would work cleanly that way

@TheDan64
Copy link
Contributor

TheDan64 commented Apr 2, 2019

I've added support for _mm_extract_epi32's builtin (and a bunch of others I found) upstream w/ Clang 7; so those changes should be available next time we do a repo sync here.

@thedataking
Copy link
Contributor

thedataking commented Apr 9, 2019

Closing since the repo is now synced. Feel free to reopen.

@d33tah
Copy link
Author

d33tah commented Apr 9, 2019

@TheDan64 what do you mean by not synced? What's the canonical repo URL? Perhaps it's worth mentioning in Github project description / README?

@thedataking
Copy link
Contributor

Sorry, we should have been more clear. For various reasons, we've had to do development in a non-public github repository that we'd occasionally sync with this one (which is indeed the canonical repository for this project). Going forward, we should be able to do most development in public here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants