[llvm-bugs] [Bug 39569] New: Backend produces sub-optimal code for switch conditions with illegal types

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Nov 6 10:01:23 PST 2018


            Bug ID: 39569
           Summary: Backend produces sub-optimal code for switch
                    conditions with illegal types
           Product: libraries
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: denis.bakhvalov at intel.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 21094
  --> https://bugs.llvm.org/attachment.cgi?id=21094&action=edit

This bug is forked from https://bugs.llvm.org/show_bug.cgi?id=29009.

If we have illegal types for switch conditions:

  %trunc = trunc i32 %3 to i3
  switch i3 %trunc, label %11 [
    i3 0, label %4
    i3 3, label %5
    i3 -2, label %6
    i3 2, label %7
    i3 -4, label %8
    i3 -3, label %9

backend will generate sub-optimal code (notice redundant MOV's and AND's):

$ llc 1.ll

        movl    %eax, %edx
        andb    $7, %dl
        movl    $6, %ecx
        cmpb    $7, %dl
        je      .LBB0_10
# %bb.3:                                
        movl    %eax, %edx
        andl    $7, %edx
        jmpq    *.LJTI0_0(,%rdx,8)

Full reproducer attached.

Comments by Craig Topper:

CodeGenPrepare inserts a zext to turn the i3 back into i8. This leaves us with
a trunc+zext pair. This non-canonical IR as far as InstCombine would say.
Canonical IR would be trunc to i8 followed by an and with 7.

Then SelectionDAGBuilder inserts a zext i8 to i64 for the jump table lookup.
getNode sees that we have a (i32 (zext (i8 (zext (i3)))) and decides that we
should by pass the i3->i8 zext. So now we have an i3->i64 zext and a i3->i8
zext seprately.

Now DAG combine runs and a setcc optimization runs that sees (setcc (i8 (zext
(i3 trunc)))) and replaces it with (setcc (i3 trunc)). Separately the (i64
(zext (i3 trunc)) pair is turned into a (i64 (and (any_extend (i32)), 7).

Then type legalization runs and rewrites the setcc input to an (i8 (and
(trunc(i3)), 7)).

And that's how we got 2 different ands.

I tried making codegen prepare emit canonical IR so the i3 type would
disappear. But DAGCombiner still seems to prefer turning (zext (and)) into (and
(any_extend)) even when the 'and' has an additional user.

I also tried a patch to force SelectionDAGBuilder to emit the zext for the
jumptable in the basic block with the jump table load instead of in the basic
block with the setcc. That actually produces reasonable code, but I didn't see
much perf change from our benchmark list.

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181106/bbda62ac/attachment.html>

More information about the llvm-bugs mailing list