# Julia equivalent of C compiler intrinsics?

**URL:** <https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278>\
**Category:** General Usage\
**Created:** [November 7, 2018, 9:47pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278 "2018-11-07T21:47:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [November 7, 2018, 9:47pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/1 "2018-11-07T21:47:44Z")

</div>

I just learned about @code\_native, and it’s really cool that you can see the assembly instructions for code easily.

So, C has “compiler intrinsics” that provide C-like functions that map to particular CPU instructions. Does Julia have an equivalent?

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [November 7, 2018, 10:24pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/2 "2018-11-07T22:24:38Z")

</div>

`llvmcall` with CPU intrinsics. It is a pain, though. For an example, see [https://discourse.julialang.org/t/compiling-to-branch-table/16599/9](https://discourse.julialang.org/t/compiling-to-branch-table/16599/9) and consider that the `sext` of vector comparison results is essential (this is what x86 does natively) while SIMD.jl uses `zext`. This is why the `pmovmskb`/ `_mm_movemask_epi8` composes well with `pcmpeqb` / `_mm_cmpeq_epi8`, and does not compose with `SIMD.jl` comparison.

The preferred way is to figure out the age old C idiom for whatever you want to do, because llvm was made for clang, and both clang and your processor’s instruction set were made for old C idioms. Hence this will often compile to something good.

The second preferred way is to hope that somebody has written a julia wrapper. Only afterwards one should look whether llvm exposes your intrinsic, under which crazy name and with what crazy calling convention.

Of course llvm only exposes the intrinsic if they have no idiom (in llvm IR!) that reliably compiles to whatever instruction you want, but good luck finding a documentation for that. I passionately hate the llvm docs for processor intrinsics. I often reverse the calling convention from the llvm unit tests; alternatively, compile from C to llvm IR with clang and reverse engineer that.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 7, 2018, 10:33pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/3 "2018-11-07T22:33:19Z")

</div>

Godbolt + `-emit-llvm` is pretty ok.

> **[Compiler Explorer - C++ (x86-64 clang 7.0.0)](https://godbolt.org/z/8eHDwj)**
>
> /\* ========================================================================
> 
> meow\_intrinsics.h
> (C) Copyright 2018 by Molly Rocket, Inc. (https://mollyrocket.com)
>    
> See https://mollyrocket.com/meowhash for details.
>    
> This is the...

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [November 8, 2018, 4:13pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/4 "2018-11-08T16:13:57Z")

</div>

Thanks! I imagine there probably isn’t a lot of demand for such a feature, and those who really need it can do as you suggest.

I wrote a cryptographic function (scrypt) for fun in C++ once and made heavy use of SIMD, explicit prefetching and minimizing cache pollution to increase its performance. It was cool to be able to manipulate the CPU that directly and simply. Too bad that isn’t easily achievable here.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [November 8, 2018, 7:01pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/5 "2018-11-08T19:01:10Z")

</div>

I think there would be a lot of demand for `immintrin.jl` that contains most of of `immintrin.h` (see [https://software.intel.com/sites/landingpage/IntrinsicsGuide/](https://software.intel.com/sites/landingpage/IntrinsicsGuide/)) with the same API.

It’s just that somebody needs to annotate everything (hopefully via a script), compile it with clang, generate the julia code (with `llvmcall`) and generate tests for everything (to see that behavior is correct; possibly checking that `code_native` matches the icc/gcc/clang variant), possibly fixing or documenting everything that goes wrong. Afaik nobody went to that effort yet.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 7:38pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/6 "2018-11-08T19:38:33Z")

</div>

Yeah, I actually started looking how something like that should look ([intrinsics.jl · GitHub](https://gist.github.com/KristofferC/e75b376cb2dd54fec39a049687518806))

What is annoying is that there is not a one to one correspondence with LLVM intrinsics and the intrinsics one write in C.

For example:

`_mm_xor_si128(A, B)` is in LLVM: `xor <2 x i64> %1, %0,`

`_mm_add_sd` is:

```julia
  %3 = extractelement <2 x double> %1, i32 0, !dbg !357
  %4 = extractelement <2 x double> %0, i32 0, !dbg !357
  %5 = fadd double %4, %3, !dbg !357
  %6 = insertelement <2 x double> %0, double %5, i32 0, !dbg !357

```

etc.

AFAIU, you basically need to write a mini-compiler for the intrinsics. Or maybe the intrinsic exists and clang just doesn’t emit it?

I found this file: [https://github.com/llvm-mirror/clang/blob/master/www/builtins.py](https://github.com/llvm-mirror/clang/blob/master/www/builtins.py) which perhaps are the ones that are “special cased” in LLVM.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 7:46pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/7 "2018-11-08T19:46:57Z")

</div>

Actually, it is possible just to use the intrinsic even for `_mm_add_sd` (it is just that clang doesnt use it).

```julia
const VE{N, T} = NTuple{N, VecElement{T}}

@generated function _mm_add_sd(a::VE{2,Float64}, b::VE{2, Float64})
    exp = """
    %3 = call <2 x double> @llvm.x86.sse2.add.sd(<2 x double> %0, <2 x double> %1)
    ret <2 x double> %3
    """
    return quote
            Base.llvmcall(
            ("""
            declare <2 x double> @llvm.x86.sse2.add.sd(<2 x double>, <2 x double>)
            """,
            $exp),
               VE{2,Float64},
               Tuple{VE{2,Float64}, VE{2, Float64}},
               a, b)
    end
end

```

```julia
julia> a = VE{2, Float64}((1.0,2.0))
(VecElement{Float64}(1.0), VecElement{Float64}(2.0))

julia> b = VE{2, Float64}((3.0,4.0))
(VecElement{Float64}(3.0), VecElement{Float64}(4.0))

julia> _mm_add_sd(a, b)
(VecElement{Float64}(4.0), VecElement{Float64}(2.0))

julia> @code_native _mm_add_sd(b, a)
        .section __TEXT,__ text,regular,pure_instructions
; Function _mm_add_sd {
; Location: REPL[3]:2
; Function macro expansion; {
; Location: REPL[3]:2
        vaddsd %xmm1, %xmm0, %xmm0
        retq
        nopw %cs:(%rax,%rax)
;}}

```

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [November 8, 2018, 7:48pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/8 "2018-11-08T19:48:12Z")

</div>

Yeah. My best guess would be to use clang to compile everything in `immintinsics.h` into functions, grab the llvm IR, and generate the surrounding `@inline __mm_foobar(arg1::Type1, arg2::Type2) = llvmcall(...)`. At the same time, we would need to automatically generate cheap tests for each function (maybe steal some projects unit tests), and also write the generated code\_native somewhere.

Then the stolen tests would check functionality and generated tests would check that the code\_native matches if we generate a `@cfunction`. Since we expect only 3-4 instructions (the one that the intrinsic corresponds to, plus maybe a handful of register moves and `ret` to conform to C-ABI) there should be almost no spurious difference.

So the main tasks is to use a convenient C and ascii-llvm-IR parser/preprocessor to do all the text processing, and to write a monumentally annoying build-script for this. And if something here does not work in the obvious way this is of course a world of pain.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 7:48pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/9 "2018-11-08T19:48:24Z")

</div>

There’s basically no point to use intrinsics for most (all) vector math operations.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 7:50pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/10 "2018-11-08T19:50:59Z")

</div>

Sure, (SIMD.jl works well for normal arithmetic). There is, however, value in having something that works similar to C-intrinsics in how you write it in Julia for consistency (and learning) and also for stuff like `aesdec` you need intrinsics AFAIU.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 7:54pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/11 "2018-11-08T19:54:03Z")

</div>

For things that is not normal arithmatic and cannot be expressed as one, sure. I’m just pointing out that most of the intrinsics you’ve tested so far are implemented as a icc compatibility layer in clang/gcc and I’m 99% sure the corresponding actual intrinsics are meant for the backend and doesn’t actually expose any more functions. You shouldn’t be looking specifically for llvm intrinsics since there’s no point using them (they only make the code non-portable and potentially harder for the compiler to optimize).

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 7:55pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/12 "2018-11-08T19:55:21Z")

</div>

For example,

```nohighlight
static __inline__ m256 __DEFAULT_FN_ATTRS
_mm256_mul_ps( __m256__ a, __m256__ b)
{
  return (__m256)((__v8sf)__a * (__v8sf)__b);
}

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 8:01pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/13 "2018-11-08T20:01:39Z")

</div>

> [@yuyichao](#):
>
> I’m just pointing out that most of the intrinsics you’ve tested so far

Sure, but like, those were just examples to experiment with calling intrinsics at all.

Anyway, my point is that to be able to port something like [https://github.com/cmuratori/meow\_hash/blob/5ceaf1476baeef38c16ab95cbb4e18f6df20b05d/meow\_intrinsics.h#L70-L100](https://github.com/cmuratori/meow_hash/blob/5ceaf1476baeef38c16ab95cbb4e18f6df20b05d/meow_intrinsics.h#L70-L100) it would be nice if there was something in Julia that made that convenient.

For fused operations I guess you also need to use intrinsics.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [November 8, 2018, 8:05pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/14 "2018-11-08T20:05:47Z")

</div>

> [@yuyichao](#):
>
> You shouldn’t be looking specifically for llvm intrinsics since there’s no point using them (they only make the code non-portable and potentially harder for the compiler to optimize).

Yes. The intrinsic set of llvm is designed for clang, such that all of `immintinsics.h` can be compiled, not such that they are conveniently usable for humans. So we should grab the clang output, inline it and hope that llvm does not destroy its good properties in later passes.

E.g. converting `<8 x i1> to i8` would be the obvious idiom, but is afaik not understood by llvm, needing the x86 intrinsic calls plus `sext to <8 x i8>` to get `pmovmskb`. This is a lot of work for humans, and just directly porting C code for the very innermost loop operations that uses `_mm_something` would be very convenient. And, as Kristoffer said, aes intrinsics in llvm are madness.

Of course, general vector math without fancy stuff, like e.g. chacha20 works without llvmcall.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 8:06pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/15 "2018-11-08T20:06:04Z")

</div>

> [@kristoffer.carlsson](#):
>
> it would be nice if there was something in Julia that made that convenient.

Yes? I’m not saying you can’t make “compatibility layers”. I’m saying that you shouldn’t be looking for LLVM intrinsics. Moreover, you shouldn’t be looking for backend intrinsics, since most of the operations are implemented as normal operations and the rest as platform independent intrinsics.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 8:09pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/16 "2018-11-08T20:09:02Z")

</div>

And if you really want to know how things should be implemented, you can just have a look at the clang implementation in the headers. it contains a minimum set of actual intrinsics that you need to find and call and many more operation you can just implement in normal julia or llvm code. The C implementation of `_mm_add_sd` I pasted above, for example, should be fairely straightforward to implement in julia. If it does not yield the same code, it’s a compiiler bug that should be fixed.

Edit: and finally for the list of actual C intrinsics you need, I believe the GCC doc is usually pretty good. Maybe clang has one but I have always been using the GCC one.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 8:11pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/17 "2018-11-08T20:11:51Z")

</div>

> [@yuyichao](#):
>
> Moreover, you shouldn’t be looking for backend intrinsics

If I want to call `_mm_aesdec_si128` I would right now see what LLVM outputs [Compiler Explorer](https://godbolt.org/z/qBQtmd) and then call that intrinsic `@llvm.x86.aesni.aesdec`.

What should I do instead?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 8:15pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/18 "2018-11-08T20:15:56Z")

</div>

> [@kristoffer.carlsson](#):
>
> What should I do instead?

Use it?

Just to be more clear, I’m replying to,

> [@kristoffer.carlsson](#):
>
> What is annoying is that there is not a one to one correspondence with LLVM intrinsics and the intrinsics one write in C.

and

> [@kristoffer.carlsson](#):
>
> Actually, it is possible just to use the intrinsic even for `_mm_add_sd` (it is just that clang doesnt use it).

I’m just saying that if there’s a way to do it in julia code, don’t look for intrinsics, and when there’s a way to do it with generic intrinsics, don’t look for backend specific intrinsics. This is the right way to do things and also give the compiler the best input for optimization. I’m not saying that you shouldn’t use any backend intrinsics or other intrinsics, just that they shouldn’t be what you specifically look for.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2018, 8:17pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/19 "2018-11-08T20:17:07Z")

</div>

Alright, so do I understand you correctly in that you recommend:

- Implement the possible operations using the normal LLVM vector operations (this is basically SIMD.jl).
- Provide a compatibility layer on top of these for the arithmetic instrinsics ([https://github.com/llvm-mirror/clang/blob/master/www/builtins.py](https://github.com/llvm-mirror/clang/blob/master/www/builtins.py)) which could simplify in porting code from C.
- For the rest that do not have a vector operations, just use the intrinsic.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 8, 2018, 8:18pm UTC](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278/20 "2018-11-08T20:18:21Z")

</div>

Yes. And use generic intrinsics as much as possible. The llvm langref, gcc intrinsics doc and the clang implementations in the headers are your friends.

[Next page](https://discourse.julialang.org/t/julia-equivalent-of-c-compiler-intrinsics/17278.md?page=2)
