http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53533

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Target|                            |x86_64-*-*
             Status|WAITING                     |NEW
      Known to work|                            |4.6.3
           Keywords|                            |missed-optimization
          Component|middle-end                  |rtl-optimization
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |uros at gcc dot gnu.org
            Summary|[4.7 regression] loop       |[4.7/4.8 regression]
                   |unrolling as measured by    |vectorization causes loop
                   |Adobe's C++Benchmark is     |unrolling test slowdown as
                   |twice as slow versus        |measured by Adobe's
                   |4.4-4.6                     |C++Benchmark
      Known to fail|                            |4.7.1, 4.8.0
           Severity|major                       |normal

--- Comment #6 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-06-12 
09:54:02 UTC ---
Ok, it seems to me that this has template-metaprogramming loop unrolling.  With
GCC 4.7 we unroll and vectorize all loops, for example unroll factor 8 looks
like

<bb 50>:
  # vect_var_.941_3474 = PHI <vect_var_.941_3472(50), {0, 0, 0, 0}(64)>
  # vect_var_.941_3473 = PHI <vect_var_.941_3471(50), {0, 0, 0, 0}(64)>
  # ivtmp.1325_970 = PHI <ivtmp.1325_812(50), ivtmp.1325_813(64)>
  D.9934_819 = (void *) ivtmp.1325_970;
  vect_var_.918_323 = MEM[base: D.9934_819, offset: 0B];
  vect_var_.919_325 = MEM[base: D.9934_819, offset: 16B];
  vect_var_.920_328 = vect_var_.918_323 + { 12345, 12345, 12345, 12345 };
  vect_var_.920_330 = vect_var_.919_325 + { 12345, 12345, 12345, 12345 };
  vect_var_.923_480 = vect_var_.920_328 * { 914237, 914237, 914237, 914237 };
  vect_var_.923_895 = vect_var_.920_330 * { 914237, 914237, 914237, 914237 };
  vect_var_.926_231 = vect_var_.923_480 + { 12332, 12332, 12332, 12332 };
  vect_var_.926_232 = vect_var_.923_895 + { 12332, 12332, 12332, 12332 };
  vect_var_.929_235 = vect_var_.926_231 * { 914237, 914237, 914237, 914237 };
  vect_var_.929_236 = vect_var_.926_232 * { 914237, 914237, 914237, 914237 };
  vect_var_.932_239 = vect_var_.929_235 + { 12332, 12332, 12332, 12332 };
  vect_var_.932_240 = vect_var_.929_236 + { 12332, 12332, 12332, 12332 };
  vect_var_.935_113 = vect_var_.932_239 * { 914237, 914237, 914237, 914237 };
  vect_var_.935_247 = vect_var_.932_240 * { 914237, 914237, 914237, 914237 };
  vect_var_.938_582 = vect_var_.935_113 + { -13, -13, -13, -13 };
  vect_var_.938_839 = vect_var_.935_247 + { -13, -13, -13, -13 };
  vect_var_.941_3472 = vect_var_.938_582 + vect_var_.941_3474;
  vect_var_.941_3471 = vect_var_.938_839 + vect_var_.941_3473;
  ivtmp.1325_812 = ivtmp.1325_970 + 32;
  if (ivtmp.1325_812 != D.9937_388)
    goto <bb 50>;
  else
    goto <bb 51>;

<bb 51>:
  # vect_var_.941_3468 = PHI <vect_var_.941_3472(50)>
  # vect_var_.941_3467 = PHI <vect_var_.941_3471(50)>
  vect_var_.945_3466 = vect_var_.941_3468 + vect_var_.941_3467;
  vect_var_.946_3465 = vect_var_.945_3466 v>> 64;
  vect_var_.946_3464 = vect_var_.946_3465 + vect_var_.945_3466;
  vect_var_.946_3463 = vect_var_.946_3464 v>> 32;
  vect_var_.946_3462 = vect_var_.946_3463 + vect_var_.946_3464;
  stmp_var_.944_3461 = BIT_FIELD_REF <vect_var_.946_3462, 32, 0>;
  init_value.7_795 = init_value;
  D.8606_796 = (int) init_value.7_795;
  D.8600_797 = D.8606_796 + 12345;
  D.8599_798 = D.8600_797 * 914237;
  D.8602_799 = D.8599_798 + 12332;
  D.8601_800 = D.8602_799 * 914237;
  D.8604_801 = D.8601_800 + 12332;
  D.8603_802 = D.8604_801 * 914237;
  D.8605_803 = D.8603_802 + -13;
  temp_804 = D.8605_803 * 8000;
  if (temp_804 != stmp_var_.944_3461)
    goto <bb 52>;
  else
    goto <bb 53>;


