Skip to content

ICE when using function as an argument #452

@nazar-pc

Description

@nazar-pc

I need to reuse a sorting function to sort by different keys depending on use case, so I made the following changes to my project:

@@ -17,6 +17,7 @@
     bit_position: u32,
     block_size: usize,
     local_bucket: &mut [PositionR; ELEMENTS_PER_THREAD],
+    cmp_key: fn(&PositionR) -> u32,
 ) {
     // For local swaps within a thread's register data, iterate over half the elements to form pairs
     // `(a_offset, b_offset)` where indices differ only at `bit_position` and swaps them in-place
@@ -40,7 +41,7 @@
         let select_smaller =
             ((lane_id as usize * ELEMENTS_PER_THREAD + a_offset) & block_size) == 0;
 
-        let (final_a, final_b) = if (a.position <= b.position) == select_smaller {
+        let (final_a, final_b) = if (cmp_key(&a) <= cmp_key(&b)) == select_smaller {
             (a, b)
         } else {
             (b, a)
@@ -57,6 +58,7 @@
     bit_position: u32,
     block_size: usize,
     local_bucket: &mut [PositionR; ELEMENTS_PER_THREAD],
+    cmp_key: fn(&PositionR) -> u32,
 ) {
     // For cross-subgroup swaps, compute partner lane differing at `lane_bit_position`
     let lane_bit_position = bit_position - ELEMENTS_PER_THREAD.ilog2();
@@ -84,7 +86,7 @@
             PositionR { position, r }
         };
 
-        let selected_value = if (a.position <= b.position) == select_smaller {
+        let selected_value = if (cmp_key(&a) <= cmp_key(&b)) == select_smaller {
             a
         } else {
             b
@@ -121,6 +123,7 @@
 fn sort_local_bucket<const ELEMENTS_PER_THREAD: usize>(
     lane_id: u32,
     local_bucket: &mut [PositionR; ELEMENTS_PER_THREAD],
+    cmp_key: fn(&PositionR) -> u32,
 ) {
     // Iterate over merger stages, doubling block_size each time
     let mut block_size = 2;
@@ -132,10 +135,22 @@
         for bit_position in (0..merger_stage).rev() {
             if bit_position < ELEMENTS_PER_THREAD.ilog2() {
                 // Local swaps within thread's registers, no synchronization needed
-                perform_local_compare_swap(lane_id, bit_position, block_size, local_bucket);
+                perform_local_compare_swap(
+                    lane_id,
+                    bit_position,
+                    block_size,
+                    local_bucket,
+                    cmp_key,
+                );
             } else {
                 // Cross-lane swaps using subgroup shuffles for communication
-                perform_cross_compare_swap(lane_id, bit_position, block_size, local_bucket);
+                perform_cross_compare_swap(
+                    lane_id,
+                    bit_position,
+                    block_size,
+                    local_bucket,
+                    cmp_key,
+                );
             }
         }
         block_size *= 2;
@@ -172,7 +187,12 @@
 
     load_into_local_bucket(lane_id, bucket_size, bucket, &mut local_bucket);
 
-    sort_local_bucket(lane_id, &mut local_bucket);
+    sort_local_bucket(
+        lane_id,
+        &mut local_bucket,
+        #[inline(always)]
+        |position_r| position_r.position,
+    );
 
     store_from_local_bucket(lane_id, bucket, &local_bucket);
 }

Unfortunately, rustc didn't like that at all:

ICE
thread 'rustc' panicked at /home/nazar-pc/.cargo/git/checkouts/rust-gpu-d06d15e2ba0f0ae2/6a9ea3b/crates/rustc_codegen_spirv/src/linker/simple_passes.rs:240:44:
no entry found for key
stack backtrace:
   0:     0x7f4c944a3b85 - std::backtrace::Backtrace::create::h32a51249d78657b9
   1:     0x7f4c944a3ad5 - std::backtrace::Backtrace::force_capture::h59fbd3beb0b7ebd4
   2:     0x7f4c93584f52 - std[47a95048f41649f2]::panicking::update_hook::<alloc[a82d94b8c3b79735]::boxed::Box<rustc_driver_impl[5ab17e6b36e59dd4]::install_ice_hook::{closure#1}>>::{closure#0}
   3:     0x7f4c935847e3 - std[47a95048f41649f2]::panicking::update_hook::<alloc[a82d94b8c3b79735]::boxed::Box<rustc_driver_impl[5ab17e6b36e59dd4]::install_ice_hook::{closure#1}>>::{closure#0}
   4:     0x7f4c944bdbbb - std::panicking::rust_panic_with_hook::h25a3025a927f112d
   5:     0x7f4c944bd8ba - std::panicking::begin_panic_handler::{{closure}}::h21266e60c12bf697
   6:     0x7f4c944b9ee9 - std::sys::backtrace::__rust_end_short_backtrace::hef199fe2823162f9
   7:     0x7f4c944bd59d - __rustc[a3a962cb80ef9725]::rust_begin_unwind
   8:     0x7f4c90ca4570 - core::panicking::panic_fmt::hb5cc6ca3635c7279
   9:     0x7f4c9200c5fb - core::option::expect_failed::h1d79806550377b1e
  10:     0x7f4c82768e60 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  11:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  12:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  13:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  14:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  15:     0x7f4c82767ffe - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::hef947097e42244f9
  16:     0x7f4c82627c5f - rustc_codegen_spirv::linker::link::hf9bff09557bd6aa7
  17:     0x7f4c82752f6c - rustc_codegen_spirv::link::link::h4ba4c007671007c2
  18:     0x7f4c829dd035 - <rustc_codegen_spirv::SpirvCodegenBackend as rustc_codegen_spirv::maybe_pqp_cg_ssa::traits::backend::CodegenBackend>::link::h2e0b043a12ab3da6
  19:     0x7f4c95d09633 - <rustc_interface[9a4f103755b13c1e]::queries::Linker>::link
  20:     0x7f4c95e24219 - rustc_interface[9a4f103755b13c1e]::interface::run_compiler::<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}
  21:     0x7f4c95de0638 - std[47a95048f41649f2]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_with_globals<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_pool_with_globals<rustc_interface[9a4f103755b13c1e]::interface::run_compiler<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  22:     0x7f4c95de0316 - <<std[47a95048f41649f2]::thread::Builder>::spawn_unchecked_<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_with_globals<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_pool_with_globals<rustc_interface[9a4f103755b13c1e]::interface::run_compiler<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[28534e9693d03804]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  23:     0x7f4c95dde93d - std::sys::pal::unix::thread::Thread::new::thread_start::hf0d6fc1bcf013f18
  24:     0x7f4c8f69caa4 - start_thread
                               at ./nptl/pthread_create.c:447:8
  25:     0x7f4c8f729c6c - clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0
  26:                0x0 - <unknown>


rustc version: 1.90.0-nightly (35f603652 2025-06-29)
platform: x86_64-unknown-linux-gnuthread 'rustc' panicked at /home/nazar-pc/.cargo/git/checkouts/rust-gpu-d06d15e2ba0f0ae2/6a9ea3b/crates/rustc_codegen_spirv/src/linker/simple_passes.rs:240:44:
no entry found for key
stack backtrace:
   0:     0x7f4c944a3b85 - std::backtrace::Backtrace::create::h32a51249d78657b9
   1:     0x7f4c944a3ad5 - std::backtrace::Backtrace::force_capture::h59fbd3beb0b7ebd4
   2:     0x7f4c93584f52 - std[47a95048f41649f2]::panicking::update_hook::<alloc[a82d94b8c3b79735]::boxed::Box<rustc_driver_impl[5ab17e6b36e59dd4]::install_ice_hook::{closure#1}>>::{closure#0}
   3:     0x7f4c944bdbbb - std::panicking::rust_panic_with_hook::h25a3025a927f112d
   4:     0x7f4c944bd8ba - std::panicking::begin_panic_handler::{{closure}}::h21266e60c12bf697
   5:     0x7f4c944b9ee9 - std::sys::backtrace::__rust_end_short_backtrace::hef199fe2823162f9
   6:     0x7f4c944bd59d - __rustc[a3a962cb80ef9725]::rust_begin_unwind
   7:     0x7f4c90ca4570 - core::panicking::panic_fmt::hb5cc6ca3635c7279
   8:     0x7f4c9200c5fb - core::option::expect_failed::h1d79806550377b1e
   9:     0x7f4c82768e60 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  10:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  11:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  12:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  13:     0x7f4c827689d7 - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::visit::hf4b4918e200b98b5
  14:     0x7f4c82767ffe - rustc_codegen_spirv::linker::simple_passes::check_fragment_insts::hef947097e42244f9
  15:     0x7f4c82627c5f - rustc_codegen_spirv::linker::link::hf9bff09557bd6aa7
  16:     0x7f4c82752f6c - rustc_codegen_spirv::link::link::h4ba4c007671007c2
  17:     0x7f4c829dd035 - <rustc_codegen_spirv::SpirvCodegenBackend as rustc_codegen_spirv::maybe_pqp_cg_ssa::traits::backend::CodegenBackend>::link::h2e0b043a12ab3da6
  18:     0x7f4c95d09633 - <rustc_interface[9a4f103755b13c1e]::queries::Linker>::link
  19:     0x7f4c95e24219 - rustc_interface[9a4f103755b13c1e]::interface::run_compiler::<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}
  20:     0x7f4c95de0638 - std[47a95048f41649f2]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_with_globals<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_pool_with_globals<rustc_interface[9a4f103755b13c1e]::interface::run_compiler<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  21:     0x7f4c95de0316 - <<std[47a95048f41649f2]::thread::Builder>::spawn_unchecked_<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_with_globals<rustc_interface[9a4f103755b13c1e]::util::run_in_thread_pool_with_globals<rustc_interface[9a4f103755b13c1e]::interface::run_compiler<(), rustc_driver_impl[5ab17e6b36e59dd4]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[28534e9693d03804]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  22:     0x7f4c95dde93d - std::sys::pal::unix::thread::Thread::new::thread_start::hf0d6fc1bcf013f18
  23:     0x7f4c8f69caa4 - start_thread
                               at ./nptl/pthread_create.c:447:8
  24:     0x7f4c8f729c6c - clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78:0
  25:                0x0 - <unknown>

This is unexpected, especially because I want it to be literally inlined by the compiler so that generated code is no different to before.

Currently using 6a9ea3b.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions