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] Fix reg-stack ICE (PR target/21716)


Hi!

PR target/21716 contains a big testcase on which reg-stack ICEs
at -m32 -march=i386 -O2 -ffast-math in swap_rtx_condition.
Cross jumping there merges testqi_ext_0/jcc_1 from 2 different BB's, but keeps
the %ax setters (cmpfp_2_df_1) in the original blocks.
 (insn:HI 2037 4155 2038 55 (set (reg:HI 0 ax [783])
         (unspec:HI [
                 (compare:CCFP (reg/v:DF 10 st(2) [orig:354 cf0d2 ] [354])
                     (reg:DF 12 st(4)))
             ] 24)) 22 {*cmpfp_2_df_1} (insn_list 4399 (insn_list 4400 (nil)))
     (expr_list:REG_DEAD (reg:DF 12 st(4))
         (nil)))

 (note:HI 2038 2037 4525 55 NOTE_INSN_DELETED)
 ;; End of basic block 55, registers live:
  0 [ax] 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp] 10 [st(2)] 11 [st(3)] 13 [st(5)] 14
 [st(6)] 15 [st(7)] 16 [argp] 20 [frame]

 ;; Start of basic block 56, registers live: 0 [ax] 3 [bx] 4 [si] 5 [di] 6 [bp] 7
 [sp] 10 [st(2)] 11 [st(3)] 13 [st(5)] 14 [st(6)] 15 [st(7)] 16 [argp] 20 [frame]
 (code_label 4525 2038 4523 56 173 "" [1 uses])

 (note 4523 4525 2448 56 [bb 56] NOTE_INSN_BASIC_BLOCK)

 (note:HI 2448 4523 2449 56 NOTE_INSN_DELETED)

 (note:HI 2449 2448 2450 56 NOTE_INSN_DELETED)

 (note:HI 2450 2449 4359 56 NOTE_INSN_DELETED)

 (insn 4359 2450 2453 56 (set (reg:CCZ 17 flags)
         (compare:CCZ (and:SI (zero_extract:SI (reg:SI 0 ax [834])
                     (const_int 8 [0x8])
                     (const_int 8 [0x8]))
                 (const_int 1 [0x1]))
             (const_int 0 [0x0]))) 278 {*testqi_ext_0} (nil)
     (expr_list:REG_DEAD (reg:SI 0 ax [834])
         (nil)))

 (jump_insn:HI 2453 4359 4454 56 (set (pc)
         (if_then_else (eq (reg:CCZ 17 flags)
                 (const_int 0 [0x0]))
             (label_ref 1835)
             (pc))) 494 {*jcc_1} (insn_list 4359 (nil))
     (expr_list:REG_DEAD (reg:CCZ 17 flags)
         (expr_list:REG_BR_PROB (const_int 8448 [0x2100])
             (nil))))

When swap_rtx_condition is called on insn 2037, it doesn't find the %ax user
in the same BB, but as the last instruction in the BB is not INSN_P(), it crashes
when trying to dereference it's PATTERN (because NOTEs don't have any).

If swap_rtx_condition returns non-zero, insn after the forward search loop
must point at sahf and after it there must be a conditional jump in the
basic block as well, so if insn == BB_END (current_block), then it is supposed
to return 0.
Alternatively,
-     pat = PATTERN (insn);
-     if (GET_CODE (pat) != SET
+     if (! INSN_P (insn)
+         || GET_CODE (pat = PATTERN (insn)) != SET
          || GET_CODE (SET_SRC (pat)) != UNSPEC
          || XINT (SET_SRC (pat), 1) != UNSPEC_SAHF
          || ! dead_or_set_p (insn, dest))
        return 0;
would work equally well I guess.
Ok for 3.4 branch (where it fixes the failure, though the testcase is too
large to be usable in this case and depending too much on other optimizations
to be really useful) and 4.0/HEAD (where the code has not changed at all since
then)?

2005-05-23  Jakub Jelinek  <jakub@redhat.com>

	PR target/21716
	* reg-stack.c (swap_rtx_condition): Don't crash if %ax user was not
	found in the basic block and last insn in the basic block is not
	INSN_P.  Remove explicit unspec numbers that are no longer valid
	from comments.

--- gcc/reg-stack.c.jj	2004-12-27 21:31:18.000000000 +0100
+++ gcc/reg-stack.c	2005-05-23 11:28:01.000000000 +0200
@@ -1231,9 +1231,9 @@ swap_rtx_condition (rtx insn)
       pat = PATTERN (insn);
     }
 
-  /* See if this is, or ends in, a fnstsw, aka unspec 9.  If so, we're
-     not doing anything with the cc value right now.  We may be able to
-     search for one though.  */
+  /* See if this is, or ends in, a fnstsw.  If so, we're not doing anything
+     with the cc value right now.  We may be able to search for one
+     though.  */
 
   if (GET_CODE (pat) == SET
       && GET_CODE (SET_SRC (pat)) == UNSPEC
@@ -1252,9 +1252,13 @@ swap_rtx_condition (rtx insn)
 	    return 0;
 	}
 
+      /* We haven't found it.  */
+      if (insn == BB_END (current_block))
+	return 0;
+
       /* So we've found the insn using this value.  If it is anything
-	 other than sahf, aka unspec 10, or the value does not die
-	 (meaning we'd have to search further), then we must give up.  */
+	 other than sahf or the value does not die (meaning we'd have
+	 to search further), then we must give up.  */
       pat = PATTERN (insn);
       if (GET_CODE (pat) != SET
 	  || GET_CODE (SET_SRC (pat)) != UNSPEC

	Jakub


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