]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Adjust v850 rotate expander to allow more cases for V850E3V5
authorJeff Law <jlaw@ventanamicro.com>
Sat, 17 Aug 2024 16:30:48 +0000 (10:30 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Sat, 17 Aug 2024 16:30:48 +0000 (10:30 -0600)
The recent if-conversion changes tripped a failure on the v850 port.

The core underlying issue is that while the if-conversion code tries to do the
right thing with noce_can_force_operand to determine if it can force an
arbitrary operand into a register, it's not really a sufficient check.

Essentially for arithmetic codes, it checks the operands.  If the operands are
force-able and there's a code_to_optab mapping, then it returns true.

code_to_optab doesn't actually check anything other than the existence of  a
mapping in the target.  If the target pattern has restrictions enforced by the
condition or it's an expander that is allowed to FAIL, then
noce_can_force_operand to be true, even though we may not be able to directly
force the operand into a register.

This came up on the v850 when we had an operand that was a rotate by a constant
number of bits (I don't remember the count, all that's important about it was
the count was not 8 or 16).

The v850 port has this define_expand:

 > (define_expand "rotlsi3"
>   [(parallel [(set (match_operand:SI 0 "register_operand" "")
>                    (rotate:SI (match_operand:SI 1 "register_operand" "")
>                               (match_operand:SI 2 "const_int_operand" "")))
>               (clobber (reg:CC CC_REGNUM))])]
>   "(TARGET_V850E_UP)"
>   {
>     if (INTVAL (operands[2]) != 16)
>       FAIL;
>   })
So the only rotate count allowed is 16 (there's a similar HI rotate with a count of 8).  AFAICT the rotate patterns are allowed to FAIL.  So naturally the expander fails and we get a testsuite regression:

> Tests that now fail, but worked before (4 tests):
>
> v850-sim/-mgcc-abi/-msoft-float/-mv850e3v5: gcc: gcc.c-torture/execute/20100805-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> v850-sim/-mgcc-abi/-msoft-float/-mv850e3v5: gcc: gcc.c-torture/execute/20100805-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> v850-sim/-msoft-float/-mv850e3v5: gcc: gcc.c-torture/execute/20100805-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> v850-sim/-mv850e3v5: gcc: gcc.c-torture/execute/20100805-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)

This patch works around the problem by allowing the rotates in additional
cases, particularly for the V850E3V5+ variants which have a general rotate
capability.  But let's be clear, this is just a workaround and I expect we're
going to have to revisit the code to test if an operand can be forced into a
register.

gcc/
* config/v850/v850.md (rotlsi3): Allow more cases for V850E3V5+.

gcc/config/v850/v850.md

index f810a27fa2e1b71f9baa08fa9d3863b8430331c3..83cc9972673da72938142a13d5bcaa2261211d82 100644 (file)
              (clobber (reg:CC CC_REGNUM))])]
   "(TARGET_V850E_UP)"
   {
-    if (INTVAL (operands[2]) != 16)
+    if (TARGET_V850E3V5_UP && e3v5_shift_operand (operands[2], SImode))
+      ;
+    else if (INTVAL (operands[2]) != 16)
       FAIL;
   })