fix sparc conditional trap failure

Richard Henderson rth@redhat.com
Thu Jun 5 16:32:00 GMT 2003


DaveM found the problem and identified the cause.  I cleaned
up the surrounding code a bit.


r~



        * optabs.c (HAVE_conditional_trap): Provide default.
        (gen_conditional_trap): Likewise.
        (init_optabs): Merge init_traps.
        (gen_cond_trap): Use prepare_operand.  Restructure and avoid ifdef.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.175
diff -c -p -d -r1.175 optabs.c
*** optabs.c	4 Jun 2003 04:42:14 -0000	1.175
--- optabs.c	5 Jun 2003 16:24:20 -0000
*************** enum insn_code setcc_gen_code[NUM_RTX_CO
*** 88,93 ****
--- 88,98 ----
  enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
  #endif
  
+ /* The insn generating function can not take an rtx_code argument.
+    TRAP_RTX is used as an rtx argument.  Its code is replaced with
+    the code to be used in the trap insn and all other fields are ignored.  */
+ static GTY(()) rtx trap_rtx;
+ 
  static int add_equal_note	PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
  static rtx widen_operand	PARAMS ((rtx, enum machine_mode,
  				       enum machine_mode, int, int));
*************** static inline optab init_optabv	PARAMS (
*** 114,122 ****
  static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
  static void init_integral_libfuncs PARAMS ((optab, const char *, int));
  static void init_floating_libfuncs PARAMS ((optab, const char *, int));
- #ifdef HAVE_conditional_trap
- static void init_traps PARAMS ((void));
- #endif
  static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
  					    enum rtx_code, int, rtx));
  static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
--- 119,124 ----
*************** static rtx expand_vector_unop PARAMS ((e
*** 128,133 ****
--- 130,140 ----
  				       int));
  static rtx widen_clz PARAMS ((enum machine_mode, rtx, rtx));
  static rtx expand_parity PARAMS ((enum machine_mode, rtx, rtx));
+ 
+ #ifndef HAVE_conditional_trap
+ #define HAVE_conditional_trap 0
+ #define gen_conditional_trap(a,b) (abort (), NULL_RTX)
+ #endif
  
  /* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
     the result of operation CODE applied to OP0 (and OP1 if it is a binary
*************** init_optabs ()
*** 5806,5814 ****
    gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
    gcov_init_libfunc = init_one_libfunc ("__gcov_init");
  
! #ifdef HAVE_conditional_trap
!   init_traps ();
! #endif
  
  #ifdef INIT_TARGET_OPTABS
    /* Allow the target to add more libcalls or rename some, etc.  */
--- 5813,5820 ----
    gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
    gcov_init_libfunc = init_one_libfunc ("__gcov_init");
  
!   if (HAVE_conditional_trap)
!     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
  
  #ifdef INIT_TARGET_OPTABS
    /* Allow the target to add more libcalls or rename some, etc.  */
*************** init_optabs ()
*** 5816,5839 ****
  #endif
  }
  
- static GTY(()) rtx trap_rtx;
- 
- #ifdef HAVE_conditional_trap
- /* The insn generating function can not take an rtx_code argument.
-    TRAP_RTX is used as an rtx argument.  Its code is replaced with
-    the code to be used in the trap insn and all other fields are
-    ignored.  */
- 
- static void
- init_traps ()
- {
-   if (HAVE_conditional_trap)
-     {
-       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-     }
- }
- #endif
- 
  /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
     CODE.  Return 0 on failure.  */
  
--- 5822,5827 ----
*************** gen_cond_trap (code, op1, op2, tcode)
*** 5843,5872 ****
       rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
  {
    enum machine_mode mode = GET_MODE (op1);
  
    if (mode == VOIDmode)
      return 0;
  
! #ifdef HAVE_conditional_trap
!   if (HAVE_conditional_trap
!       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
!       rtx insn;
!       start_sequence ();
!       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
!       PUT_CODE (trap_rtx, code);
!       insn = gen_conditional_trap (trap_rtx, tcode);
!       if (insn)
! 	{
! 	  emit_insn (insn);
! 	  insn = get_insns ();
! 	}
!       end_sequence ();
!       return insn;
      }
! #endif
  
!   return 0;
  }
  
  #include "gt-optabs.h"
--- 5831,5864 ----
       rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
  {
    enum machine_mode mode = GET_MODE (op1);
+   enum insn_code icode;
+   rtx insn;
+ 
+   if (!HAVE_conditional_trap)
+     return 0;
  
    if (mode == VOIDmode)
      return 0;
  
!   icode = cmp_optab->handlers[(int) mode].insn_code;
!   if (icode == CODE_FOR_nothing)
!     return 0;
! 
!   start_sequence ();
!   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
!   op2 = prepare_operand (icode, op2, 0, mode, mode, 0);
!   emit_insn (GEN_FCN (icode) (op1, op2));
! 
!   PUT_CODE (trap_rtx, code);
!   insn = gen_conditional_trap (trap_rtx, tcode);
!   if (insn)
      {
!       emit_insn (insn);
!       insn = get_insns ();
      }
!   end_sequence ();
  
!   return insn;
  }
  
  #include "gt-optabs.h"
Index: testsuite/gcc.c-torture/compile/20030605-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/20030605-1.c
diff -N testsuite/gcc.c-torture/compile/20030605-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/20030605-1.c	5 Jun 2003 16:28:04 -0000
***************
*** 0 ****
--- 1,12 ----
+ /* Test for proper preparation of the comparison operands for 
+    generation of a conditional trap.  Produced unrecognizable
+    rtl on Sparc.  */
+ 
+ struct blah { char *b_data; };
+ 
+ void set_bh_page(struct blah *bh, unsigned long offset)
+ {
+         if ((1UL << 12 ) <= offset)
+                 __builtin_trap() ;
+         bh->b_data = (char *)offset;
+ }



More information about the Gcc-patches mailing list