aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <jlaw@ventanamicro.com>2024-08-17 10:30:48 -0600
committerJeff Law <jlaw@ventanamicro.com>2024-08-17 10:30:48 -0600
commitabfc140579682598cd178eb9d0b0160bbfafc633 (patch)
tree031cb22c7fdd669dd2c08738203df9ca706e0ef9 /gcc
parent6d734ba485547329599f12bea63842a4fba8d72c (diff)
downloadgcc-abfc140579682598cd178eb9d0b0160bbfafc633.zip
gcc-abfc140579682598cd178eb9d0b0160bbfafc633.tar.gz
gcc-abfc140579682598cd178eb9d0b0160bbfafc633.tar.bz2
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+.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/v850/v850.md4
1 files changed, 3 insertions, 1 deletions
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index f810a27..83cc997 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;
})