if I write: int z, x; ... z = (x >= k); -- where k is a constant The compiler always wants to translate this into: z = (x > (k-1)); In general this can often lead to better code (and it does for Mips 16 for sure), except at the boundary condition where k==-32768 Then it creates the literal -32769 which cannot be placed in a simple immediate field. That creates a lot of extra code for Mips 16. I had originally written a pattern for setge when the right operand is a constant. def: Mips16Pat <(setge CPU16Regs:$lhs, immZExt16:$rhs), (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), (LiRxImmX16 1))>; I was able to work around this boundary case by doing the reverse transformation at the boundary. i..e. z = (x > (k-1)) => z = (x >= k) def: Mips16Pat <(setgt CPU16Regs:$lhs, -32769), (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768), (LiRxImmX16 1))>;
sorry;;; original pattern was def: Mips16Pat <(setge CPU16Regs:$lhs, immSExt16:$rhs), (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs), (LiRxImmX16 1))>; (cut and pasted immZExt16:$rhs into example accidentally) On 10/18/2012 08:13 PM, reed kotler wrote:> if I write: > > int z, x; > ... > z = (x >= k); -- where k is a constant > > The compiler always wants to translate this into: > > z = (x > (k-1)); > > In general this can often lead to better code (and it does for Mips 16 > for sure), except at > the boundary condition where k==-32768 > > Then it creates the literal -32769 which cannot be placed in a simple > immediate field. > That creates a lot of extra code for Mips 16. > > I had originally written a pattern for setge when the right operand is a > constant. > > def: Mips16Pat > <(setge CPU16Regs:$lhs, immZExt16:$rhs), > (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), > (LiRxImmX16 1))>; > > I was able to work around this boundary case by doing the reverse > transformation at the boundary. > > i..e. > > z = (x > (k-1)) => z = (x >= k) > > def: Mips16Pat > <(setgt CPU16Regs:$lhs, -32769), > (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768), > (LiRxImmX16 1))>;
This is more an canonicalization than optimization. The canonicalization reduces the number of cases which later optimization phases have to worry about. Targets usually handle the edge cases in lowering phase (e.g. ARM). Evan On Oct 18, 2012, at 8:13 PM, reed kotler <rkotler at mips.com> wrote:> if I write: > > int z, x; > ... > z = (x >= k); -- where k is a constant > > The compiler always wants to translate this into: > > z = (x > (k-1)); > > In general this can often lead to better code (and it does for Mips 16 for sure), except at > the boundary condition where k==-32768 > > Then it creates the literal -32769 which cannot be placed in a simple immediate field. > That creates a lot of extra code for Mips 16. > > I had originally written a pattern for setge when the right operand is a constant. > > def: Mips16Pat > <(setge CPU16Regs:$lhs, immZExt16:$rhs), > (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), > (LiRxImmX16 1))>; > > I was able to work around this boundary case by doing the reverse transformation at the boundary. > > i..e. > > z = (x > (k-1)) => z = (x >= k) > > def: Mips16Pat > <(setgt CPU16Regs:$lhs, -32769), > (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768), > (LiRxImmX16 1))>; > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev