Closed hzhangxyz closed 7 months ago
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)
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