With GCC 4.6 OTOH the above loop is not vectorized, only the (slow) not
unrolled loop is.

<bb 49>:
  # result_622 = PHI <result_704(49), 0(63)>
  # ivtmp.852_1026 = PHI <ivtmp.852_842(49), ivtmp.852_844(63)>
  D.9283_3302 = (void *) ivtmp.852_1026;
  temp_801 = MEM[base: D.9283_3302, offset: 0B];
  D.8366_802 = temp_801 + 12345;
  D.8365_803 = D.8366_802 * 914237;
  D.8368_804 = D.8365_803 + 12332;
  D.8367_805 = D.8368_804 * 914237;
  D.8370_806 = D.8367_805 + 12332;
  D.8369_807 = D.8370_806 * 914237;
  temp_808 = D.8369_807 + -13;
  result_810 = temp_808 + result_622;
  temp_815 = MEM[base: D.9283_3302, offset: 4B];
  D.8381_816 = temp_815 + 12345;
  D.8382_817 = D.8381_816 * 914237;
  D.8378_818 = D.8382_817 + 12332;
  D.8379_819 = D.8378_818 * 914237;
  D.8376_820 = D.8379_819 + 12332;
  D.8377_821 = D.8376_820 * 914237;
  temp_822 = D.8377_821 + -13;
  result_824 = result_810 + temp_822;
  temp_788 = MEM[base: D.9283_3302, offset: 8B];
  D.8351_789 = temp_788 + 12345;
  D.8352_790 = D.8351_789 * 914237;
  D.8348_791 = D.8352_790 + 12332;
  D.8349_792 = D.8348_791 * 914237;
  D.8346_793 = D.8349_792 + 12332;
  D.8347_794 = D.8346_793 * 914237;
  temp_795 = D.8347_794 + -13;
  result_797 = temp_795 + result_824;
  temp_774 = MEM[base: D.9283_3302, offset: 12B];
  D.8333_775 = temp_774 + 12345;
  D.8334_776 = D.8333_775 * 914237;
  D.8330_777 = D.8334_776 + 12332;
  D.8331_778 = D.8330_777 * 914237;
  D.8328_779 = D.8331_778 + 12332;
  D.8329_780 = D.8328_779 * 914237;
  temp_781 = D.8329_780 + -13;
  result_783 = temp_781 + result_797;
  temp_760 = MEM[base: D.9283_3302, offset: 16B];
  D.8315_761 = temp_760 + 12345;
  D.8316_762 = D.8315_761 * 914237;
  D.8312_763 = D.8316_762 + 12332;
  D.8313_764 = D.8312_763 * 914237;
  D.8310_765 = D.8313_764 + 12332;
  D.8311_766 = D.8310_765 * 914237;
  temp_767 = D.8311_766 + -13;
  result_769 = temp_767 + result_783;
  temp_746 = MEM[base: D.9283_3302, offset: 20B];
  D.8297_747 = temp_746 + 12345;
  D.8298_748 = D.8297_747 * 914237;
  D.8294_749 = D.8298_748 + 12332;
  D.8295_750 = D.8294_749 * 914237;
  D.8292_751 = D.8295_750 + 12332;
  D.8293_752 = D.8292_751 * 914237;
  temp_753 = D.8293_752 + -13;
  result_755 = temp_753 + result_769;
  temp_732 = MEM[base: D.9283_3302, offset: 24B];
  D.8279_733 = temp_732 + 12345;
  D.8280_734 = D.8279_733 * 914237;
  D.8276_735 = D.8280_734 + 12332;
  D.8277_736 = D.8276_735 * 914237;
  D.8274_737 = D.8277_736 + 12332;
  D.8275_738 = D.8274_737 * 914237;
  temp_739 = D.8275_738 + -13;
  result_741 = temp_739 + result_755;
  temp_695 = MEM[base: D.9283_3302, offset: 28B];
  D.8246_696 = temp_695 + 12345;
  D.8245_697 = D.8246_696 * 914237;
  D.8248_698 = D.8245_697 + 12332;
  D.8247_699 = D.8248_698 * 914237;
  D.8250_700 = D.8247_699 + 12332;
  D.8249_701 = D.8250_700 * 914237;
  temp_702 = D.8249_701 + -13;
  result_704 = temp_702 + result_741;
  ivtmp.852_842 = ivtmp.852_1026 + 32;
  if (ivtmp.852_842 != D.9292_3369)
    goto <bb 49>;
  else
    goto <bb 50>;

