How to insert vector type input parameter for function in C/C++ API?

I am working on AVX2 code generation by LLVM framework.

I want to generate LLVM-IR code for the following code by C/C++ API from LLVM framework. I am using LLVM3.8.

Basically, I want to generate TARGET (Refer to below) LLVM-IR code for SOURCE function by C/C++ API.

As you see below, the AVX2 data type is __m256i which is vector type. How can I indicate vector type (function return type, input parameters) for IRBuiler by C/C++ APIs?

I don’t see any example online and please let me know if anybody has examples.

#include “immintrin.h”
__m256i sum(__m256i a, __m256i b) {
return a+b;

michael@michael-Precision-Tower-3420:~/Year_2017/work_DEMO$ cat avx2_add2.ll
; ModuleID = ‘avx2_add2.c’
target datalayout = “e-m:w-i64:64-f80:128-n8:16:32:64-S128”
target triple = “x86_64-unknown-windows-cygnus”

; Function Attrs: nounwind
define <4 x i64> @sum(<4 x i64> %a, <4 x i64> %b) #0 {
%1 = alloca <4 x i64>, align 32
%2 = alloca <4 x i64>, align 32
store <4 x i64> %a, <4 x i64>* %1, align 32
store <4 x i64> %b, <4 x i64>* %2, align 32
%3 = load <4 x i64>, <4 x i64>* %1, align 32
%4 = load <4 x i64>, <4 x i64>* %2, align 32
%5 = add <4 x i64> %3, %4
ret <4 x i64> %5

attributes #0 = { nounwind “disable-tail-calls”=“false” “less-precise-fpmad”=“false” “no-frame-pointer-elim”=“false” “no-infs-fp-math”=“false” “no-nans-fp-math”=“false” “stack-protector-buffer-size”=“8” “target-features”=“+mmx,+sse,+sse2” “unsafe-fp-math”=“false” “use-soft-float”=“false” }

!llvm.ident = !{!0}

!0 = !{!“clang version 3.8.1 (tags/RELEASE_381/final)”}



To create a vector type you can call VectorType::get(, ) and pass the output of that to the Type argument when creating instructions. To get the scalar element type you can use the getTy methods in IRBuilder or the Type::getTy methods.

Thank you so much Craig!

I tried it. But still complaining. Here is the error message during compilation.

HowToUseJIT_SIMD_FuncProto.cpp:94:55: error: expected unqualified-id

LLVMContext Context;

std::unique_ptr Owner = make_unique(“test”, Context);
Module *M = Owner.get();

Function *Add1F =

//Type::getInt32Ty(Context), //This is working fine
//Type::getInt32Ty(Context), //This is working fine


Any idea?

Please let me know what is wrong in my code.



It should be VectorType::get(Type::getInt32Ty(Context),4). You need the word “get” after VectorType::

Fantastic! It’s working! Thank you so much Craig!!!

Hi Craig,

Thank you for your help!

As you know from my first mail , I want to generrate LLVM-IR code (TARGET) by C/C++ APIs for below SOURCE source code (AVX2 code).

I am using LLVM 3.8.x

I can’t find useful examples from online. So far, I just done following ‘Done: Part-1’ which gives me this,

= LLVM-IR code from ‘Done: Part-1’ =========================================

define i32 @add1(i32 %AnArg) {
%0 = add i32 1, %AnArg // Line 1: From C/C++ APIs below
ret i32 %0 // Line 2: From C/C++ APIs below


I am referencing attached implementation for my project.



HowToUseJIT.cpp (4.56 KB)

There are quite a few different ways to make constant vectors. You can create a splat of integer constants by using ConstantInt::get(, ) The scalar value can be an uint64_t or an APInt. Of if you have a Constant * you want to splat you can use ConstantVector::getSplat. If it’s not a splat, you can use ConstantDataVector::get which will take an array of uint8_t, uint16_t, uint32_t, or uin64_t and auto infer the width and element count. Or you can use ConstantVector::get which will take an array of individual Constant * that all have the same scalar type.

I don’t have any complete code for implementing a function. Most of my interaction with these APIs has been in converting intrinsics into native IR in lib/IR/AutoUpgrade.cpp and clang’s lib/CodeGen/CGBuiltin.cpp. I’m sure you’ll find every function I mentioned above used in one or both of those files.