From 190ad81282057b0e5884faaaad30a7270356b9b1 Mon Sep 17 00:00:00 2001 From: Jeff Law <jlaw@ventanamicro.com> Date: Thu, 8 Aug 2024 07:42:26 -0600 Subject: [PATCH] [RISC-V][PR target/116240] Ensure object is a comparison before extracting arguments This was supposed to go out the door yesterday, but I kept getting interrupted. The target bits for rtx costing can't assume the rtl they're given actually matches a target pattern. It's just kind of inherent in how the costing routines get called in various places. In this particular case we're trying to cost a conditional move: (set (dest) (if_then_else (cond) (true) (false)) On the RISC-V port the backend only allows actual conditionals for COND. So something like (eq (reg) (const_int 0)). In the costing code for if-then-else we did something like (XEXP (XEXP (cond, 0), 0))) Which fails miserably if COND is a terminal node like (reg) rather than (ne (reg) (const_int 0) So this patch tightens up the RTL scanning to ensure that we have a comparison before we start looking at the comparison's arguments. Run through my tester without incident, but I'll wait for the pre-commit tester to run through a cycle before pushing to the trunk. Jeff ps. We probably could support a naked REG for the condition and internally convert it to (ne (reg) (const_int 0)), but I don't think it likely happens with any regularity. PR target/116240 gcc/ * config/riscv/riscv.cc (riscv_rtx_costs): Ensure object is a comparison before looking at its arguments. gcc/testsuite * gcc.target/riscv/pr116240.c: New test. --- gcc/config/riscv/riscv.cc | 6 ++++-- gcc/testsuite/gcc.target/riscv/pr116240.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/pr116240.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 5fe4273beb7e..3d0a1d12b146 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3646,9 +3646,11 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1)))) || (GET_CODE (XEXP (x, 2)) == REG && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2)))) - || (GET_CODE (XEXP (x, 1)) == REG + || (COMPARISON_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == REG && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0))) - || (GET_CODE (XEXP (x, 1)) == REG + || (COMPARISON_P (XEXP (x, 0)) + && GET_CODE (XEXP (x, 1)) == REG && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0))))) { *total = COSTS_N_INSNS (1); diff --git a/gcc/testsuite/gcc.target/riscv/pr116240.c b/gcc/testsuite/gcc.target/riscv/pr116240.c new file mode 100644 index 000000000000..7e3eaa2f5445 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr116240.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fwrapv -march=rv64imvxtheadcondmov_xventanacondops -mabi=lp64d" } */ + +int a, b; +void c() { + int e = a >= 2 ? b : a; + short d = e * 2; + if (d) + for (;;) + ; +} + -- GitLab