calls copy00(a,c,c) where c is seen both as const (aka b) and non-const (aka r) by the compiler. Since copy00 is only considering the header of the TPSA common to tpsa and ctpsa, the casts from ctpsa to tpsa are safe as far as their constness is preserved. None of the pointed memory locations are read-only protected and none of the pointers are restricted (to allow strict aliasing optimizations). Thus in principle, the non-const should prevail and memory pointed by c-as-r should be updated and reloaded. But GCC considers only the const c-as-b and discards the calculation, which is a serious bug in the static analysis of memory aliasing, even in the presence of aggressive optimizations...
The workaround is to reassign the returned non-const pointer to c = copy00(a,c,c) to enforce the calculation on c-as-r.
I finally found what was breaking the normal forms (somewhere in billions of operations!) and it's a bug in the compiler (actually GCC 13.2.0)...
The tpsa and ctpsa functions
perform simple bits manipulation and assignment to the header of
r
only for add-like operations but in the normal forms the function accumulatecalls
copy00(a,c,c)
wherec
is seen both as const (aka b) and non-const (aka r) by the compiler. Sincecopy00
is only considering the header of the TPSA common to tpsa and ctpsa, the casts from ctpsa to tpsa are safe as far as their constness is preserved. None of the pointed memory locations are read-only protected and none of the pointers are restricted (to allow strict aliasing optimizations). Thus in principle, the non-const should prevail and memory pointed by c-as-r should be updated and reloaded. But GCC considers only the const c-as-b and discards the calculation, which is a serious bug in the static analysis of memory aliasing, even in the presence of aggressive optimizations...The workaround is to reassign the returned non-const pointer to
c = copy00(a,c,c)
to enforce the calculation on c-as-r.