<bb 50>:
  # result_3198 = PHI <result_704(49)>
  init_value.7_825 = init_value;
  D.8393_826 = (int) init_value.7_825;
  D.8387_827 = D.8393_826 + 12345;
  D.8386_828 = D.8387_827 * 914237;
  D.8389_829 = D.8386_828 + 12332;
  D.8388_830 = D.8389_829 * 914237;
  D.8391_831 = D.8388_830 + 12332;
  D.8390_832 = D.8391_831 * 914237;
  D.8392_833 = D.8390_832 + -13;
  temp_834 = D.8392_833 * 8000;
  if (temp_834 != result_3198)
    goto <bb 51>;
  else
    goto <bb 52>;

With -fno-tree-vectorize the performance is the same.  It seems that
vectorization is not profitable here for some reason.  Same behavior
can be observed with GCC 4.8.

I used the preprocessed source for 4.7 from the ZIP file.

The code generated is odd at least, the inner loop looks like

        movdqa  .LC6(%rip), %xmm3
        xorl    %ebx, %ebx
        movdqa  .LC7(%rip), %xmm0
        movdqa  .LC8(%rip), %xmm1
        movdqa  .LC9(%rip), %xmm2
        .p2align 4,,10
        .p2align 3
.L51:
        pxor    %xmm6, %xmm6
        movl    $data32, %eax
        movdqa  %xmm6, %xmm7
        .p2align 4,,10
        .p2align 3
.L53:
        movdqa  (%rax), %xmm4
        movdqa  %xmm0, %xmm8
        paddd   %xmm3, %xmm4
        movdqa  %xmm4, %xmm5
        psrldq  $4, %xmm4
        psrldq  $4, %xmm8
        pmuludq %xmm8, %xmm4
        pshufd  $8, %xmm4, %xmm4
        pmuludq %xmm0, %xmm5
        pshufd  $8, %xmm5, %xmm5
        movdqa  %xmm0, %xmm8
        psrldq  $4, %xmm8
        punpckldq       %xmm4, %xmm5
        paddd   %xmm1, %xmm5
        movdqa  %xmm5, %xmm4
        psrldq  $4, %xmm5
        pmuludq %xmm8, %xmm5
        pshufd  $8, %xmm5, %xmm5
        pmuludq %xmm0, %xmm4
        pshufd  $8, %xmm4, %xmm4
        punpckldq       %xmm5, %xmm4
        movdqa  %xmm0, %xmm5
        paddd   %xmm1, %xmm4
        movdqa  %xmm4, %xmm8
        psrldq  $4, %xmm5
        psrldq  $4, %xmm4
        pmuludq %xmm4, %xmm5
        pshufd  $8, %xmm5, %xmm5
        pmuludq %xmm0, %xmm8
        pshufd  $8, %xmm8, %xmm4
        movdqa  %xmm0, %xmm8
        psrldq  $4, %xmm8
        punpckldq       %xmm5, %xmm4
        paddd   %xmm2, %xmm4
        paddd   %xmm4, %xmm7
        movdqa  16(%rax), %xmm4
        addq    $32, %rax
        paddd   %xmm3, %xmm4
        movdqa  %xmm4, %xmm5
        psrldq  $4, %xmm4
        pmuludq %xmm8, %xmm4
        pshufd  $8, %xmm4, %xmm4
        movdqa  %xmm0, %xmm8
        pmuludq %xmm0, %xmm5
        pshufd  $8, %xmm5, %xmm5
        cmpq    $data32+32000, %rax
        psrldq  $4, %xmm8
        punpckldq       %xmm4, %xmm5
        paddd   %xmm1, %xmm5
        movdqa  %xmm5, %xmm4
        psrldq  $4, %xmm5
        pmuludq %xmm8, %xmm5
        pshufd  $8, %xmm5, %xmm5
        pmuludq %xmm0, %xmm4
        pshufd  $8, %xmm4, %xmm4
        punpckldq       %xmm5, %xmm4
        movdqa  %xmm0, %xmm5
        paddd   %xmm1, %xmm4
        movdqa  %xmm4, %xmm8
        psrldq  $4, %xmm5
        psrldq  $4, %xmm4
        pmuludq %xmm4, %xmm5
        pshufd  $8, %xmm5, %xmm5
        pmuludq %xmm0, %xmm8
        pshufd  $8, %xmm8, %xmm4
        punpckldq       %xmm5, %xmm4
        paddd   %xmm2, %xmm4
        paddd   %xmm4, %xmm6
        jne     .L53

which means we expand the multiplications with the constants in an odd way.

Reply via email to