[llvm-dev] Dealing with information loss for widened integer operations at ISel time

Alex Bradbury via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 3 04:01:02 PST 2019


On Fri, 14 Dec 2018 at 21:08, Friedman, Eli <efriedma at codeaurora.org> wrote:
>
> On 12/14/2018 3:43 AM, Alex Bradbury wrote:
> > It only matters when it allows you to avoid an unnecessary sext/zext
> > of the input operands. Consider the following input:
> >
> > define i32 @aext_divuw_aext_aext(i32 %a, i32 %b) nounwind {
> >    %1 = udiv i32 %a, %b
> >    ret i32 %1
> > }
> >
> > This pattern won't match:
> > def : Pat<(sext_inreg (udiv (zexti32 GPR:$rs1), (zexti32 GPR:$rs2)), i32),
> >            (DIVUW GPR:$rs1, GPR:$rs2)>;
> >
> > This pattern would match but is incorrect in the general case (e.g. if
> > rs1 is 0xffffffff and rs2 is 0x1, the result will be sign-extended).:
> > def : Pat<(udiv (zexti32 GPR:$rs1), (zexti32 GPR:$rs2)),
> >            (DIVUW GPR:$rs1, GPR:$rs2)>;
> >
> > So this function would generate:
> > slli a1, a1, 32
> > srli a1, a1, 32
> > slli a0, a0, 32
> > srli a0, a0, 32
> > divu a0, a0, a1
> > ret
> >
> > Rather than a simple divuw. Obviously we can argue whether such cases
> > are likely to occur in real-world code (certainly this specific case
> > of aext function args/returns isn't going to happen for
> > clang-generated code), but it makes me uncomfortable that we can't
> > easily make the best codegen decision for such a straight-forward
> > input.
>
> Okay, that makes sense.
>
> I think you only end up with an explicit "zext" like this for unsigned
> division and unsigned right shift with a variable amount?  And for
> signed division, I guess you end up with an analogous problem with sext
> (since -2^31/-1 needs to produce 2^31, not -2^31).

Hi Eli, I've posted https://reviews.llvm.org/D56264 and updated
https://reviews.llvm.org/D53230 to add patterns for SLLW/SRLW/SRAW and
the RV64M instructions. Rather than introducing custom SelectionDAG
nodes, I've added DAG combines for the shifts to add assertzext i5 and
additionally added a DAG combine to convert an ANY_EXTEND to a
SIGN_EXTEND when this is likely to allow a *W instruction to be
selected (can't leave this to ISel time, because the any_extend will
be never reach instruction selection).

I'd really welcome review and any extra input on these patches.

Thanks,

Alex


More information about the llvm-dev mailing list