[patch] final.c: Fix gcc.c-torture/execute/20020418-1.c.

Kazu Hirata kazu@codesourcery.com
Fri Mar 16 00:50:00 GMT 2007


Hi,

Attached is a patch to fix the failure of
gcc.c-torture/execute/20020418-1.c at -O1 and -O2 on m68k-elf (and
fido-elf).

Consider a reduced version of gcc.c-torture/execute/20020418-1.c.

void
foo (int a)
{
  if (a <= 51)
    __builtin_trap ();
}

./cc1 -O0 gives me correct assembly code like so:

foo:
	link.w %fp,#0
	moveq #51,%d0
	cmp.l 8(%fp),%d0
	jblt .L4
	trap #7
.L4:
	unlk %fp
	rts

In English, if the parameter A is 100, for example, we have that 51 -
100 is negative, meaning we skip the trap instruction.

Here is the output with ./cc1 -O1.

foo:
	link.w %fp,#0
	moveq #51,%d0
	cmp.l 8(%fp),%d0
	traple
	unlk %fp
	rts

In English, if the paramter A is 100 again, we have that 51 - 100 is
negative, and we triger the trap.

This difference in behavior comes from the fact that we do not take
CC_REVERSED into account when we print out the conditional trap.  When
the final pass runs, we have the following compare:

  (set (cc0)
       (compare (mem/c/i:SI (plus:SI (reg/f:SI 14 %a6)
				     (const_int 8 [0x8])) [0 a+0 S4 A32])
		(reg:SI 0 %d0)))

We do set CC_REVERSED in cmpsi+1, but nobody cares about it.  As a
result, we end up using a condition that would be for reversed
operands (i.e. cmp.l %d0,8(%fp)).

This patch fixes the problem by calling alter_cond to alter the trap
condition if we have nonstadard CC, such as CC_REVERSED.

Note that final_scan_insn does a similar treatment on conditional
branches and conditional moves.  All this patch does is essentially
the same treatment on conditional traps.

Tested on fido-none-elf on top of

  http://gcc.gnu.org/ml/gcc-patches/2007-03/msg01069.html

OK to apply?

Kazu Hirata

2007-03-15  Kazu Hirata  <kazu@codesourcery.com>

	* final.c (final_scan_insn): Alter the condition of a
	conditional trap if we have nonstandard CC.

Index: final.c
===================================================================
--- final.c	(revision 122956)
+++ final.c	(working copy)
@@ -2291,6 +2291,41 @@ final_scan_insn (rtx insn, FILE *file, i
 	      INSN_CODE (insn) = -1;
 	  }
 
+	/* If this is a conditional trap, maybe modify it if the cc's
+	   are in a nonstandard state so that it accomplishes the same
+	   thing that it would do straightforwardly if the cc's were
+	   set up normally.  */
+	if (cc_status.flags != 0
+	    && NONJUMP_INSN_P (insn)
+	    && GET_CODE (body) == TRAP_IF
+	    && COMPARISON_P (TRAP_CONDITION (body))
+	    && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx)
+	  {
+	    /* This function may alter the contents of its argument
+	       and clear some of the cc_status.flags bits.
+	       It may also return 1 meaning condition now always true
+	       or -1 meaning condition now always false
+	       or 2 meaning condition nontrivial but altered.  */
+	    int result = alter_cond (TRAP_CONDITION (body));
+
+	    /* If TRAP_CONDITION has become always false, delete the
+	       instruction.  */
+	    if (result == -1)
+	      {
+		delete_insn (insn);
+		break;
+	      }
+
+	    /* If TRAP_CONDITION has become always true, replace
+	       TRAP_CONDITION with const_true_rtx.  */
+	    if (result == 1)
+	      TRAP_CONDITION (body) = const_true_rtx;
+
+	    /* Rerecognize the instruction if it has changed.  */
+	    if (result != 0)
+	      INSN_CODE (insn) = -1;
+	  }
+
 	/* Make same adjustments to instructions that examine the
 	   condition codes without jumping and instructions that
 	   handle conditional moves (if this machine has either one).  */



More information about the Gcc-patches mailing list