Skip to content

Commit

Permalink
[LLVM] Support for newer versions of LLVM APIs
Browse files Browse the repository at this point in the history
This commit fixes deprications warnings and errors that
occur due to switch of LLVM to opaque pointers: recent versions
of LLVM instruction builder APIs require explicit type parameters
when doing `gep`s, `load`s, `gather`s.

Moreover, with recent change to LLVM `https://reviews.llvm.org/D106678`
MASSV SIMD functions have no `_P8` suffix by default. Tests were
adjusted to take that into account.

Note: tested with the LLVM version from `brew` (13).
  • Loading branch information
georgemitenkov authored and pramodk committed Mar 8, 2022
1 parent f721890 commit ff5430c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
44 changes: 30 additions & 14 deletions src/codegen/llvm/llvm_ir_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,14 @@ llvm::Value* IRBuilder::create_inbounds_gep(const std::string& var_name, llvm::V

// Since we index through the pointer, we need an extra 0 index in the indices list for GEP.
ValueVector indices{llvm::ConstantInt::get(get_i64_type(), 0), index};
return builder.CreateInBoundsGEP(variable_ptr, indices);
llvm::Type* variable_type = variable_ptr->getType()->getPointerElementType();
return builder.CreateInBoundsGEP(variable_type, variable_ptr, indices);
}

llvm::Value* IRBuilder::create_inbounds_gep(llvm::Value* variable, llvm::Value* index) {
return builder.CreateInBoundsGEP(variable, {index});
ValueVector indices{index};
llvm::Type* variable_type = variable->getType()->getPointerElementType();
return builder.CreateInBoundsGEP(variable_type, variable, indices);
}

llvm::Value* IRBuilder::create_index(llvm::Value* value) {
Expand All @@ -378,23 +381,25 @@ llvm::Value* IRBuilder::create_index(llvm::Value* value) {

llvm::Value* IRBuilder::create_load(const std::string& name, bool masked) {
llvm::Value* ptr = lookup_value(name);
llvm::Type* loaded_type = ptr->getType()->getPointerElementType();

// Check if the generated IR is vectorized and masked.
if (masked) {
return builder.CreateMaskedLoad(ptr, llvm::Align(), mask);
builder.CreateMaskedLoad(loaded_type, ptr, llvm::Align(), mask);
}
llvm::Type* loaded_type = ptr->getType()->getPointerElementType();
llvm::Value* loaded = builder.CreateLoad(loaded_type, ptr);
value_stack.push_back(loaded);
return loaded;
}

llvm::Value* IRBuilder::create_load(llvm::Value* ptr, bool masked) {
llvm::Type* loaded_type = ptr->getType()->getPointerElementType();

// Check if the generated IR is vectorized and masked.
if (masked) {
return builder.CreateMaskedLoad(ptr, llvm::Align(), mask);
builder.CreateMaskedLoad(loaded_type, ptr, llvm::Align(), mask);
}
llvm::Type* loaded_type = ptr->getType()->getPointerElementType();

llvm::Value* loaded = builder.CreateLoad(loaded_type, ptr);
value_stack.push_back(loaded);
return loaded;
Expand Down Expand Up @@ -466,7 +471,9 @@ llvm::Value* IRBuilder::get_struct_member_ptr(llvm::Value* struct_variable, int
ValueVector indices;
indices.push_back(llvm::ConstantInt::get(get_i32_type(), 0));
indices.push_back(llvm::ConstantInt::get(get_i32_type(), member_index));
return builder.CreateInBoundsGEP(struct_variable, indices);

llvm::Type* type = struct_variable->getType()->getPointerElementType();
return builder.CreateInBoundsGEP(type, struct_variable, indices);
}

void IRBuilder::invert_mask() {
Expand All @@ -491,14 +498,23 @@ llvm::Value* IRBuilder::load_to_or_store_from_array(const std::string& id_name,
bool generating_vector_ir = vector_width > 1 && vectorize;

// If the vector code is generated, we need to distinguish between two cases. If the array is
// indexed indirectly (i.e. not by an induction variable `kernel_id`), create a gather
// instruction.
// indexed indirectly (i.e. not by an induction variable `kernel_id`), create gather/scatter
// instructions.
if (id_name != kernel_id && generating_vector_ir) {
return maybe_value_to_store ? builder.CreateMaskedScatter(maybe_value_to_store,
element_ptr,
llvm::Align(),
mask)
: builder.CreateMaskedGather(element_ptr, llvm::Align(), mask);
if (maybe_value_to_store) {
return builder.CreateMaskedScatter(maybe_value_to_store,
element_ptr,
llvm::Align(),
mask);
} else {
// Construct the loaded vector type.
auto* ptrs = llvm::cast<llvm::VectorType>(element_ptr->getType());
llvm::ElementCount element_count = ptrs->getElementCount();
llvm::Type* element_type = ptrs->getElementType()->getPointerElementType();
llvm::Type* loaded_type = llvm::VectorType::get(element_type, element_count);

return builder.CreateMaskedGather(loaded_type, element_ptr, llvm::Align(), mask);
}
}

llvm::Value* ptr;
Expand Down
4 changes: 2 additions & 2 deletions test/unit/codegen/codegen_llvm_ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1354,8 +1354,8 @@ SCENARIO("Vector library calls", "[visitor][llvm][vector_lib]") {
/*use_single_precision=*/false,
/*vector_width=*/2,
/*vec_lib=*/"MASSV");
std::regex massv2_exp_decl(R"(declare <2 x double> @__expd2_P8\(<2 x double>\))");
std::regex massv2_exp_call(R"(call <2 x double> @__expd2_P8\(<2 x double> .*\))");
std::regex massv2_exp_decl(R"(declare <2 x double> @__expd2\(<2 x double>\))");
std::regex massv2_exp_call(R"(call <2 x double> @__expd2\(<2 x double> .*\))");
REQUIRE(std::regex_search(massv2_library_module_str, m, massv2_exp_decl));
REQUIRE(std::regex_search(massv2_library_module_str, m, massv2_exp_call));
REQUIRE(!std::regex_search(massv2_library_module_str, m, exp_call));
Expand Down

0 comments on commit ff5430c

Please sign in to comment.