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]

RFA: final.c:final_scan_insn: Delete notes when reinserting test insns. +testcase.


Bug appears as:
foo.ii:320: Internal compiler error in `final_scan_insn', at
foo.ii:320: final.c:2203
foo.ii:320: Please submit a full bug report.
(etc.)

Not for any target in CVS for the testcase below, though.

Some targets have cc0-user insns that return NULL as output template
when cc0 flags are not to taste, like when the overflow bit is unusable.
This is supposed to cause the pseudo-deleted cc0-setter test insn to be
"reinserted".  This is implemented by final_scan_insn returning the
cc0-setter as the return value (presumably the next insn) when the
cc0-user insn has a NULL template.

Unfortunately the code overlooked that the cc0-setter can be on the other
side of a block note.  I'm not sure if that happens for valid reasons, but
it happens.  (If it's not valid, then this patch should be transmogrified
into a sanity check.)  The cautiously guarded block_depth variable got out
of sync, with a later abort.  A *.27.dbr (last generated dump)
snippet showing the straddled (double) block-end:

...
(insn 151 150 152 (set (reg:SI 9 r9)
        (minus:SI (reg:SI 9 r9)
            (mem/s:SI (plus:SI (reg:SI 8 r8)
                    (const_int -16 [0xfffffff0])) 0))) 69 {subsi3} (insn_list 149 (insn_list 149 (nil)))
    (nil))

(insn:QI 152 151 153 (set (cc0)
        (reg:SI 9 r9)) 1 {tstsi} (insn_list 151 (insn_list 151 (nil)))
    (expr_list:REG_DEAD (reg:SI 9 r9)
        (nil)))

(note:HI 153 152 154 NOTE_INSN_DELETED 0)

(note:HI 154 153 158 NOTE_INSN_DELETED 0)

(note:HI 158 154 159 0x40177560 NOTE_INSN_BLOCK_END 0)

(note:HI 159 158 161 0x401774c0 NOTE_INSN_BLOCK_END 0)

(note:HI 161 159 162 ("stdin") 234 0)

(insn 162 161 163 (set (reg:SI 11 r11)
        (le:SI (cc0)
            (const_int 0 [0x0]))) 176 {sle} (nil)
    (nil))

(insn 163 162 164 (set (reg:SI 0 r0)
        (symbol_ref:SI ("*LC0"))) 31 {movsi} (nil)
    (expr_list:REG_EQUIV (symbol_ref:SI ("*LC0"))
        (nil)))
...

As mentioned, the bug might appear for cc0 machines that "return 0" for
cc-user insns like "sle".  Not spotted with v850 with this test-case
though (I thought I could provoke it); spotted with CRIS (yeah, not in CVS
yet).  Flags "-O -g", where "-g" is the important one.

Bootstrapped and checked with no additional failures on i686-pc-linux-gnu
(although this is not a cc0 target where the bug will appear).

Likewise compiled and checked on the simulator for powerpc-unknown-eabi as
described in <URL:http://gcc.gnu.org/ml/gcc-bugs/2000-01/msg00347.html>,
only because it's a cc0 target and I have access to no other cc0 targets;
the bug is not expected to appear on that target.

Ok to commit patch?

Ok to commit test-case (below, after patch)?  If so, where?  If it had
been C, I would have suggested gcc.c-torture/compile/20000610-1.c.  I
can't figure out where the C++ equivalent should be.

Sat Jun 10 15:34:20 2000  Hans-Peter Nilsson  <hp@axis.com>

	* final.c (final_scan_insn): Delete notes between cc0 setter and
	user when restarting from setter.

Index: final.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/final.c,v
retrieving revision 1.133
diff -p -c -r1.133 final.c
*** final.c	2000/05/29 22:02:42	1.133
--- final.c	2000/06/10 13:23:39
*************** final_scan_insn (insn, file, optimize, p
*** 2943,2952 ****
  	   needs to be reinserted.  */
  	if (template == 0)
  	  {
  	    if (prev_nonnote_insn (insn) != last_ignored_compare)
  	      abort ();
  	    new_block = 0;
! 	    return prev_nonnote_insn (insn);
  	  }
  
  	/* If the template is the string "#", it means that this insn must
--- 2943,2968 ----
  	   needs to be reinserted.  */
  	if (template == 0)
  	  {
+ 	    rtx prev;
+ 
  	    if (prev_nonnote_insn (insn) != last_ignored_compare)
  	      abort ();
  	    new_block = 0;
! 
! 	    /* We have already processed the notes between the setter and
! 	       the user.  Make sure we don't process them again.  */
! 	    for (prev = insn;
! 		 prev != last_ignored_compare;
! 		 prev = PREV_INSN (prev))
! 	      {
! 		if (GET_CODE (prev) == NOTE)
! 		  {
! 		    NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;
! 		    NOTE_SOURCE_FILE (prev) = 0;
! 		  }
! 	      }
! 
! 	    return prev;
  	  }
  
  	/* If the template is the string "#", it means that this insn must

----------- Testcase:
typedef unsigned int    udword;
extern "C" {
void __assert (const char *, int, const char *);
}
class ShZzy;
class ShBe;
class Sh
{
 public:
  class Xy;
  inline  Sh(const char*      theName,
               const Xy& theXys);
  virtual ~Sh();
  inline const char* name() const;
  inline bool        shXy(const Xy& theXy);
  virtual void       setParent(Sh* theParent);
  class Xy
  {
   public:
    Xy(int   theXy);
    Xy(const Xy& theXy);
    Xy& operator = (const Xy&);
    bool sh(const Xy& theXy);
   private:
    int  myXyFlags;
  };
 protected:
  Xy     myXys;
 private:
  Sh();
  Sh(const Sh&);
  Sh& operator = (const Sh&);
  const char*   myName;
  Sh*         myParent;
};
class ShZzy : public Sh 
{
 public:
  inline ShZzy(const char* theName);
  inline ShZzy(const char* theName,
                   const Xy& theXys);
  virtual ~ShZzy();
  void         addShTo(char* theParent);
  virtual void ap() {}
  void         addSh(Sh* theSh);
  virtual void setParent(Sh* theParent);
  void         baseAp();
 private:
  ShZzy();
  ShZzy(const ShZzy&);
  ShZzy& operator = (const ShZzy&);
  bool          iAmInited;
};
class ShBop
{
 public:
  inline ShBop(const ShBe* theBe);
  void            shWw(bool,
                                char* a1 = "",
                                char* a2 = "",
                                int   a3 = -1,
                                char* a4 = "foo");
  typedef enum { shOk,
                 shFailed,
                 shDone,
                 invalidBop } bopType;
  inline bopType bop();
  inline int        numberOfVs();
  inline void       closeBop();
 private:
  ShBop(const ShBop&);
  ShBop& operator = (const ShBop&);
  const ShBe*  myBe;
  bopType       myBop;
  int              my1;
  int              my2;
  const char*      my3;
  const char*      my4;
  int              my5;
  const char*      my6;
};
Sh::Sh(const char* theName,
           const Xy& theXys)
  :myXys(theXys),
   myName(theName),
   myParent(0)
{}
const char*
Sh::name() const
{
  return myName;
}
bool
Sh::shXy(const Xy& theXy)
{
  return myXys.sh(theXy);
}
ShZzy::ShZzy(const char* theName)
  :Sh(theName, Xy(0)),
   iAmInited(false)
{}
ShZzy::ShZzy(const char* theName,
                     const Xy& theXys)
  :Sh(theName, theXys),
   iAmInited(false)
{}
ShBop::ShBop(const ShBe* theBe)
  :myBe(theBe),
   myBop(invalidBop),
   my1(0),
   my2(0),
   my3(""),
   my4(""),
   my5(0),
   my6("")
{}
ShBop::bopType
ShBop::bop()
{
  ((!my2 || myBop == shFailed) ? (void)0 : __assert("foo", 91,"foo"));
  return myBop;
}
int
ShBop::numberOfVs()
{
  return my2 + my1;
}
void
ShBop::closeBop()
{
  if (myBop == invalidBop)
  {
    myBop = shDone;
  }
}
class ShBe;
template <class ShCc>
class ShAp : public ShZzy
{
 public:
  ShAp(const char* theName);
  ShAp(const char* theName,
                const Xy& theXys);
  virtual ~ShAp() {}
  typedef void (ShCc::*ShMethod)();
  virtual void ap() {}
 protected:
  ShBop* bop();
 private:
  ShAp();
  ShAp(const ShAp&);
  ShAp& operator = (const ShAp&);
  ShBop* myBop;
  ShBe*   myBe;
};
class ShBe : public Sh
{
 public:
  inline ShBe(const char* theName);
  inline ShBe(const char* theName,
                  const Xy& theXys);
  inline virtual ~ShBe();
  virtual void    run() = 0;
  ShBop*  runBe();
 protected:
  inline ShBop* bop();
 private:
  ShBe();
  ShBe(const ShBe&);
  ShBe& operator = (const ShBe&);
  ShBop* myBop;
};
template <class ShCc> 
ShAp<ShCc>::ShAp(const char* theName)
  : ShZzy(theName),
    myBop(0),
    myBe(0)
{}
template <class ShCc> 
ShAp<ShCc>::ShAp(const char* theName,
                                   const Sh::Xy& theXys)
  : ShZzy(theName, theXys),
    myBop(0),
    myBe(0)
{}
template <class ShCc>
ShBop*
ShAp<ShCc>::bop()
{
  ((myBop) ? (void)0 : __assert("foo", 96,"foo"));
  return myBop;
}
class xSh : public ShAp<xSh>
{
 public:
  xSh();
  virtual ~xSh();
  void ap();
  void uff();
  void rtt();
};
class xUff
{
 public:
  xUff();
  xUff(const xUff&);
  xUff& operator = (const xUff&);
  xUff(udword);
  operator udword() const;
  xUff& operator = (udword);
  bool operator < (const xUff) const;
  bool operator <= (const xUff) const;
  bool operator > (const xUff) const;
  bool operator >= (const xUff) const;
  bool operator == (const xUff) const;
  enum {size = 4};
  xUff(unsigned char* theUff);
 private:
  udword myUff;
};
inline
xUff::xUff()
  : myUff(0)
{
}
inline
xUff::xUff(udword theUff)
  : myUff(theUff)
{
}
inline
xUff::xUff(
  const xUff& theUff)
  : myUff(theUff.myUff)
{
}
inline xUff&
xUff::operator = (const xUff& theUff)
{
  myUff = theUff.myUff;
  return *this;
}
inline xUff&
xUff::operator = (udword theUff)
{
  myUff = theUff;
  return *this; 
}
inline
xUff::operator udword() const
{
  return myUff;
}
inline bool
xUff::operator < (const xUff ding) const
{
  return (((int) (myUff - ding.myUff)) < 0);
}
inline bool
xUff::operator <= (const xUff ding) const
{
  return (((int) (myUff - ding.myUff)) <= 0);
}
inline bool
xUff::operator > (const xUff ding) const
{
  return (((int) (myUff - ding.myUff)) > 0);
}
inline bool
xUff::operator >= (const xUff ding) const
{
  return (((int) (myUff - ding.myUff)) >= 0);
}
inline bool
xUff::operator == (const xUff ding) const
{
  return (myUff == ding.myUff);
}
inline
xUff::xUff(unsigned char* theUff)
{
  myUff = *(udword *)theUff;
}
void
xSh::uff()
{
  static const udword halfudword = 0x80000000;
  xUff aGah((udword)0);
  udword diagonal = halfudword + (udword) aGah;
  xUff aGeh(diagonal - 1);
  xUff aGoh(diagonal + 1);
  (bop()->shWw ((aGah.operator <=(aGah)), ("foo"), ( ""), 118, "foo"));
  (bop()->shWw ((aGah.operator >=(aGah)), ("foo"), ( ""), 119, "foo"));
  (bop()->shWw ((!(aGah.operator <(aGah))), ("foo"), ( ""), 120, "foo"));
  (bop()->shWw ((!(aGah.operator >(aGah))), ("foo"), ( ""), 121, "foo"));
  (bop()->shWw ((aGah.operator <(aGeh)), ("foo"), ( ""), 124, "foo"));
  (bop()->shWw ((aGah.operator <=(aGeh)), ("foo"), ( ""), 125, "foo"));
  (bop()->shWw ((!(aGah.operator >(aGeh))), ("foo"), ( ""), 126, "foo"));
  (bop()->shWw ((!(aGah.operator >=(aGeh))), ("foo"), ( ""), 127, "foo"));
  (bop()->shWw ((aGeh.operator >(aGah)), ("foo"), ( ""), 130, "foo"));
  (bop()->shWw ((aGeh.operator >=(aGah)), ("foo"), ( ""), 131, "foo"));
  (bop()->shWw ((!(aGeh.operator <(aGah))), ("foo"), ( ""), 132, "foo"));
  (bop()->shWw ((!(aGeh.operator <=(aGah))), ("foo"), ( ""), 133, "foo"));
  (bop()->shWw ((aGeh.operator <(aGoh)), ("foo"), ( ""), 136, "foo"));
  (bop()->shWw ((aGeh.operator <=(aGoh)), ("foo"), ( ""), 137, "foo"));
  (bop()->shWw ((!(aGeh.operator >(aGoh))), ("foo"), ( ""), 138, "foo"));
  (bop()->shWw ((!(aGeh.operator >=(aGoh))), ("foo"), ( ""), 139, "foo"));
  (bop()->shWw ((aGoh.operator >(aGeh)), ("foo"), ( ""), 142, "foo"));
  (bop()->shWw ((aGoh.operator >=(aGeh)), ("foo"), ( ""), 143, "foo"));
  (bop()->shWw ((!(aGoh.operator <(aGeh))), ("foo"), ( ""), 144, "foo"));
  (bop()->shWw ((!(aGoh.operator <=(aGeh))), ("foo"), ( ""), 145, "foo"));
  (bop()->shWw ((aGah.operator >(aGoh)), ("foo"), ( ""), 152, "foo"));
  (bop()->shWw ((aGah.operator >=(aGoh)), ("foo"), ( ""), 153, "foo"));
  (bop()->shWw ((!(aGah.operator <(aGoh))), ("foo"), ( ""), 154, "foo"));
  (bop()->shWw ((!(aGah.operator <=(aGoh))), ("foo"), ( ""), 155, "foo"));
  (bop()->shWw ((aGoh.operator <(aGah)), ("foo"), ( ""), 158, "foo"));
  (bop()->shWw ((aGoh.operator <=(aGah)), ("foo"), ( ""), 159, "foo"));
  (bop()->shWw ((!(aGoh.operator >(aGah))), ("foo"), ( ""), 160, "foo"));
  (bop()->shWw ((!(aGoh.operator >=(aGah))), ("foo"), ( ""), 161, "foo"));
}

brgds, H-P

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