Hi, The testcase in this patch, from libgcc, causes an ICE in the Vax build.
The problem is that the sign and zero extend patterns in vax.md do not expect to see SUBREG rtx patterns, but use register_operand as the predicate. Forwprop isn't doing anything wrong or unusual in the testcase, so I think this is just an oversight in the Vax patterns. The problem is that the condition for this pattern treats any operands[1] which is not a REG_P as a MEM, which is invalid for SUBREG. In the patch we modify the condition to catch anything which is !MEM_P before treating operands[1] as a MEM. As far as I know, reload is going to get rid of these SUBREGs for us, so we don't need to modify the output statement. Tested that this restores the VAX build and that the code-gen is sensible for the testcase. OK? Thanks, James --- gcc/ 2015-06-16 James Greenhalgh <james.greenha...@arm.com> * config/vax/vax.md: Adjust sign/zero extend patterns to handle SUBREGs in operands[1]. gcc/testsuite/ 2015-06-16 James Greenhalgh <james.greenha...@arm.com> * gcc.target/vax/bswapdi-1.c: New.
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 44d162f..d5caa15 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -780,7 +780,7 @@ (match_operand:SI 3 "general_operand" "g"))] "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 - && (REG_P (operands[0]) + && (!MEM_P (operands[0]) || ! mode_dependent_address_p (XEXP (operands[0], 0), MEM_ADDR_SPACE (operands[0])))" "* @@ -809,7 +809,7 @@ (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (REG_P (operands[1]) + && (!MEM_P (operands[1]) || ! mode_dependent_address_p (XEXP (operands[1], 0), MEM_ADDR_SPACE (operands[1])))" "* @@ -837,7 +837,7 @@ (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (REG_P (operands[1]) + && (!MEM_P (operands[1]) || ! mode_dependent_address_p (XEXP (operands[1], 0), MEM_ADDR_SPACE (operands[1])))" "* diff --git a/gcc/testsuite/gcc.target/vax/bswapdi-1.c b/gcc/testsuite/gcc.target/vax/bswapdi-1.c new file mode 100644 index 0000000..c658d91 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/bswapdi-1.c @@ -0,0 +1,13 @@ +typedef int DItype __attribute__ ((mode (DI))); +DItype +__bswapdi2 (DItype u) +{ + return ((((u) & 0xff00000000000000ull) >> 56) + | (((u) & 0x00ff000000000000ull) >> 40) + | (((u) & 0x0000ff0000000000ull) >> 24) + | (((u) & 0x000000ff00000000ull) >> 8) + | (((u) & 0x00000000ff000000ull) << 8) + | (((u) & 0x0000000000ff0000ull) << 24) + | (((u) & 0x000000000000ff00ull) << 40) + | (((u) & 0x00000000000000ffull) << 56)); +}