llvm-cbe complains intrinsic function `llvm.is.constant.i64` not support
Closed this issue · 3 comments
The source is compiled to bc via clang-11.1.0
And I build llvm-cbe with system llvm(of course 11.1.0)
llvm-cbe xxx.bc output the following
LLVM ERROR: Code generator does not support intrinsic function 'llvm.is.constant.i64'!
#0 0x00007f145db9c0db llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/lib/libLLVM-11.so+0xa760db)
#1 0x00007f145db99e14 llvm::sys::RunSignalHandlers() (/usr/lib/libLLVM-11.so+0xa73e14)
#2 0x00007f145db99f61 (/usr/lib/libLLVM-11.so+0xa73f61)
#3 0x00007f145cd9ef80 __restore_rt (/usr/lib/libc.so.6+0x3cf80)
#4 0x00007f145cd9eef5 raise (/usr/lib/libc.so.6+0x3cef5)
#5 0x00007f145cd88862 abort (/usr/lib/libc.so.6+0x26862)
#6 0x00007f145dabfeb4 llvm::report_fatal_error(llvm::Twine const&, bool) (/usr/lib/libLLVM-11.so+0x999eb4)
#7 0x00007f145de70e39 llvm::IntrinsicLowering::LowerIntrinsicCall(llvm::CallInst*) (/usr/lib/libLLVM-11.so+0xd4ae39)
#8 0x0000562e79c7bf3a (/usr/bin/llvm-cbe+0x16f3a)
#9 0x0000562e79c92225 (/usr/bin/llvm-cbe+0x2d225)
#10 0x00007f145dce9a60 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/lib/libLLVM-11.so+0xbc3a60)
#11 0x00007f145dceb03d llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/lib/libLLVM-11.so+0xbc503d)
#12 0x00007f145dce8b20 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/lib/libLLVM-11.so+0xbc2b20)
#13 0x0000562e79c75d5f (/usr/bin/llvm-cbe+0x10d5f)
#14 0x0000562e79c74421 (/usr/bin/llvm-cbe+0xf421)
#15 0x00007f145cd89b25 __libc_start_main (/usr/lib/libc.so.6+0x27b25)
#16 0x0000562e79c7451e (/usr/bin/llvm-cbe+0xf51e)
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: llvm-cbe test_contract.bc
1. Running pass 'Function Pass Manager' on module 'test_contract.bc'.
2. Running pass 'C backend' on function '@_ZNSt11char_traitsIcE7compareEPKcS2_m'
[1] 1603923 abort (core dumped) llvm-cbe test_contract.bc
Presumably this means that LLVM-CBE needs to implement this intrinsic itself.
From looking at the description of llvm.is.constant
in the LLVM Language Reference, I think we can just replace it with false
? I wonder if “It is guaranteed to fold to either true or false before generating machine code.” means we shouldn't be encountering the intrinsic, though.
@hzhangxyz Can you provide the original program that triggered the problem?
Yes, false
should be correct, or it could lower to the gcc function __builtin_constant_p
, but define that to false elsewhere.
Hello, This is a small example to reproduce this issue:
#include <algorithm>
struct NoSymmetry {
bool operator==(NoSymmetry) {
return true;
}
NoSymmetry operator+=(NoSymmetry) {
return *this;
}
};
template<typename Symmetry>
struct Edge {
static constexpr bool conjugated = false;
using symmetry_t = Symmetry;
using map_t = std::vector<std::pair<Symmetry, int>>;
map_t map;
Edge(const int dimension) : map({{Symmetry(), dimension}}) {}
};
template<bool check_conjugated = false, typename Edges>
[[nodiscard]] auto initialize_block_symmetries_with_check(const Edges& edges) {
using Edge = typename Edges::value_type;
using Symmetry = typename Edge::symmetry_t;
int rank = edges.size();
using ResultItem = std::pair<std::vector<Symmetry>, int>;
auto result = std::vector<ResultItem>();
auto symmetries = std::vector<Symmetry>(rank);
auto sizes = std::vector<int>(rank);
if (rank == 0) {
result.emplace_back(std::piecewise_construct, std::tuple{}, std::tuple{1});
return result;
}
using Iterator = typename Edge::map_t::const_iterator;
auto symmetry_iterator_list = std::vector<Iterator>();
symmetry_iterator_list.reserve(rank);
for (auto i = 0; i != rank; ++i) {
const auto& map = edges[i].map;
if (edges[i].map.empty()) {
return result;
}
symmetry_iterator_list.push_back((check_conjugated && edges[i].conjugated) ? std::prev(map.end()) : map.begin());
}
int minimum_changed = 0;
while (true) {
{
auto symmetry_summary = Symmetry();
for (const auto& symmetry_iterator : symmetry_iterator_list) {
symmetry_summary += symmetry_iterator->first;
}
if (symmetry_summary == Symmetry()) {
for (auto i = minimum_changed; i < rank; i++) {
symmetries[i] = symmetry_iterator_list[i]->first;
sizes[i] = symmetry_iterator_list[i]->second * (i ? sizes[i - 1] : 1);
}
result.emplace_back(std::piecewise_construct, std::tuple{symmetries.begin(), symmetries.end()}, std::tuple{sizes.back()});
minimum_changed = rank;
}
}
auto edge_position = rank - 1;
while ((check_conjugated && edges[edge_position].conjugated) ? symmetry_iterator_list[edge_position]-- == edges[edge_position].map.begin() :
++symmetry_iterator_list[edge_position] == edges[edge_position].map.end()) {
if (edge_position == 0) {
return result;
}
symmetry_iterator_list[edge_position] =
(check_conjugated && edges[edge_position].conjugated) ? std::prev(edges[edge_position].map.end()) : edges[edge_position].map.begin();
--edge_position;
}
minimum_changed = minimum_changed < edge_position ? minimum_changed : edge_position;
}
}
int main() {
using E = Edge<NoSymmetry>;
auto edges = std::vector<E>{2, 3};
auto r = initialize_block_symmetries_with_check(edges);
}
I compile with
clang++ test.cpp -std=c++17 -S -emit-llvm
llvm-cbe test.ll
Then the error reported.
My clang version is 11.1.0,
llvm-cbe is build from current master (139e254)