[Bug target/61810] New: init-regs.c papers over issues elsewhere

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Jul 15 13:07:00 GMT 2014


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61810

            Bug ID: 61810
           Summary: init-regs.c papers over issues elsewhere
           Product: gcc
           Version: 4.10.0
            Status: UNCONFIRMED
          Keywords: missed-optimization, wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
            Target: x86_64-*-*, i?86-*-*

Earlier this year Uli complained about undefined uses generating
code in the context of implementing _mm_undefined x86 intrinsics
in the "GCC way".  Example:

extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__,
__artificial__))
_mm_undefined_pd (void)
{ 
  __m128d __Y = __Y;
  return __Y;
}

and the culprit was found to be the init-regs pass which initializes
all must-undefined but used pseudos with zero.  That has been
introduced with the dataflow-merge with some big handwaving
comment (and no testcase as far as we could see):

/* Check all of the uses of pseudo variables.  If any use that is MUST
   uninitialized, add a store of 0 immediately before it.  For
   subregs, this makes combine happy.  For full word regs, this makes
   other optimizations, like the register allocator and the reg-stack
   happy as well as papers over some problems on the arm and other
   processors where certain isa constraints cannot be handled by gcc.
   These are of the form where two operands to an insn my not be the
   same.  The ra will only make them the same if they do not
   interfere, and this can only happen if one is not initialized.

   There is also the unfortunate consequence that this may mask some
   buggy programs where people forget to initialize stack variable.
   Any programmer with half a brain would look at the uninitialized
   variable warnings.  */

Of course earlier this year it wasn't the appropriate time to
kill off init-regs (which doesn't run at -O0 btw...).  But now
it is.

All of the issues in the comment at the top of init-regs.c
point to issues elsewhere - papering over them by means
of init-regs.c isn't a correct solution - especially as
passes between init-regs and $issue may expose must-undefined
but used pseudos (if-conversion for example).

Disabling init-regs.c by adjusting its gate to always return 0 causes

FAIL: gcc.dg/vect/vect-strided-a-u8-i8-gap7.c execution test

on x86_64 and

FAIL: gcc.dg/vect/vect-strided-a-u16-i4.c execution test
FAIL: gcc.dg/vect/vect-strided-a-u8-i8-gap7.c execution test
FAIL: gcc.dg/vect/vect-strided-u8-i8-gap7-big-array.c execution test
FAIL: gcc.dg/vect/vect-strided-a-u16-i4.c -flto -ffat-lto-objects execution
test
FAIL: gcc.dg/vect/vect-strided-a-u8-i8-gap7.c -flto -ffat-lto-objects execution 
test

on x86_64 -m32

no other FAILs (the comment hints at more issues on other targets).


Patch to disable init-regs (apart from the above bootstraps/tests ok
on x86_64)

Index: gcc/init-regs.c
=================================================================== 
--- gcc/init-regs.c     (revision 212520)
+++ gcc/init-regs.c     (working copy)
@@ -147,7 +147,7 @@ public:
   {}

   /* opt_pass methods: */
-  virtual bool gate (function *) { return optimize > 0; }
+  virtual bool gate (function *) { return 0; }
   virtual unsigned int execute (function *)
     {
       initialize_uninitialized_regs ();



More information about the Gcc-bugs mailing list