MIPS: comparison modes in conditional branches
Adam Nemet
anemet@sonic.net
Mon Dec 5 07:12:00 GMT 2005
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
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: cmpmodes.diff
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20051205/1eaf33db/attachment.ksh>
More information about the Gcc
mailing list