[Bug c++/78046] New: Unnecessary setne/testb instructions with temporary int brace-initialized in if statement

jamespharvey20 at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Oct 20 04:20:00 GMT 2016


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

            Bug ID: 78046
           Summary: Unnecessary setne/testb instructions with temporary
                    int brace-initialized in if statement
           Product: gcc
           Version: 6.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jamespharvey20 at gmail dot com
  Target Milestone: ---

A two-variable comparison

   int main() {
      int i{0};
      int j{0};
      if(i != j) {
      }
   }

And a one-variable comparison to a temporary

   int main() {
      int i{0};
      if(i != int{0}) {
      }
   }

Generate fairly similar assembly, as expected, using gcc -Wa,-adhln -g
source.cpp -O0 > source.s

The two-variable version creates assembly for the declaration and if statement
of:

   movl $0, -8(%rbp)
   movl -4(%rbp), %eax
   cmpl -8(&rbp), %eax

The temporary version generates assembly for the if statement and temporary of:

   movl $0, %eax
   cmpl -4(%rbp), %eax
   setne %al
   testb %al, %al

So, at least without optimization, they are (and should be) different in terms
of a stack variable vs a register temporary.

But, why I'm writing is the `setne` and `testb` instructions that appear there.

FWIW, clang assembles with the same difference for stack variable vs a register
temporary, but does NOT create add the `setne` and `testb` instructions.

Additionally, changing from using an `int` to a class, there aren't extra
`setne` and `testb` instructions.  The assembly of stack vs register variables
is effectively identical, just the order of two sets of `leaq` instructions is
reversed, as in:

   class foo {
   public:
      foo(int _x) : x{_x} { }
      int x;
      bool operator!=(const foo& other) { return x != other.x; }
   };

   int main() {
      foo i{0};
      if(i != foo{0}) {
      }
   }


More information about the Gcc-bugs mailing list