This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/13041


Hi,

This is the kernel miscompilation talked about here:

   http://gcc.gnu.org/ml/gcc/2003-11/msg00893.html

a regression on the 3.3 branch.

The attached patch implements the minimal fix.

Bootstrapped/regtested on i586-redhat-linux-gnu (3.3 branch except Ada). I've 
attached a reduced testcase but it is not integrable in the testsuite. The 
problem can be found by visual inspection (line below the .L4 label).

Ok for mainline and 3.3 branch?


2003-11-20  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR optimization/13041
	* final.c (frame_pointer_needed): Fix comment.
	* reload1.c (reload): Decrease alignment of the frame
	pointer if it was used for register allocation.


-- 
Eric Botcazou
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.271.2.1
diff -u -r1.271.2.1 final.c
--- final.c	25 Jan 2003 23:40:06 -0000	1.271.2.1
+++ final.c	20 Nov 2003 10:24:13 -0000
@@ -170,8 +170,8 @@
 char regs_ever_live[FIRST_PSEUDO_REGISTER];
 
 /* Nonzero means current function must be given a frame pointer.
-   Set in stmt.c if anything is allocated on the stack there.
-   Set in reload1.c if anything is allocated on the stack there.  */
+   Initialized in function.c to 0.  Set only in reload1.c as per
+   the needs of the function.  */
 
 int frame_pointer_needed;
 
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.366.2.6
diff -u -r1.366.2.6 reload1.c
--- reload1.c	7 Jun 2003 05:30:09 -0000	1.366.2.6
+++ reload1.c	20 Nov 2003 10:24:40 -0000
@@ -1291,6 +1291,14 @@
      by this, so unshare everything here.  */
   unshare_all_rtl_again (first);
 
+#ifdef STACK_BOUNDARY
+  /* init_emit has set the alignment of the hard frame pointer
+     to STACK_BOUNDARY.  It is very likely no longer valid if
+     the hard frame pointer was used for register allocation.  */
+  if (!frame_pointer_needed)
+    REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
+#endif
+
   return failure;
 }
 
typedef unsigned char u_int8_t;
typedef signed char int8_t;
typedef unsigned short u_int16_t;
typedef signed short int16_t;
typedef unsigned int u_int32_t;
typedef signed int int32_t;

static __inline__ __attribute__((always_inline)) __const__ u_int16_t __fswab16(u_int16_t x)
{
        __asm__("xchgb %b0,%h0"
                : "=q" (x)
                : "0" (x));
                return x;
}

typedef struct my_snd_pcm_channel_area {
        void *addr;
        unsigned int first;
        unsigned int step;
} my_snd_pcm_channel_area_t;

typedef struct my_snd_pcm_plugin_channel {
        void *aptr;
        my_snd_pcm_channel_area_t area;
        unsigned int enabled:1;
        unsigned int wanted:1;
} my_snd_pcm_plugin_channel_t;

typedef struct my_snd_pcm_plugin_format {
        int format;
        unsigned int rate;
        unsigned int channels;
} my_snd_pcm_plugin_format_t;

struct my_snd_pcm_plugin {
        my_snd_pcm_plugin_format_t src_format;
        my_snd_pcm_plugin_format_t dst_format;
        char extra_data[0];
};

typedef struct {
        signed short last_S1;
        signed short last_S2;
} rate_channel_t;

typedef struct rate_private_data {
        unsigned int pitch;
        unsigned int pos;
        int get, put;
        rate_channel_t channels[0];
} rate_t;

