https://gcc.gnu.org/g:abfc140579682598cd178eb9d0b0160bbfafc633

commit r15-2973-gabfc140579682598cd178eb9d0b0160bbfafc633
Author: Jeff Law <j...@ventanamicro.com>
Date:   Sat Aug 17 10:30:48 2024 -0600

    Adjust v850 rotate expander to allow more cases for V850E3V5
    
    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+.

Diff:
---
 gcc/config/v850/v850.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index f810a27fa2e..83cc9972673 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -1352,7 +1352,9 @@
              (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;
   })

Reply via email to