Patchwork [ARM] Fix PR 49069.

login
register
mail settings
Submitter Sameera Deshpande
Date Jan. 24, 2012, 4:10 p.m.
Message ID <1327421419.18910.116.camel@e102549-lin.cambridge.arm.com>
Download mbox | patch
Permalink /patch/137583/
State New
Headers show

Comments

Sameera Deshpande - Jan. 24, 2012, 4:10 p.m.
Hi,

Please find attached the patch fixing bug 49069.

This patch is tested with check-gcc on trunk and 4.6 without regression.
OK for trunk?
Is it fine to backport to 4.6 branch?

ChangeLog:
2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
        PR target/49069
        gcc/config/arm/arm.md (cstoredi4): Handle the case when both
operands are const_int.

gcc/testsuite/ChangeLog:
2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
        PR target/49069
        gcc.target/arm/pr49069.c: New compile-only test.

- Thanks and regards,
  Sameera D.
Matthew Gretton-Dann - March 1, 2012, 3:28 p.m.
PING.

On Tue, Jan 24, 2012 at 04:10:19PM +0000, Sameera Deshpande wrote:
> Hi,
> 
> Please find attached the patch fixing bug 49069.
> 
> This patch is tested with check-gcc on trunk and 4.6 without regression.
> OK for trunk?
> Is it fine to backport to 4.6 branch?
> 
> ChangeLog:
> 2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
>         PR target/49069
>         gcc/config/arm/arm.md (cstoredi4): Handle the case when both
> operands are const_int.
> 
> gcc/testsuite/ChangeLog:
> 2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
>         PR target/49069
>         gcc.target/arm/pr49069.c: New compile-only test.
> 
> - Thanks and regards,
>   Sameera D.

> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 751997f..e3dc98f 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -7911,8 +7911,9 @@
>       enum rtx_code code = GET_CODE (operands[1]);
>  
>       /* We should not have two constants.  */
> -     gcc_assert (GET_MODE (operands[2]) == DImode
> -		 || GET_MODE (operands[3]) == DImode);
> +     if (!(GET_MODE (operands[2]) == DImode || GET_MODE (operands[3]) == DImode)
> +         && !(reload_in_progress || reload_completed))
> +       operands[3] = force_reg (DImode, operands[3]);
>  
>      /* Flip unimplemented DImode comparisons to a form that
>         arm_gen_compare_reg can handle.  */
> diff --git a/gcc/testsuite/gcc.target/arm/pr49069.c b/gcc/testsuite/gcc.target/arm/pr49069.c
> new file mode 100644
> index 0000000..3cc903e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr49069.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Os -mfloat-abi=softfp -mfpu=vfpv3-d16" } */
> +
> +__extension__ typedef unsigned long long int uint64_t;
> +
> +static int
> +func2 (int a, int b)
> +{
> +  return a == 0 ? a : a / b;
> +}
> +
> +int array1[1];
> +const uint64_t array2[1] = { 1 };
> +
> +void
> +foo (void)
> +{
> +  for (array1[0] = 0; array1[0] == 1; array1[0]++)
> +    {
> +    }
> +  if (bar (array2[0] == func2 (array1[0], 0)) == 0)
> +    {
> +    }
> +}
Richard Earnshaw - March 1, 2012, 3:58 p.m.
On 01/03/12 15:28, Matthew Gretton-Dann wrote:
> PING.
> 

Sorry, I don't think this is right.  Why is gen_cstoredi being called
with two constants in a comparison?  If both operands are constant then
the comparison is deterministic and we don't need a cstore operation.

R.

> On Tue, Jan 24, 2012 at 04:10:19PM +0000, Sameera Deshpande wrote:
>> Hi,
>>
>> Please find attached the patch fixing bug 49069.
>>
>> This patch is tested with check-gcc on trunk and 4.6 without regression.
>> OK for trunk?
>> Is it fine to backport to 4.6 branch?
>>
>> ChangeLog:
>> 2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
>>         PR target/49069
>>         gcc/config/arm/arm.md (cstoredi4): Handle the case when both
>> operands are const_int.
>>
>> gcc/testsuite/ChangeLog:
>> 2012-01-24  Sameera Deshpande  <sameera.deshpande@arm.com>
>>         PR target/49069
>>         gcc.target/arm/pr49069.c: New compile-only test.
>>
>> - Thanks and regards,
>>   Sameera D.
> 
>> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
>> index 751997f..e3dc98f 100644
>> --- a/gcc/config/arm/arm.md
>> +++ b/gcc/config/arm/arm.md
>> @@ -7911,8 +7911,9 @@
>>       enum rtx_code code = GET_CODE (operands[1]);
>>  
>>       /* We should not have two constants.  */
>> -     gcc_assert (GET_MODE (operands[2]) == DImode
>> -		 || GET_MODE (operands[3]) == DImode);
>> +     if (!(GET_MODE (operands[2]) == DImode || GET_MODE (operands[3]) == DImode)
>> +         && !(reload_in_progress || reload_completed))
>> +       operands[3] = force_reg (DImode, operands[3]);
>>  
>>      /* Flip unimplemented DImode comparisons to a form that
>>         arm_gen_compare_reg can handle.  */
>> diff --git a/gcc/testsuite/gcc.target/arm/pr49069.c b/gcc/testsuite/gcc.target/arm/pr49069.c
>> new file mode 100644
>> index 0000000..3cc903e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/arm/pr49069.c
>> @@ -0,0 +1,24 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-Os -mfloat-abi=softfp -mfpu=vfpv3-d16" } */
>> +
>> +__extension__ typedef unsigned long long int uint64_t;
>> +
>> +static int
>> +func2 (int a, int b)
>> +{
>> +  return a == 0 ? a : a / b;
>> +}
>> +
>> +int array1[1];
>> +const uint64_t array2[1] = { 1 };
>> +
>> +void
>> +foo (void)
>> +{
>> +  for (array1[0] = 0; array1[0] == 1; array1[0]++)
>> +    {
>> +    }
>> +  if (bar (array2[0] == func2 (array1[0], 0)) == 0)
>> +    {
>> +    }
>> +}
>

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 751997f..e3dc98f 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -7911,8 +7911,9 @@ 
      enum rtx_code code = GET_CODE (operands[1]);
 
      /* We should not have two constants.  */
-     gcc_assert (GET_MODE (operands[2]) == DImode
-		 || GET_MODE (operands[3]) == DImode);
+     if (!(GET_MODE (operands[2]) == DImode || GET_MODE (operands[3]) == DImode)
+         && !(reload_in_progress || reload_completed))
+       operands[3] = force_reg (DImode, operands[3]);
 
     /* Flip unimplemented DImode comparisons to a form that
        arm_gen_compare_reg can handle.  */
diff --git a/gcc/testsuite/gcc.target/arm/pr49069.c b/gcc/testsuite/gcc.target/arm/pr49069.c
new file mode 100644
index 0000000..3cc903e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr49069.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Os -mfloat-abi=softfp -mfpu=vfpv3-d16" } */
+
+__extension__ typedef unsigned long long int uint64_t;
+
+static int
+func2 (int a, int b)
+{
+  return a == 0 ? a : a / b;
+}
+
+int array1[1];
+const uint64_t array2[1] = { 1 };
+
+void
+foo (void)
+{
+  for (array1[0] = 0; array1[0] == 1; array1[0]++)
+    {
+    }
+  if (bar (array2[0] == func2 (array1[0], 0)) == 0)
+    {
+    }
+}