On 25/01/17 10:58, Kyrill Tkachov wrote:
> Hi all,
> 
> We're hitting an ICE when expanding a DImode xor with an immediate on
> TARGET_IWMMXT:
> (insn 6 5 7 2 (set (reg:DI 111 [ t1.1_3 ])
>         (xor:DI (reg:DI 110 [ t1.0_2 ])
>             (const_int 85 [0x55]))) ./z32.c:13 -1
>      (nil))
> 
> The problem is that the general xordi3 expander accepts some immediates
> in operand 2 but the iwmmxt_xordi3
> define_insn only accepts register operands, and nothing forces the
> operand into a register in between.
> This doesn't affect the iordi3 or anddi3 expanders because their
> predicates are designed to accept immediates
> valid for the VORR and VBIC NEON instructions and thus check for
> TARGET_NEON as well, so they don't accept any
> immediates during expand time for TARGET_IWMMXT.
> 
> A fix could be to modify arm_xordi_operand to allow only register
> operands for TARGET_IWMMXT.
> Another approach, used in this patch, is to force the constants into
> registers in the expander itself.
> 
> Bootstrapped and tested on arm-none-linux-gnueabihf (I don't have access
> to iWMMXt hardware).
> 
> Ok for trunk and the branches after some time?
> This patch should only affect TARGET_IWMMXT and therefore is pretty safe
> at any stage.
> 
> Thanks,
> Kyrill
> 
> 2016-01-25  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>
> 
>     PR target/79145
>     * config/arm/arm.md (xordi3): Force constant operand into a register
>     for TARGET_IWMMXT.
> 
> 2016-01-25  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>
> 
>     PR target/79145
>     * gcc.target/arm/pr79145.c: New test.
> 

OK.

R.

> iwmmxt-xor.patch
> 
> 
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 
> 2eee8bc5701297f52e5ed991f074f1069bde1b6e..48bf07e5b6c121944b38ab8d0d14b029d2b34560
>  100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -3328,7 +3328,14 @@ (define_expand "xordi3"
>       (xor:DI (match_operand:DI 1 "s_register_operand" "")
>               (match_operand:DI 2 "arm_xordi_operand" "")))]
>    "TARGET_32BIT"
> -  ""
> +  {
> +    /* The iWMMXt pattern for xordi3 accepts only register operands but we 
> want
> +       to reuse this expander for all TARGET_32BIT targets so just force the
> +       constants into a register.  Unlike for the anddi3 and iordi3 there are
> +       no NEON instructions that take an immediate.  */
> +    if (TARGET_IWMMXT && !REG_P (operands[2]))
> +      operands[2] = force_reg (DImode, operands[2]);
> +  }
>  )
>  
>  (define_insn_and_split "*xordi3_insn"
> diff --git a/gcc/testsuite/gcc.target/arm/pr79145.c 
> b/gcc/testsuite/gcc.target/arm/pr79145.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..667824400390d6fe72d05a85769d210791b8c378
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr79145.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-mcpu=*" } 
> { "-mcpu=iwmmxt" } } */
> +/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-mabi=*" } 
> { "-mabi=iwmmxt" } } */
> +/* { dg-skip-if "Test is specific to the iWMMXt" { arm*-*-* } { "-march=*" } 
> { "-march=iwmmxt" } } */
> +/* { dg-skip-if "Test is specific to ARM mode" { arm*-*-* } { "-mthumb" } { 
> "" } } */
> +/* { dg-require-effective-target arm32 } */
> +/* { dg-require-effective-target arm_iwmmxt_ok } */
> +/* { dg-options "-mcpu=iwmmxt" } */
> +
> +int
> +main (void)
> +{
> +  volatile long long t1;
> +  t1 ^= 0x55;
> +  return 0;
> +}
> 

Reply via email to