This is the mail archive of the gcc@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] | |
Hi,
I am trying to understand why the MIPS backend's handling of
comparison modes seems to be different from what rtl.texi says:
The mode of the comparison operation is independent of the mode
of the data being compared. If the comparison operation is being tested
(e.g., the first operand of an @code{if_then_else}), the mode must be
@code{VOIDmode}.
In the MIPS backend conditional branches based on integer comparisons
are valid only if the mode of the comparison matches the mode of the
operands, e.g. in 64-bit mode (if_then_else (eq:DI (reg:DI 1)
(const_int 0)) ...).
This is relevant because combine could optimize this:
(set (reg:DI 2) (and:DI (reg:DI 1) (const_int 1)))
(set (reg:SI 3) (truncate:SI (reg:DI 2)))
(set (pc) (if_then_else (eq:SI (reg:SI 3) (const_int 0)) ...))
into this:
(set (reg:DI 2) (and:DI (regDI 1) (const_int 1)))
(set (pc) (if_then_else (eq:SI (reg:DI 2) (const_int 0)) ...))
I think this is a valid transformation on MIPS64 too. In fact I
believe that as long as we compare valid SImode or DImode values the
64-bit comparison should work fine.
If I remove the comparison modes from the conditional branch patterns
regression testing on mips64-elf does not show any problem (diff is
attached for reference). When I however compare the assembly output
it is clear that some of the changes are incorrect. This is
a simplified testcase illustrating the problem:
f (long long a)
{
if ((a & 0xffffffff) != 0)
abort ();
}
long long a = 0x1234567800000000LL;
main ()
{
f (a);
}
What happens is that combine.c:simplify_comparison <AND> noticing the
zero-extension transforms this:
(ne:DI (and:DI (reg:DI 4) (const_int 0xffffffff)) (const_int 0))
into this:
(ne:DI (reg:SI 4) (const_int 0))
And now we do allow comparison like this in conditional branches.
On targets where DI->SI mode-switch is not a nop I think the
transformation in simplify_comparison is incorrect. We need an
explicit truncate here to enforce valid SI values:
(ne:DI (truncate:SI (reg:DI 4)) (const_int 0)).
Now if I am correct and this last thing is really a bug then the
obvious question is whether it has anything to do with the more
restrictive form for conditional branches on MIPS64? And of course if
I fix it then whether it would be OK to lift the mode restrictions in
the conditional branch patterns.
Thanks,
Adam
Attachment:
cmpmodes.diff
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |