This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: optimization/7702: gcc-3.2 optimization problem on a DEC alpha under OSF1
- From: Falk Hueffner <falk dot hueffner at student dot uni-tuebingen dot de>
- To: Blair Kelly III <bfkelly at afterlife dot ncsc dot mil>
- Cc: gcc-gnats at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org
- Date: 28 Jan 2003 01:09:40 +0100
- Subject: Re: optimization/7702: gcc-3.2 optimization problem on a DEC alpha under OSF1
- References: <200301272147.QAA16442@gladsheim><87vg0a2pv5.fsf@student.uni-tuebingen.de>
Falk Hueffner <falk.hueffner@student.uni-tuebingen.de> writes:
> Blair Kelly III <bfkelly@afterlife.ncsc.mil> writes:
>
> > > I cannot reproduce this problem with gcc 3.2.2 (Debian prerelease)
> > > on Alpha Linux. I guess it it fixed meanwhile (or it only ocurrs
> > > on OSF1, but that seems unlikely to me).
> >
> > I know (because I just tested) that the problem occurs using
> > gcc-3.2.1 under OSF1. I do not know about gcc-3.2.2. If you tell
> > me where I can get source for a prerelease of gcc-3.2.2, I might be
> > able to test.
>
> I just noticed it is *not* fixed in the gcc 3.2.2 prerelease; I didn't
> notice because it is triggered by -mcpu=ev67 (which is implicit for
> you, since you built on an ev67).
>
> However, I can't reproduce it with CVS head (gcc version 3.4 20030116
> (experimental)). I'll try to investigate it a bit, maybe I can find
> out whether it was fixed or is just hidden.
Here's some analysis. I used this slightly stripped source:
void bar(int n) {
int i;
int *r = malloc(5 * sizeof(int));
r[0] = 100;
r[1] = 101;
for (i = 0; i < n; i++) {
if (i < 0) {
puts("?");
r[i] = 23;
} else {
if (i == 0) {
r[i] = 23;
printf("r[%d] = %d\n", i, r[i]);
} else {
r[i] = 42;
}
}
}
fprintf(stdout, "r[0] = %d\n", r[0]);
fprintf(stdout, "r[1] = %d\n", r[1]);
}
gcc decides to load the two 23s into FP registers:
21.greg:
(insn 189 231 232 (set (reg:SI 35 $f3 [81])
(mem/u/f:SI (reg:DI 1 $1) [3 S4 A32])) 229 {*movsi_fix} (nil)
(expr_list:REG_EQUIV (const_int 23 [0x17])
(nil)))
[...]
(insn 192 233 195 (set (reg:SI 34 $f2 [85])
(mem/u/f:SI (reg:DI 1 $1) [3 S4 A32])) 229 {*movsi_fix} (nil)
(expr_list:REG_EQUIV (const_int 23 [0x17])
(nil)))
[...]
(insn 74 163 91 (set (mem:SI (reg/v/f:DI 11 $11 [71]) [3 S4 A32])
(reg:SI 34 $f2 [85])) 229 {*movsi_fix} (insn_list:REG_DEP_ANTI 64 (insn_list:REG_DEP_ANTI 41 (nil)))
(nil))
Then, in 22.postreload, it decides to sign extend one from the other:
(insn 192 233 195 (set (reg:DI 34 $f2 [85])
(sign_extend:DI (reg:SI 35 $f3 [81]))) 1 {*extendsidi2_fix} (nil)
(expr_list:REG_EQUIV (const_int 23 [0x17])
(nil)))
but the store remains SI:
(insn 74 163 91 (set (mem:SI (reg/v/f:DI 11 $11 [71]) [3 S4 A32])
(reg:SI 34 $f2 [85])) 229 {*movsi_fix} (insn_list:REG_DEP_ANTI 64 (insn_list:REG_DEP_ANTI 41 (nil)))
(nil))
That doesn't work with FP registers. The sign extension will generate
cvtlq, which is a repositioning of 32 bits of the operand (with sign
extension). Storing it in SImode will then write 0.
I have no clue what to do about this. I hope somebody more
knowledgeable will look at it...
--
Falk