         {
             if (segment_flags[ITEM])
             {
-                OffsetT scatter_offset = segment_indices[ITEM] - num_tile_segments_prefix - ((IS_FIRST_TILE ? 1 : 0));
-                temp_storage.raw_exchange_values.Alias()[scatter_offset] = values[ITEM];
+                temp_storage.raw_exchange_values.Alias()[segment_indices[ITEM] - num_tile_segments_prefix] = values[ITEM];
             }
         }
 
         __syncthreads();
 
-        for (int item = threadIdx.x; item < num_tile_segments + ((IS_LAST_TILE ? 1 : 0)); item += BLOCK_THREADS)
-        {
-            OffsetT scatter_offset = num_tile_segments_prefix + item - ((IS_FIRST_TILE ? 0 : 1));
-            d_aggregates_out[scatter_offset] = temp_storage.raw_exchange_values.Alias()[item];
+        int first_value = (IS_FIRST_TILE) ? threadIdx.x + 1 : threadIdx.x;
+        int last_value = (IS_LAST_TILE) ? CUB_MIN(num_tile_segments + 1, TILE_ITEMS) : num_tile_segments;
+        for (int item = first_value; item < last_value; item += BLOCK_THREADS)
+        {
+            d_aggregates_out[num_tile_segments_prefix + item - 1] = temp_storage.raw_exchange_values.Alias()[item];
         }
     }
 

        OffsetT (&segment_indices)[ITEMS_PER_THREAD],
        OffsetT num_segments)
    {
        // Scatter flagged keys and values
        #pragma unroll
        for (int ITEM = 0; ITEM < ITEMS_PER_THREAD; ++ITEM)

            // Update tile status if this is not the last tile
            if (!IS_LAST_TILE)
                tile_state.SetInclusive(0, tile_aggregate);

            // Initialize the segment index for the first scan item if necessary (the exclusive prefix for the first item is garbage)
            if (!HAS_IDENTITY_ZERO)
