https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83133

            Bug ID: 83133
           Summary: Superflous x86 test instructions in generated
                    assembly.
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: maxim.yegorushkin at gmail dot com
  Target Milestone: ---

Consider the following code:

    int negative(int);
    int positive(int);
    int nonnegative(int);
    int nonpositive(int);

    int f(int a, int b) {
        int diff = a - b;
        if(diff < 0)
            return negative(diff);
        else
            return nonnegative(diff);
    }

    int g(int a, int b) {
        int diff = a - b;
        if(diff > 0)
            return positive(diff);
        else
            return nonpositive(diff);
    }

And the assembly generated with `-O3 -march=broadwell`:

    f(int, int):
      subl %esi, %edi
      js .L4
      jmp nonnegative(int)
    .L4:
      jmp negative(int)

    g(int, int):
      subl %esi, %edi
      testl %edi, %edi <---- unnecessary instruction.
      jle .L6
      jmp positive(int)
    .L6:
      jmp nonpositive(int)

g function assembly contains a superflous test instruction. It should not
generate that instruction, since sub instruction already sets all the required
flags. I first discovered this issue in gcc-4.9.2 and it is still there in
gcc-7.2.0.

Double-checked it with clang-5.0.0 and it seem to generate optimal assembly:

    f(int, int): # @f(int, int)
      subl %esi, %edi
      js .LBB0_1
      jmp nonnegative(int) # TAILCALL
    .LBB0_1:
      jmp negative(int) # TAILCALL

    g(int, int): # @g(int, int)
      subl %esi, %edi
      jle .LBB1_2
      jmp positive(int) # TAILCALL
    .LBB1_2:
      jmp nonpositive(int) # TAILCALL

Reply via email to