This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch ARM] Fix PR 49069.
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: GCC-Patches <gcc-patches at gcc dot gnu dot org>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>
- Date: Thu, 01 Mar 2012 15:58:51 +0000
- Subject: Re: [Patch ARM] Fix PR 49069.
- References: <1327421419.18910.116.camel@e102549-lin.cambridge.arm.com> <20120301152848.GF3858@e103070-lin.arm.com>
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)
>> + {
>> + }
>> +}
>