https://gcc.gnu.org/g:49d5e21d41aed827038f6766140e2449a64a9726

commit r15-2899-g49d5e21d41aed827038f6766140e2449a64a9726
Author: Kewen Lin <li...@linux.ibm.com>
Date:   Tue Aug 13 04:28:28 2024 -0500

    LRA: Don't emit move for substituted CONSTATNT_P operand [PR116170]
    
    Commit r15-2084 exposes one ICE in LRA.  Firstly, before
    r15-2084 KFmode has 126 bit precision while V1TImode has 128
    bit precision, so the subreg (subreg:V1TI (reg:KF 131) 0) is
    paradoxical_subreg_p, which stops some passes from doing
    some optimization.  After r15-2084, KFmode has the same mode
    precision as V1TImode, passes are able to optimize more, but
    it causes this ICE in LRA as described below:
    
    For insn 106 (set (mem:V1TI ...) (subreg:V1TI (reg:KF 133) 0)),
    which matches pattern
    
    (define_insn "*vsx_le_perm_store_<mode>"
      [(set (match_operand:VSX_LE_128 0 "memory_operand" "=Z,Q")
            (match_operand:VSX_LE_128 1 "vsx_register_operand" "+wa,r"))]
      "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR
       && !altivec_indexed_or_indirect_operand (operands[0], <MODE>mode)"
      "@
       #
       #"
      [(set_attr "type" "vecstore,store")
       (set_attr "length" "12,8")
       (set_attr "isa" "<VSisa>,*")])
    
    LRA makes equivalence substitution on r133 with const double
    (const_double:KF 0.0), selects alternative 0 and fixes up
    operand 1 for constraint "wa", because operand 1 is OP_INOUT,
    so it considers assigning back to it as well, that is:
    
      lra_emit_move (type == OP_INOUT ? copy_rtx (old) : old, new_reg);
    
    But because old has been changed to const_double in equivalence
    substitution, the move is actually assigning to const_double,
    which is invalid and cause ICE.
    
    Considering reg:KF 133 is equivalent with (const_double:KF 0.0)
    even though this operand is OP_INOUT, IMHO there should not be
    any following uses of reg:KF 133, otherwise it doesn't have the
    chance to be equivalent to (const_double:KF 0.0).  So this patch
    is to guard the lra_emit_move with !CONSTANT_P to exclude such
    case.
    
            PR rtl-optimization/116170
    
    gcc/ChangeLog:
    
            * lra-constraints.cc (curr_insn_transform): Don't emit move back to
            old operand if it's CONSTANT_P.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/powerpc/pr116170.c: New test.

Diff:
---
 gcc/lra-constraints.cc                      |  4 +++-
 gcc/testsuite/gcc.target/powerpc/pr116170.c | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 92b343fa99a0..90cbe6c012b7 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4742,7 +4742,9 @@ curr_insn_transform (bool check_only_p)
            }
          *loc = new_reg;
          if (type != OP_IN
-             && find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX)
+             && find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX
+             /* OLD can be an equivalent constant here.  */
+             && !CONSTANT_P (old))
            {
              start_sequence ();
              lra_emit_move (type == OP_INOUT ? copy_rtx (old) : old, new_reg);
diff --git a/gcc/testsuite/gcc.target/powerpc/pr116170.c 
b/gcc/testsuite/gcc.target/powerpc/pr116170.c
new file mode 100644
index 000000000000..6f6ca0f1ae93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr116170.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -fstack-protector-strong 
-ffloat-store" } */
+
+/* Verify there is no ICE.  */
+
+int a, d;
+_Float128 b, c;
+void
+e ()
+{
+  int f = 0;
+  if (a)
+    if (b || c)
+      f = 1;
+  if (d)
+    e (f ? 0 : b);
+}

Reply via email to