wide-int testing results

Richard Sandiford rdsandiford@googlemail.com
Thu Nov 7 17:58:00 GMT 2013


I wanted to make sure that each backend still builds with wide-int and that
there weren't any unexplained changes in assembly output.  I arbitrarily
picked one target for each CPU:

    aarch64-linux-gnueabi alpha-linux-gnu arc-elf arm-linux-gnueabi
    avr-rtems bfin-elf c6x-elf cr16-elf cris-elf epiphany-elf
    fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
    lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
    microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
    msp430-elf nds32le-elf hppa64-hp-hpux11.23 pdp11 picochip-elf
    powerpc-linux-gnu powerpc-eabispe rl78-elf rx-elf s390-linux-gnu
    score-elf sh-linux-gnu sparc-linux-gnu spu-elf tilegx-elf
    tilepro-elf xstormy16-elf v850-elf vax-netbsdelf xtensa-elf
    x86_64-darwin

and built gcc and g++ from both the merge point and the wide-int branch.
The branch included the patches I've posted and a local change
to put CONST_WIDE_INT at the end of rtl.def (just for comparison,
as mentioned before).  I then compiled gcc.c-torture, gcc.dg and g++.dg
at -O2 and compared the asm output.  This obviously isn't a very strong
test, since none of the libraries are built, and since some of the test
cases rely on system headers, but it should at least be better than nothing.

pdp11 and picochip-elf don't build on mainline due to:

   gcc/target-def.h:69:34: error: ‘default_stabs_asm_out_destructor’ was not declared in this scope
   #   define TARGET_ASM_DESTRUCTOR default_stabs_asm_out_destructor

Both the merge point and the branch built the other targets and there were
no new warnings on the branch.  The only asm differences were in:

* gcc.dg/fixed-point/const-1.s on targets that support it

  I think this is a known improvement.  The test case checks a series of
  conversions to make sure that the out-of-range ones produce a warning.
  E.g.:

    short _Fract sfF = 1.0;  /* { dg-warning "overflow" } */

  The asm differences are in the values produced for these out-of-range
  casees.  The old code used real_to_integer2, which saturates the result
  to double_int precision.  It then uses the fractional part of that result
  to initialise sfF.  The result therefore depends on the host (at least
  in the general case).

  The new code instead saturates to the precision of the result, just like
  we already do for:

    signed short s = 32768.0f;

  So this seems like a good change. 

* gcc.dg/vect/pr51799.c on m32c-elf and
* gcc.c-torture/execute/divconst-2.c on xstormy16-elf

  These are cases where wide-int converts a narrower-than-HWI
  multiplication by 1 << (GET_MODE_PRECISION - 1) into a shift but
  mainline doesn't.  The mainline code looks like:

      /* Convert multiply by constant power of two into shift unless
	 we are still generating RTL.  This test is a kludge.  */
      if (CONST_INT_P (trueop1)
	  && (val = exact_log2 (UINTVAL (trueop1))) >= 0
	  /* If the mode is larger than the host word size, and the
	     uppermost bit is set, then this isn't a power of two due
	     to implicit sign extension.  */
	  && (width <= HOST_BITS_PER_WIDE_INT
	      || val != HOST_BITS_PER_WIDE_INT - 1))
	return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));

  and this exact_log2 doesn't cope properly with the sign-extended
  0xff....8000... CONST_INT.  The wide-int code is:

      /* Convert multiply by constant power of two into shift.  */
      if (CONST_SCALAR_INT_P (trueop1))
	{
	  val = wi::exact_log2 (std::make_pair (trueop1, mode));
	  if (val >= 0 && val < GET_MODE_BITSIZE (mode))
	    return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
	}

  So this too seems like a good thing.

Thanks,
Richard



More information about the Gcc-patches mailing list