[PATCH][ARM] PR target/68648: Fold NOT of CONST_INT in andsi_iorsi3_notsi splitter
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Wed Dec 16 10:03:00 GMT 2015
Hi Ramana,
On 15/12/15 21:20, Ramana Radhakrishnan wrote:
> On 07/12/15 10:39, Kyrill Tkachov wrote:
>> Hi all,
>>
>> In this PR we ICE because during post-reload splitting we generate the insn:
>> (insn 27 26 11 2 (set (reg:SI 0 r0 [orig:121 D.4992 ] [121])
>> (and:SI (not:SI (const_int 1 [0x1]))
>> (reg:SI 0 r0 [orig:121 D.4992 ] [121])))
>> (nil))
>>
>>
>> The splitter at fault is andsi_iorsi3_notsi that accepts a const_int in operands[3]
>> and outputs (not (match_dup 3)). It should really be trying to constant fold the result
>> first. This patch does that by calling simplify_gen_unary to generate the complement
>> of operands[3] if it's a register or the appropriate const_int rtx with the correct
>> folded result that will still properly match the arm bic-immediate instruction.
>>
>> Bootstrapped and tested on arm-none-eabi.
>>
>> Is this ok for trunk?
>>
>> This appears on GCC 4.9 and GCC 5 and I'll be testing the fix there as well.
>> Ok for those branches if testing is successful?
>>
>> Thanks,
>> Kyrill
>>
>> 2015-12-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
>>
>> PR target/68648
>> * config/arm/arm.md (*andsi_iorsi3_notsi): Try to simplify
>> the complement of operands[3] during splitting.
>>
>> 2015-12-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
>>
>> PR target/68648
>> * gcc.c-torture/execute/pr68648.c: New test.
>>
>> arm-not-int.patch
>>
>>
>> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
>> index 2b48bbaf034b286d723536ec2aa6fe0f9b312911..dfb75c5f11c66c6b4a34ff3071b5a0957c3512cb 100644
>> --- a/gcc/config/arm/arm.md
>> +++ b/gcc/config/arm/arm.md
>> @@ -3274,8 +3274,22 @@ (define_insn_and_split "*andsi_iorsi3_notsi"
>> "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
>> "&& reload_completed"
>> [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
>> - (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
>> - ""
>> + (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
>> + {
>> + /* If operands[3] is a constant make sure to fold the NOT into it
>> + to avoid creating a NOT of a CONST_INT. */
>> + rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
>> + if (CONST_INT_P (not_rtx))
>> + {
>> + operands[4] = operands[0];
>> + operands[5] = not_rtx;
>> + }
>> + else
>> + {
>> + operands[5] = operands[0];
>> + operands[4] = not_rtx;
>> + }
> Watch out indentation here - I'm not sure if this is your mail client or mine causing this sort of thing.
Looks fine in two of my editors and also in the svn diff output, so I think there
must be something on your end.
>
> Ok with that double checked.
Thanks, I've committed it as r231675.
Will backport to the branches after some time on trunk.
Kyrill
> regards
> Ramana
>
>> + }
>> [(set_attr "length" "8")
>> (set_attr "ce_count" "2")
>> (set_attr "predicable" "yes")
>> diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68648.c b/gcc/testsuite/gcc.c-torture/execute/pr68648.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..fc66806a99a0abef7bd517ae2f5200b387e69ce4
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.c-torture/execute/pr68648.c
>> @@ -0,0 +1,20 @@
>> +int __attribute__ ((noinline))
>> +foo (void)
>> +{
>> + return 123;
>> +}
>> +
>> +int __attribute__ ((noinline))
>> +bar (void)
>> +{
>> + int c = 1;
>> + c |= 4294967295 ^ (foo () | 4073709551608);
>> + return c;
>> +}
>> +
>> +int
>> +main ()
>> +{
>> + if (bar () != 0x83fd4005)
>> + __builtin_abort ();
>> +}
>>
More information about the Gcc-patches
mailing list