SH patches for DImode comparing

kaz Kojima kkojima@rr.iij4u.or.jp
Sun Aug 13 21:04:00 GMT 2000


Hi,

I've found a reverse conditional statement in cmpeqdi_t splitter
of sh.md. This splitter didn't set JUMP_LABEL for the generated
conditional jump instruction in non-optimized case, too. In -O0
-m[234] case, this causes a fault in insn_current_reference_address
to gcc.c-torture/compile/920501-23.c, for example.
The first patch tries to fix these.

With -O0 -m[234] option, the function like
  int f(long long x){ return x == 1LL;}
causes an error like

Unrecognizable insn:
(insn 12 11 13 (set (reg:SI 18 t)
        (eq:SI (reg:DI 55)
            (const_int 1 [0x1]))) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 55)
        (nil)))

and the second patch is for this.

	kaz
----

	* config/sh/sh.md (cmpeqdi_t splitter): Fix a reverse testing and
	set JUMP_LABEL for the generated jump insn in non-optimized case.

	* config/sh/sh.c (prepare_scc_operands): Apply force_reg to
	sh_compare_op1 when the mode is DImode and sh_compare_op1 isn't
	const0_rtx.

Index: sh.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.38
diff -u -p -r1.38 sh.md
--- sh.md	2000/08/07 09:58:29	1.38
+++ sh.md	2000/08/14 02:54:11
@@ -636,7 +636,7 @@
 			   (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
   "reload_completed"
   [(set (reg:SI 18) (eq:SI (match_dup 2) (match_dup 3)))
-   (set (pc) (if_then_else (ne (reg:SI 18) (const_int 0))
+   (set (pc) (if_then_else (eq (reg:SI 18) (const_int 0))
 			   (label_ref (match_dup 6))
 			   (pc)))
    (set (reg:SI 18) (eq:SI (match_dup 4) (match_dup 5)))
@@ -655,6 +655,27 @@
   operands[4] = gen_lowpart (SImode, operands[0]);
   operands[5] = gen_lowpart (SImode, operands[1]);
   operands[6] = gen_label_rtx ();
+  if (! optimize)
+    {
+      rtx tmp, insn;
+      emit_insn (gen_rtx_SET (VOIDmode,
+			      gen_rtx_REG (SImode, 18),
+			      gen_rtx_EQ (SImode, operands[2], operands[3])));
+      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
+				  gen_rtx_EQ (VOIDmode,
+					      gen_rtx_REG (SImode, 18),
+					      const0_rtx),
+				  gen_rtx_LABEL_REF (VOIDmode, operands[6]),
+				  pc_rtx);
+      insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+      JUMP_LABEL (insn) = operands[6];
+      LABEL_NUSES (operands[6])++;
+      emit_insn (gen_rtx_SET (VOIDmode,
+			      gen_rtx_REG (SImode, 18),
+			      gen_rtx_EQ (SImode, operands[4], operands[5])));
+      emit_label (operands[6]);
+      DONE;
+    }
 }")
 
 (define_insn "cmpgtdi_t"

Index: sh.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.57
diff -u -p -r1.57 sh.c
--- sh.c	2000/08/07 09:58:29	1.57
+++ sh.c	2000/08/14 02:55:08
@@ -524,6 +524,7 @@ prepare_scc_operands (code)
   if ((code != EQ && code != NE
        && (sh_compare_op1 != const0_rtx
 	   || code == GTU  || code == GEU || code == LTU || code == LEU))
+      || (mode == DImode && sh_compare_op1 != const0_rtx)
       || (TARGET_SH3E && GET_MODE_CLASS (mode) == MODE_FLOAT))
     sh_compare_op1 = force_reg (mode, sh_compare_op1);
 


More information about the Gcc-patches mailing list