This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch,avr] PR78883: Implement CANNOT_CHANGE_MODE_CLASS.


This fixes PR78883 which is a problem in reload revealed by a
change to combine.c.  The fix is as proposed by Segher: implement
CANNOT_CHANGE_MODE_CLASS.

Ok for trunk?

Johann


gcc/
	PR target/78883
	* config/avr/avr.h (CANNOT_CHANGE_MODE_CLASS): New define.
	* config/avr/avr-protos.h (avr_cannot_change_mode_class): New proto.
	* config/avr/avr.c (avr_cannot_change_mode_class): New function.

gcc/testsuite/
	PR target/78883
	* gcc.c-torture/compile/pr78883.c: New test.
Index: config/avr/avr-protos.h
===================================================================
--- config/avr/avr-protos.h	(revision 244001)
+++ config/avr/avr-protos.h	(working copy)
@@ -111,7 +111,7 @@ extern int _reg_unused_after (rtx_insn *
 extern int avr_jump_mode (rtx x, rtx_insn *insn);
 extern int test_hard_reg_class (enum reg_class rclass, rtx x);
 extern int jump_over_one_insn_p (rtx_insn *insn, rtx dest);
-
+extern int avr_cannot_change_mode_class (machine_mode, machine_mode, enum reg_class);
 extern int avr_hard_regno_mode_ok (int regno, machine_mode mode);
 extern void avr_final_prescan_insn (rtx_insn *insn, rtx *operand,
 				    int num_operands);
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 244001)
+++ config/avr/avr.c	(working copy)
@@ -11833,6 +11833,21 @@ jump_over_one_insn_p (rtx_insn *insn, rt
 }
 
 
+/* Worker function for `CANNOT_CHANGE_MODE_CLASS'.  */
+
+int
+avr_cannot_change_mode_class (machine_mode from, machine_mode to,
+                              enum reg_class /* rclass */)
+{
+  /* We cannot access a hard register in a wider mode, for example we
+     must not access (reg:QI 31) as (reg:HI 31).  HARD_REGNO_MODE_OK
+     would avoid such hard regs, but reload would generate it anyway
+     from paradoxical subregs of mem, cf. PR78883.  */
+   
+  return GET_MODE_SIZE (to) > GET_MODE_SIZE (from);
+}
+
+
 /* Worker function for `HARD_REGNO_MODE_OK'.  */
 /* Returns 1 if a value of mode MODE can be stored starting with hard
    register number REGNO.  On the enhanced core, anything larger than
Index: config/avr/avr.h
===================================================================
--- config/avr/avr.h	(revision 244001)
+++ config/avr/avr.h	(working copy)
@@ -216,6 +216,9 @@ These two properties are reflected by bu
 
 #define MODES_TIEABLE_P(MODE1, MODE2) 1
 
+#define CANNOT_CHANGE_MODE_CLASS(MFROM, MTO, RCLASS) \
+  avr_cannot_change_mode_class (MFROM, MTO, RCLASS)
+
 enum reg_class {
   NO_REGS,
   R0_REG,			/* r0 */
Index: testsuite/gcc.c-torture/compile/pr78883.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr78883.c	(nonexistent)
+++ testsuite/gcc.c-torture/compile/pr78883.c	(working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int foo (int *p)
+{
+  int i;
+  for (i = 0; i < 5; i++)
+    {
+      if (p[i] & 1)
+        return i;
+    }
+  return -1;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]