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