[gcc r17-3566] AVR: target/127004 - Fix ICE "incomplete application of insn"

Georg-Johann Lay via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:91291a45490dae956752e55398b6562505692dc5

commit r17-3566-g91291a45490dae956752e55398b6562505692dc5
Author: Georg-Johann Lay <[email protected]>
Date:   Sun Aug 23 20:52:57 2026 +0200

    AVR: target/127004 - Fix ICE "incomplete application of insn"
    
    This ICE occurs when RTL pass avr-fuse-move finds an optimization,
    and then finds a difference between the outcomes of the new insn
    sequence and the old one.
    
    In this specific case, optimize_data_t::ignore_mask didn't account
    for all the regs clobbered by the old sequence, so that the pass
    logic concluded there was a bug in the optimization and ICEd.
    
    The old insn is a SImode multiplication with a known result,
    which clobbers quite some regs because it is implemented as a
    transparent libgcc call.  The optimization replaces that
    multiplication with a constant.
    
    The ICE only occurs with -mpr118012 which tries to hack around
    PR118012 by calling the libgcc multiplications by hand instead
    of relying on the libcall machinery.
    
    The fix traverses the old pattern and gathers all scratch regs
    in ignore_mask.  The patch passes without new regressions.
    It fixes the ICE which occurred for targets that don't have MUL.
    
            PR target/127004
    gcc/
            * config/avr/avr-passes.cc (rtl-iter.h): Include.
            (insninfo_t::scratch_mask): New method.
            (optimize_data_t::try_split_ldi): Use it for ignore_mask.
            (optimize_data_t::try_split_any): Same.
            (optimize_data_t::emit_sequence): Dump ignore_mask prior to
            calling fatal_insn.
    gcc/testsuite/
            * gcc.target/avr/torture/pr127004.c: New test.

Diff:
---
 gcc/config/avr/avr-passes.cc                    | 30 +++++++++++++++++++++----
 gcc/testsuite/gcc.target/avr/torture/pr127004.c |  7 ++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/gcc/config/avr/avr-passes.cc b/gcc/config/avr/avr-passes.cc
index 7dc6f2b77c18..01a7853e3615 100644
--- a/gcc/config/avr/avr-passes.cc
+++ b/gcc/config/avr/avr-passes.cc
@@ -28,6 +28,7 @@
 #include "backend.h"
 #include "target.h"
 #include "rtl.h"
+#include "rtl-iter.h"
 #include "tree.h"
 #include "diagnostic-core.h"
 #include "cfghooks.h"
@@ -1053,6 +1054,28 @@ struct insninfo_t
     else
       gcc_unreachable ();
   }
+
+  gprmask_t scratch_mask () const
+  {
+    gprmask_t mask = m_scratch
+      ? regmask (m_scratch, 1)
+      : 0;
+
+    if (m_insn)
+      {
+	subrtx_iterator::array_type array;
+	FOR_EACH_SUBRTX (iter, array, PATTERN (m_insn), NONCONST)
+	  {
+	    rtx scratch_reg;
+	    if (GET_CODE (*iter) == CLOBBER
+		&& REG_P (scratch_reg = XEXP (*iter, 0))
+		&& END_REGNO (scratch_reg) <= REG_32)
+	      mask |= regmask (scratch_reg);
+	  }
+      }
+
+    return mask;
+  }
 }; // insninfo_t
 
 
@@ -1186,6 +1209,7 @@ optimize_data_t::emit_sequence (basic_block bb, rtx_insn *insns)
 	  avr_dump ("INCOMPLETE APPLICATION:\n");
 	  m2.dump ("regs old route=%s\n\n");
 	  n2.dump ("regs new route=%s\n\n");
+	  avr_dump ("ignore_mask = %08x\n\n", (unsigned) ignore_mask);
 	  avr_dump ("The new insns are:\n%L", insns);
 
 	  fatal_insn ("incomplete application of insn", insns);
@@ -2715,8 +2739,7 @@ optimize_data_t::try_split_ldi (bbinfo_t *bbi)
 
       n_new_insns = bbinfo_t::fpd->solution.emit_insns (curr.ii, curr.regs);
 
-      if (curr.ii.m_scratch)
-	ignore_mask = regmask (curr.ii.m_scratch, 1);
+      ignore_mask = curr.ii.scratch_mask ();
     }
 
   return found;
@@ -3057,8 +3080,7 @@ optimize_data_t::try_split_any (bbinfo_t *)
 	return fail ("too expensive");
     }
 
-  if (ii.m_scratch)
-    ignore_mask = regmask (ii.m_scratch, 1);
+  ignore_mask = ii.scratch_mask ();
 
   return true;
 }
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr127004.c b/gcc/testsuite/gcc.target/avr/torture/pr127004.c
new file mode 100644
index 000000000000..225923a2a805
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr127004.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99" } */
+
+unsigned f (unsigned x)
+{
+  return (unsigned) (((unsigned long long) x * 0xAAAAAAAB) >> 32) >> 1;
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.