Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/CodeGen_Hexagon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,23 @@ Value *CodeGen_Hexagon::interleave_vectors(const vector<llvm::Value *> &v) {
int native_elements =
native_vector_bits() / element_ty->getScalarSizeInBits();
int result_elements = get_vector_num_elements(v_ty) * v.size();
if (element_bits == 1) {
// If this is a vector of booleans, convert it to a vector of bytes,
// interleave that, and convert back. This avoids routing predicate
// (mask) vectors through the vdelta-based byte shuffle network
// below, which assumes native-vector-sized byte data: small,
// sub-native-width concatenations of predicates (as produced here
// when the number of lanes is much smaller than a native HVX
// vector) can trip up LLVM's Hexagon backend during DAG combining.
vector<llvm::Value *> i8_v(v.size());
for (size_t i = 0; i < v.size(); i++) {
llvm::Type *i8_ty = get_vector_type(i8_t, get_vector_num_elements(v[i]->getType()));
i8_v[i] = builder->CreateIntCast(v[i], i8_ty, true);
}
Value *result = interleave_vectors(i8_v);
llvm::Type *result_ty = get_vector_type(element_ty, result_elements);
return builder->CreateIntCast(result, result_ty, true);
}
if (v.size() == 2) {
// Interleaving two vectors.
Value *a = v[0];
Expand Down
14 changes: 14 additions & 0 deletions src/JITModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,21 @@ void compile_module_impl(
dtorRunner->add(dtors);

// Resolve system symbols (like pthread, dl and others)
#if defined(__GNUC__) && !defined(__clang__)
// GCC's -Wuninitialized/-Wmaybe-uninitialized misfires on the move
// constructor of the default-constructed llvm::unique_function
// (AddAbsoluteSymbolsFn) that GetForCurrentProcess() takes by default
// argument, after LLVM's unique_function was refactored upstream
// (llvm/llvm-project#208251). Which of the two warnings fires depends
// on the GCC version, so both are silenced here.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
auto gen = llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(target_data_layout.getGlobalPrefix());
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
internal_assert(gen) << llvm::toString(gen.takeError()) << "\n";
JIT->getMainJITDylib().addGenerator(std::move(gen.get()));

Expand Down
47 changes: 33 additions & 14 deletions test/fuzz/lossless_cast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,27 +267,46 @@ FUZZ_TEST(lossless_cast, FuzzingContext &fuzz) {
buf_u8.fill(fuzz);
buf_i8.fill(fuzz);

Expr e1 = random_expr(fuzz);
Expr simplified = simplify(e1);
// random_expr() can produce deeply-nested expressions, and simplify(),
// lower_intrinsics(), and friends visit them recursively. Unlike the
// Pipeline lowering/codegen path (which already runs on a large stack
// via Internal::run_with_large_stack), these calls would otherwise run
// directly on the calling thread's stack, which can be too small on
// some CI configurations.
Expr e1, e2;
ConstantInterval bounds;
bool skip = false;
bool has_ub = false;
run_with_large_stack([&]() {
e1 = random_expr(fuzz);
Expr simplified = simplify(e1);

if (might_have_ub(e1) ||
might_have_ub(simplified) ||
might_have_ub(lower_intrinsics(simplified))) {
skip = true;
return;
}

if (might_have_ub(e1) ||
might_have_ub(simplified) ||
might_have_ub(lower_intrinsics(simplified))) {
return 0;
}
// We're also going to test constant_integer_bounds here.
bounds = constant_integer_bounds(e1);

// We're also going to test constant_integer_bounds here.
ConstantInterval bounds = constant_integer_bounds(e1);
std::vector<Type> target_types = {UInt(32), Int(32), UInt(16), Int(16)};
Type target = fuzz.PickValueInVector(target_types);
e2 = lossless_cast(target, e1);
if (!e2.defined()) {
skip = true;
return;
}

std::vector<Type> target_types = {UInt(32), Int(32), UInt(16), Int(16)};
Type target = fuzz.PickValueInVector(target_types);
Expr e2 = lossless_cast(target, e1);
has_ub = definitely_has_ub(e2);
});

if (!e2.defined()) {
if (skip) {
return 0;
}

if (definitely_has_ub(e2)) {
if (has_ub) {
std::cerr << "lossless_cast introduced ub:\n"
<< "e1 = " << e1 << "\n"
<< "e2 = " << e2 << "\n"
Expand Down
20 changes: 10 additions & 10 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading