CMEMTHREAD waits during Index Optimisation in Availability Group
I don't have access to an Availability Group secondary that's really cooking :-)
but i can share some things that'll get you a little farther.
When you have parallel redo on the secondary, activity like redo of heavy index maintenance is accompanied by CMEMTHREAD waits.  These waits disappear when Trace Flag 3459 is globally enabled.  And you are wondering if the CMEMTHREAD wait behavior is due to a bug.
It is unlikely the CMEMTHREAD wait behavior is due to a bug.
The post linked below is a few years old but still my favorite in explaining the intent of CMEMTHREAD waits as memory object serialization control.  Bob explains those memory objects with access potentially controlled by CMEMTHREAD waits may be global, partitioned per NUMA node, or partitioned per CPU.
How It Works: CMemThread and Debugging Them
Bob Dorr &amp; Rohit Nayak
2012 December 20
https://techcommunity.microsoft.com/t5/sql-server-support/how-it-works-cmemthread-and-debugging-them/ba-p/317488
One of the important enhancements in SQL Server 2016 was the introduction of dynamic memory object partitioning.  Prior to SQL Server 2016, as contention was observed to be a significant issue on individual global memory objects, individual trace flags would enable partitioning that object by NUMA node(trace flag 1236 is an example).  And trace flag 8048 would promote many of the memory objects partitioned at the NUMA node level to being partitioned at the CPU level.
In SQL Server 2016, many of the memory objects became eligible for dynamic object partitioning: they'd start with a single global partition but as contention was detected they'd be promoted to NUMA node partitioned.  If further contention is detected, the object would be promoted again to CPU partitioned.
More about that in this blog post.
Dynamic Memory Object Scaling
Ajay Jagannathan
2016 June 27
https://techcommunity.microsoft.com/t5/sql-server/dynamic-memory-object-scaling/ba-p/384755
So while parallel redo activity is seeing high CMEMTHREAD waits, watching the results of the query below over time will reveal which memory objects are under contention. I think its likely to be a global object that is not eligible for dynamic partitioning.
SELECT omo.type, memory_node_id, omo.pages_in_bytes, omo.partition_type, omo.partition_type_desc, 
omo.waiting_tasks_count, omo.exclusive_access_count, omo.contention_factor
FROM sys.dm_os_memory_objects omo
WHERE omo.waiting_tasks_count &gt; 0
ORDER BY omo.waiting_tasks_count DESC;

So, enabling global trace flag 3459 mitigates the CMEMTHREAD wait time.  In this case, that's to be expected.  Global trace flag 3459 disables parallel redo, leaving the AG secondary with serial redo.  With a single redo thread for the Availability Group secondary redo activity, the contention for the memory object that was present with parallel redo is suddenly gone.
Whichever memory object is under contention in this scenario, it may be possible for enhancement to allow it to be dynamically promoted as many other objects are, which would alleviate the CMEMTHREAD waits even with parallel redo.  But some work is harder or more expensive to partition than to accomplish as a single global object.