Hi,

A recent change somewhere exposed a latent bug between LRA and the definition
of the movsi_compare0 pattern.

This pattern ties the source and destination register of a set together
a (match_dup) and register constraints:

   [(set (reg:CC CC_REGNUM)
        (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
                    (const_int 0)))
    (set (match_operand:SI 0 "s_register_operand" "=r,r")
        (match_dup 1))]

This confuses LRA which expects the source and destination register of
a set to be different.

reduced.c: In function '_IO_vfscanf_internal':
reduced.c:104:1: internal compiler error: in lra_create_copy, at lra.c:1512
     }
 ^
0x8c3f9a lra_create_copy(int, int, int)
        /work/gcc-dev/src/gcc/gcc/lra.c:1512
0x8e4ab0 process_bb_lives
        /work/gcc-dev/src/gcc/gcc/lra-lives.c:568
0x8e4ab0 lra_create_live_ranges(bool)
        /work/gcc-dev/src/gcc/gcc/lra-lives.c:1019
0x8c5a39 lra(_IO_FILE*)
        /work/gcc-dev/src/gcc/gcc/lra.c:2356
0x873a96 do_reload
        /work/gcc-dev/src/gcc/gcc/ira.c:5415
0x873a96 execute
        /work/gcc-dev/src/gcc/gcc/ira.c:5576
Please submit a full bug report,

We can fix the pattern by moving away from match_dup and using register
tying with constraints consistently.

I'm not entirely convinced that this is legitimate (my vague recollection is
that register tying should only be used to tie inputs to outputs).

This has passed testing on a bunch of ARM targets, and fixes the build
issues I've been seeing.

OK for trunk?

Thanks,
James

---
gcc/

2014-06-11  James Greenhalgh  <james.greenha...@arm.com>

        * config/arm/arm.md (movsi_compare0): Clarify intentions using
        register tying.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index f58a79b..a01333b 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -6582,10 +6582,10 @@
 
 (define_insn "*movsi_compare0"
   [(set (reg:CC CC_REGNUM)
-	(compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
-		    (const_int 0)))
+	(compare:CC (match_operand:SI 2 "s_register_operand" "0,1")
+	    (const_int 0)))
    (set (match_operand:SI 0 "s_register_operand" "=r,r")
-	(match_dup 1))]
+	(match_operand:SI 1 "s_register_operand" "0,r"))]
   "TARGET_32BIT"
   "@
    cmp%?\\t%0, #0

Reply via email to