static void resample_expand(struct my_snd_pcm_plugin *plugin,
                            const my_snd_pcm_plugin_channel_t *src_channels,
                            my_snd_pcm_plugin_channel_t *dst_channels,
                            int src_frames, int dst_frames)
{
        unsigned int pos = 0;
        signed int val;
        signed short S1, S2;
        char *src, *dst;
        unsigned int channel;
        int src_step, dst_step;
        int src_frames1, dst_frames1;
        rate_t *data = (rate_t *)plugin->extra_data;
        rate_channel_t *rchannels = data->channels;

static void *get_s16_labels[4 * 2 * 2] = {
        &&get_s16_xxx1_xx10,
        &&get_s16_xxx1_xx90,
        &&get_s16_xxx1_xx10,
        &&get_s16_xxx1_xx90,
        &&get_s16_xx12_xx12,
        &&get_s16_xx12_xx92,
        &&get_s16_xx12_xx21,
        &&get_s16_xx12_xxA1,
        &&get_s16_x123_xx12,
        &&get_s16_x123_xx92,
        &&get_s16_123x_xx32,
        &&get_s16_123x_xxB2,
        &&get_s16_1234_xx12,
        &&get_s16_1234_xx92,
        &&get_s16_1234_xx43,
        &&get_s16_1234_xxC3,
};

static void *put_s16_labels[4 * 2 * 2] = {
        &&put_s16_xx12_xxx1,
        &&put_s16_xx12_xxx9,
        &&put_s16_xx12_xxx1,
        &&put_s16_xx12_xxx9,
        &&put_s16_xx12_xx12,
        &&put_s16_xx12_xx92,
        &&put_s16_xx12_xx21,
        &&put_s16_xx12_xx29,
        &&put_s16_xx12_x120,
        &&put_s16_xx12_x920,
        &&put_s16_xx12_021x,
        &&put_s16_xx12_029x,
        &&put_s16_xx12_1200,
        &&put_s16_xx12_9200,
        &&put_s16_xx12_0021,
        &&put_s16_xx12_0029,
};

        void *get = get_s16_labels[data->get];
        void *put = put_s16_labels[data->put];
        signed short sample = 0;

        for (channel = 0; channel < plugin->src_format.channels; channel++) {
                pos = data->pos;
                S1 = rchannels->last_S1;
                S2 = rchannels->last_S2;

                if (!src_channels[channel].enabled) {
                        if (dst_channels[channel].wanted)
                                snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames,  plugin->dst_format.format);
                        dst_channels[channel].enabled = 0;
                        continue;
                }

                dst_channels[channel].enabled = 1;
                src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
                dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
                src_step = src_channels[channel].area.step / 8;
                dst_step = dst_channels[channel].area.step / 8;
                while (dst_frames1-- > 0) {
                        if (pos & ~((1<<11)-1)) {
                                if (src_frames1-- > 0) {
                                        goto *get;

while(0) {
get_s16_xxx1_xx10: sample = (u_int16_t)(*(u_int8_t*)(src)) << 8; goto after_get;
get_s16_xxx1_xx90: sample = (u_int16_t)((*(u_int8_t*)(src)) ^ 0x80) << 8; goto after_get;
get_s16_xx12_xx12: sample = (*(u_int16_t*)(src)); goto after_get;
get_s16_xx12_xx92: goto after_get;
get_s16_xx12_xx21: goto after_get;
get_s16_xx12_xxA1: goto after_get;
get_s16_x123_xx12: sample = (*(u_int32_t*)(src)) >> 8; goto after_get;
get_s16_x123_xx92: sample = ((*(u_int32_t*)(src)) >> 8) ^ 0x8000; goto after_get;
get_s16_123x_xx32: sample = (*(u_int32_t*)(src)) >> 16; goto after_get;
get_s16_123x_xxB2: sample = (__builtin_constant_p((u_int16_t)(((*(u_int32_t*)(src)) >> 8) ^ 0x8000)) ? ({ u_int16_t __x = ((((*(u_int32_t*)(src)) >> 8) ^ 0x8000)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((((*(u_int32_t*)(src)) >> 8) ^ 0x8000))); goto after_get;
get_s16_1234_xx12: sample = (*(u_int32_t*)(src)) >> 16; goto after_get;
get_s16_1234_xx92: sample = ((*(u_int32_t*)(src)) >> 16) ^ 0x8000; goto after_get;
get_s16_1234_xx43: goto after_get;
get_s16_1234_xxC3: goto after_get;
}

                                after_get:
                                        S2 = sample;
                                        src += src_step;
                                }
                        }

                        val = S1 + ((S2 - S1) * (signed int)pos) / (1<<11);
                        sample = val;
                        goto *put;

while (0) {
put_s16_xx12_xxx1: (*(u_int8_t*)(dst)) = sample >> 8; goto after_put;
put_s16_xx12_xxx9: (*(u_int8_t*)(dst)) = (sample >> 8) ^ 0x80; goto after_put;
put_s16_xx12_xx12: (*(u_int16_t*)(dst)) = sample; goto after_put;
put_s16_xx12_xx92: (*(u_int16_t*)(dst)) = sample ^ 0x8000; goto after_put;
put_s16_xx12_xx21: (*(u_int16_t*)(dst)) = (__builtin_constant_p((u_int16_t)(sample)) ? ({ u_int16_t __x = ((sample)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((sample)));  goto after_put;
put_s16_xx12_xx29: (*(u_int16_t*)(dst)) = (__builtin_constant_p((u_int16_t)(sample)) ? ({ u_int16_t __x = ((sample)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((sample))) ^ 0x80; goto after_put;
put_s16_xx12_x120: (*(u_int32_t*)(dst)) = (u_int32_t)sample << 8; goto after_put;
put_s16_xx12_x920: (*(u_int32_t*)(dst)) = (u_int32_t)(sample ^ 0x8000) << 8; goto after_put;
put_s16_xx12_021x: (*(u_int32_t*)(dst)) = (u_int32_t)(__builtin_constant_p((u_int16_t)(sample)) ? ({ u_int16_t __x = ((sample)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((sample))) << 8; goto after_put;
put_s16_xx12_029x: (*(u_int32_t*)(dst)) = (u_int32_t)((__builtin_constant_p((u_int16_t)(sample)) ? ({ u_int16_t __x = ((sample)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((sample))) ^ 0x80) << 8; goto after_put;
put_s16_xx12_1200: (*(u_int32_t*)(dst)) = (u_int32_t)sample << 16; goto after_put;
put_s16_xx12_9200: (*(u_int32_t*)(dst)) = (u_int32_t)(sample ^ 0x8000) << 16; goto after_put;
put_s16_xx12_0021: (*(u_int32_t*)(dst)) = (u_int32_t)(__builtin_constant_p((u_int16_t)(sample)) ? ({ u_int16_t __x = ((sample)); ((u_int16_t)( (((u_int16_t)(__x) & (u_int16_t)0x00ffU) << 8) | (((u_int16_t)(__x) & (u_int16_t)0xff00U) >> 8) )); }) : __fswab16((sample))); goto after_put;
put_s16_xx12_0029: goto after_put;
}

                after_put:
                        dst += dst_step;
                        pos += data->pitch;
                }
                rchannels->last_S1 = S1;
                rchannels++;
        }
        data->pos = pos;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]