[LLVMdev] i1 promotion issue (again)

Duncan Sands
Fri, 12 Dec 2008 20:35:49 -0000

Hi Scott,

> Problem: LegalizeTypes promotes i1 to i8 via an i32 setcc, i.e., the
> generated type legalization is:
>
> 	(i8:truncate (i32:setcc i32:lhs, i32:rhs, ch:cond))
>
> How do I keep DAGTypeLegalizer::PromoteIntRes_SETCC() from inserting
> the truncate without blowing all other type promotion out of the
> water (having everything promoted up to i32 as a consequence)? Would
> it be permissible to add a virtual function to TargetLowering such
> that the target can effectively say, "Really, the setcc is legal, no
> need to truncate!"?

since CellSPU says that i1 should be promoted into an i8, that's
exactly what's being done.  The SetCC promotion logic doesn't know
who's using the value - it can't just change the type randomly: i8
is expected by users, as far as it knows, so it must produce an i8.

The situation is quite different for users of values though.  It sounds
to me like the real question is: why is the brcond condition being promoted
from i1 to i8 and not to i32?  When promoting an operand you can change
the type promoted to without any problem.  I've got nothing against having
the brcond logic call getSetCCResultType to find out what type should be
used.  The only problem is that getSetCCResultType takes an argument, and
what should be passed?  You could pass i1, but on CellSPU it would pass
i1 right back :)  There's a solution to that: modify getSetCCResultType
so it doesn't take an argument.  After all, only one platform uses it:
CellSPU ;)

> The alternative is to do fairly deep inspection of brconds to
> eliminate the truncate, which eventually gets expanded into:
>
> 	(i8:sext_in_reg (i8:truncate (i32:setcc ...)))

I think there's no problem: you just do a zext of the i8 value, giving:
zext to i32 of truncate to i8 of i32 <- known to be zero extended
from i1.  The DAG combiner should drop all the extensions and truncations.

Ciao,

Duncan.