MethodicalAcceleratorDesign / MAD-NG

MAD Next-Generation official repository
GNU General Public License v3.0
32 stars 11 forks source link

mad_tpsa_copy00 and GCC bug #435

Closed ldeniau closed 7 months ago

ldeniau commented 7 months ago

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

static inline  tpsa_t*  mad_tpsa_copy00 (const  tpsa_t *a, const  tpsa_t *b,  tpsa_t *r);
static inline ctpsa_t* mad_ctpsa_copy00 (const ctpsa_t *a, const ctpsa_t *b, ctpsa_t *r)
    { return (ctpsa_t*) mad_tpsa_copy00 ((const tpsa_t*)a, (const tpsa_t*)b, (tpsa_t*)r); }

perform simple bits manipulation and assignment to the header of r only for add-like operations but in the normal forms the function accumulate

ctpsa_t* mad_ctpsa_acc (const ctpsa_t *a, ctpsa_t *c);

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.

ldeniau commented 7 months ago

fixed in 6c50a69f.