Hey,
I want to fix the type-punned pointer problem in freeverb~ so it can be compiled with full optimization. Here's the code snippets in question, with the warnings being issued for the FIX_DENORM_NAN_FLOAT () lines:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long*)&(v))&0x7f800000)==0) &&((v)!=0.f)) #define FIX_DENORM_NAN_FLOAT(v) ((v)=IS_DENORM_NAN_FLOAT(v)?0.f:(v))
static inline t_float comb_processR(t_freeverb *x, int filteridx, t_float input) { t_float output; int bufidx = x->x_combidxR[filteridx];
output = x->x_bufcombR[filteridx][bufidx]; FIX_DENORM_NAN_FLOAT(output);
x->x_filterstoreR[filteridx] = (output*x->x_combdamp2) + (x-
x_filterstoreR[filteridx]*x->x_combdamp1);
FIX_DENORM_NAN_FLOAT(x->x_filterstoreR[filteridx]);
[snip]
Could I just cast things to (unsigned long)? Or is there a better way?
.hc
------------------------------------------------------------------------ ----
Hans-Christoph Steiner wrote:
Hey,
I want to fix the type-punned pointer problem in freeverb~ so it can be compiled with full optimization. Here's the code snippets in question, with the warnings being issued for the FIX_DENORM_NAN_FLOAT () lines:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long*)&(v))&0x7f800000)==0) &&((v)!=0.f)) #define FIX_DENORM_NAN_FLOAT(v) ((v)=IS_DENORM_NAN_FLOAT(v)?0.f:(v))
static inline t_float comb_processR(t_freeverb *x, int filteridx, t_float input) { t_float output; int bufidx = x->x_combidxR[filteridx];
output = x->x_bufcombR[filteridx][bufidx]; FIX_DENORM_NAN_FLOAT(output);
x->x_filterstoreR[filteridx] = (output*x->x_combdamp2) + (x-
x_filterstoreR[filteridx]*x->x_combdamp1);
FIX_DENORM_NAN_FLOAT(x->x_filterstoreR[filteridx]);
[snip]
Could I just cast things to (unsigned long)? Or is there a better way?
I think the proper way is to use a union, so you can refer to the same thing as two different types.
Martin
On Dec 7, 2007, at 7:05 PM, Martin Peach wrote:
Hans-Christoph Steiner wrote:
Hey,
I want to fix the type-punned pointer problem in freeverb~ so it can be compiled with full optimization. Here's the code snippets in question, with the warnings being issued for the FIX_DENORM_NAN_FLOAT () lines:
#define IS_DENORM_FLOAT(v) ((((*(unsigned long*)&(v))&0x7f800000) ==0) &&((v)!=0.f)) #define FIX_DENORM_NAN_FLOAT(v) ((v)=IS_DENORM_NAN_FLOAT(v)?0.f: (v))
static inline t_float comb_processR(t_freeverb *x, int filteridx, t_float input) { t_float output; int bufidx = x->x_combidxR[filteridx];
output = x->x_bufcombR[filteridx][bufidx]; FIX_DENORM_NAN_FLOAT(output);
x->x_filterstoreR[filteridx] = (output*x->x_combdamp2) + (x-
x_filterstoreR[filteridx]*x->x_combdamp1);
FIX_DENORM_NAN_FLOAT(x->x_filterstoreR[filteridx]);
[snip]
Could I just cast things to (unsigned long)? Or is there a better way?
I think the proper way is to use a union, so you can refer to the same thing as two different types.
Ok, so that's out of my C knowledge. I've only barely touched unions in my life... anyone feel like taking a stab at this? It would be lovely to fix the last of these "dereferencing type-punned pointer will break strict-aliasing rules" errors so that we can build all of Pd-extended to use better optimization and auto-vectorization. (FYI, fixing this error is required for C99 compliance).
Here's the current list: ../../shared/common/binport.c /home/pd/auto-build/pd-extended/externals/bsaylor/svf~.c /home/pd/auto-build/pd-extended/externals/footils/knob/knob.c /home/pd/auto-build/pd-extended/externals/creb/modules++/DSPIfilters.h /home/pd/auto-build/pd-extended/externals/freeverb~/freeverb~.c /home/pd/auto-build/pd-extended/externals/iem/iem_spec2/src/ spec2_sqrt~.c /home/pd/auto-build/pd-extended/externals/iem/iem_tab/src/tab_sqrt.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/filter~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/ hml_shelf~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/ iem_sqrt4~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/lp1_t~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/para_bp2~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/peakenv~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/prvu~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/pvu~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/rvu~.c /home/pd/auto-build/pd-extended/externals/iemlib/iemlib1/src/ vcf_filter~.c /home/pd/auto-build/pd-extended/externals/moonlib/mknob.c /home/pd/auto-build/pd-extended/externals/moonlib/readsfv~.c /home/pd/auto-build/pd-extended/externals/sigpack/source/freqshift~.c OSC-client.c dumpOSC.c hammer/Append.c pdp2gem.cpp sickle/Line.c sickle/bitand.c sickle/bitnot.c sickle/bitor.c sickle/bitshift.c sickle/bitxor.c sickle/curve.c sickle/lores.c sickle/onepole.c sickle/rampsmooth.c sickle/reson.c sickle/slide.c sickle/svf.c vexp.c vexp_if.c
.hc
------------------------------------------------------------------------ ----
Access to computers should be unlimited and total. - the hacker ethic
On Fri, 7 Dec 2007, Hans-Christoph Steiner wrote:
I want to fix the type-punned pointer problem in freeverb~ so it can be compiled with full optimization. Here's the code snippets in question, with the warnings being issued for the FIX_DENORM_NAN_FLOAT () lines: #define IS_DENORM_FLOAT(v) ((((*(unsigned long*)&(v))&0x7f800000)==0) &&((v)!=0.f))
*(unsigned long *) causes the problem. Is there any other reliable way to test for denormals? I don't know one. Maybe just something along the lines of abs(v)<1.175494e-38 ? I don't know either.
Could I just cast things to (unsigned long)? Or is there a better way?
No, (unsigned long) never does anything similar to (unsigned long *).
If you cast either the float or the float* to (unsigned long) you get completely useless information that you can't test denormals with. (in the latter case you can still cast back to pointer, but in the former case you just rounded too much and it's all destroyed)
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada