Bug 10153

Summary: [3.3/3.4 regression] selection of %dil or %sil on ia32 by valid C source
Product: gcc Reporter: etienne.lorrain
Component: inline-asmAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: adam, aoliva, dacut, etienne.lorrain, gcc-bugs, nkoch, normvcr, richardpku, xnavara
Priority: P2 Keywords: wrong-code
Version: 3.2   
Target Milestone: 3.3.1   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2003-05-28 04:48:23

Description etienne.lorrain 2003-03-19 17:36:00 UTC
Just compile this, and look at the comment
"automatic size decision there"
(lots of comment removed and macro expanded...)
Works up to gcc-3.0.4, not after 3.1

etienne@fulbert:~/gcc/gujin$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-linux/3.2.3/specs
Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,proto,pascal,objc,ada --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.2 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-java-gc=boehm --enable-objc-gc i386-linux
Thread model: posix
gcc version 3.2.3 20030309 (Debian prerelease)
etienne@fulbert:~/gcc/gujin$
etienne@fulbert:~/gcc/gujin$ cat user.i
extern unsigned char VGA_valid_mode[];

extern inline unsigned
divrem8 (unsigned short oper, unsigned char *rem)
  {
  unsigned divider;

  asm (
"       aam     $8                      # operand in ax         \n"
"       movb    %%al,%%cl               # remainder             \n"
"       movzbl  %%ah,%%eax              # divider               \n"
        : "=a" (divider), "=c" (*rem) : "a" (oper) );
  return divider;
  }

extern inline void VIDEO_mode_invalidate (unsigned char mode)
  {

  unsigned char shift;
  unsigned index = divrem8 (mode, &shift);
  unsigned char tmp = ({
         typeof (VGA_valid_mode[index]) returned;
         asm volatile (
 "      # automatic size decision there:        \n"
 "      mov     %%cs:%a1,%0                     \n"
         : "=r" (returned) : "g" (&VGA_valid_mode[index]));
         returned; }) & ~(1 << shift);

  asm volatile (
 "      movb    %b0,%%cs:%a1            \n"
        : : "qi" (tmp), "r" (&VGA_valid_mode[index])
        );
  }

void VGA_init (void)
  {
  extern char tmpstatictable[15];
  unsigned i;

  for (i = 0; i <= 0x7F; i++) {
      unsigned char shift;
      unsigned short offset = divrem8 (i, &shift);

      if ((tmpstatictable[offset] & (1 << shift)) == 0)
          VIDEO_mode_invalidate (i);
      }
  }
etienne@fulbert:~/gcc/gujin$ gcc -Os user.i
/tmp/ccWPbdd5.s: Assembler messages:
/tmp/ccWPbdd5.s:35: Error: bad register name `%sil'

Release:
gcc version 3.2.3 20030309 (Debian prerelease)

Environment:
Linux Debian ia32
Comment 1 Dara Hazeghi 2003-05-10 13:51:39 UTC
From: Dara Hazeghi <dhazeghi@yahoo.com>
To: gcc-gnats@gcc.gnu.org, etienne.lorrain@masroudeau.com
Cc:  
Subject: Re: inline-asm/10153: selection of %dil or %sil on ia32 arch by valid C source
Date: Sat, 10 May 2003 13:51:39 -0700

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit- 
 trail&database=gcc&pr=10153
 
 Hello,
 
 on gcc 3.2.3 and 3.3 branch, I get the same error as mentioned in this  
 report, but on mainline (20030509), this code compiles and assembles  
 fine.
 
 Dara
 

Comment 2 etienne.lorrain 2003-05-12 06:59:00 UTC
From: etienne.lorrain@masroudeau.com
To: "Dara Hazeghi" <dhazeghi@yahoo.com>
Cc: gcc-gnats@gcc.gnu.org,etienne.lorrain@masroudeau.com
Subject: Re: inline-asm/10153: selection of %dil or %sil on ia32 arch by 
     valid C source
Date: Mon, 12 May 2003 06:59:00 +0100 (BST)

 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10153
 >
 > Hello,
 >
 > on gcc 3.2.3 and 3.3 branch, I get the same error as mentioned in this
 > report, but on mainline (20030509), this code compiles and assembles
 > fine.
 >
 > Dara
 >
 
   Hello,
 
   I did this morning, in an empty directory:
 lynx http://prdownloads.sourceforge.net/gujin/gujin-0.7.tgz?download
 ncftpget
 ftp://sources.redhat.com/pub/binutils/releases/binutils-2.13.2.1.tar.gz
 ncftpget ftp://sources.redhat.com/pub/gcc/snapshots/gcc-3.3-20030508.tar.gz
 tar -xvzf gujin-0.7.tgz
 
 -------------------------------------------
   Here I had to modify gujin/Makefile :
 @@ -1564,7 +1564,7 @@
         cd $(notdir $(basename $(basename $(subst core-,,$(LAST_GCC))))) ; \
         mkdir build ;                                                   \
         cd build/ ;                                                     \
 -       ../configure --prefix=$(P_PWD)/toolchain --enable-languages=C ; \
 +       ../configure --prefix=$(P_PWD)/toolchain --enable-languages=c ; \
         make bootstrap-lean ;                                           \
         make install )
  endif
 -------------------
   Is that a philosophycal change, no more "C" language, only "c" ????
 -------------------------------------------
 
 cd gujin
 make toolchain
 make dep boot.exe
 
   (all of this is shown without their output - quite long)
   At some point I got:
 ....
 GCC: gcc (GCC) 3.3 20030509 (prerelease), Binutils: GNU ld version 2.13.2.1
 ....
 /home/etienne/prjgcc/toolchain/bin/gcc -fstrict-aliasing -falign-loops=1
 -falign-jumps=1 -falign-functions=2  -mno-align-double
 -mpreferred-stack-boundary=2 -fomit-frame-pointer -march=i386 -mrtd
 -fno-builtin -fno-schedule-insns2 -finline-limit=10000 -Os -Wall
 -Wno-format -Wno-main -Wstrict-prototypes -Wundef -Wpointer-arith
 -Wcast-align -Wwrite-strings -Wsign-compare -Wdisabled-optimization 
 -ffunction-sections -include code16.h -DDEBUG="(DEBUG_STACK)"
 -DUSER_SUPPORT="(VGA_SUPPORT|VGA_EXTENDED|VESA_WINDOW|VESA_WINFUNCTION|VESA_LINEAR|VESA_EDID|VESA_RECALC|VESA_2WINDOWS|VESA_HARDWINDOW|VESA_PMINFO|VESA_16BPP|VESA_32BPP|VESA_24BPP|VESA_4BPP_EGA|VESA_4BPP_TEXT|VESA_8BPP|SERIAL_VT100|SERIAL_VT420|BIOS_MOUSE_SUPPORT|SERIAL_MOUSE_SUPPORT|JOYSTICK_SUPPORT)"
 -DDISK_SUPPORT="(BIOS_SUPPORT|EBIOS_SUPPORT|IDE_SUPPORT|DOS_SUPPORT|E2FS_PROBE|FAT12_PROBE|FAT16_PROBE|FAT32_PROBE|BOOTSECT_PROBE)"
 -DSETUP="(APPLICATION|CODE_SEGMENT|EXTRA_SEGMENT|GC_SECTION|ASSEMBLY_CISC|UPDATE_BOOTPARAM|USE_INT1587|MINIDEBUG)"
 -DLANGUAGE=ENGLISH  -S -o user.S user.c
 In file included from user.c:43:
 ega.h: In function `_EGA_read_write_mode':
 ega.h:172: warning: dereferencing type-punned pointer will break
 strict-aliasing rules
 ega.h: In function `_EGA_setup':
 ega.h:178: warning: dereferencing type-punned pointer will break
 strict-aliasing rules
 sed '/.align 32/d' < user.S > user.s
 /home/etienne/prjgcc/toolchain/bin/as -acdhls=user.lis -o user.o user.s
 user.s: Assembler messages:
 user.s:2962: Error: bad register name `%dil'
 make: *** [user.o] Error 1
 rm user.S boot.s user.s boot.S
 
   So the bug is still present in this version.
   I do not know about my "reduced to the simplest source" bug report.
 
   I have to check about new warning "dereferencing type-punned".
 
 
   Regards,
   Etienne.
Comment 3 Andrew Pinski 2003-05-28 04:48:23 UTC
I can see the problem with the mainline (20030527) with `gcc -Os pr10153.i -march=i386 
-c -save-temps', `gcc -Os pr10153.i -march=i486 -c -save-temps', `gcc -Os pr10153.i -
march=i586 -c -save-temps'
I think Dara was getting lucky with i686.

I think sil and dil are both x86-64 registers which are not defined on ia32.

I think you were luck that gcc-3.0.4 works, but still it is a regression.

Since the "g" constrant is right here, but someone with more knowledge of the ia32 
backend should look at it.
Comment 4 Richard Henderson 2003-06-12 18:18:33 UTC
I'm of the opinion that the source is invalid.  Using a "=q" constraint
instead of an "=r" constraint properly shows that the compiler must choose
one of the four "low byte" registers.

You might object that the compiler should "know" that it cannot place a
character object into %esi/%edi/%ebp, but that's not true at all -- we 
cannot store a character to memory from those registers, but we can hold
a character value in those registers.
Comment 5 Andrew Pinski 2003-10-31 22:06:56 UTC
*** Bug 12856 has been marked as a duplicate of this bug. ***
Comment 6 dacut 2004-02-13 15:13:33 UTC
Richard -- agreed with your comment, but I think the larger issue is that GCC is
choosing phantom registers (%sil/%dil).  Yonetani Tomokazu on the DragonFly BSD
lists has seen this issue compiling straight C code with "-march=pentium4 -O".

Any ideas where to look?  I'll try to get a sample of failing source (along with
GCC versions and the other goodies) and see where it's dying.
Comment 7 dacut 2004-02-14 04:22:55 UTC
After some further discussion on the DragonFly lists and further reading on my
part, I found out that %sil and %dil are the 8-bit equivalents of %al, %bl, etc.
 (Watch the light bulb undim in my head here :-)

It would be better if gcc were able to diagnose the problem code better (ensure
that the architecture is valid before emitting a %sil/%dil/%bpl/%spl register)
-- I'll see if I can't ponder on this and propose a small patch.
Comment 8 Andrew Pinski 2005-02-15 19:10:21 UTC
*** Bug 19979 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2006-10-24 16:14:22 UTC
*** Bug 29579 has been marked as a duplicate of this bug. ***
Comment 10 Andreas Schwab 2007-10-06 07:50:08 UTC
*** Bug 33674 has been marked as a duplicate of this bug. ***
Comment 11 Andrew Pinski 2011-03-30 19:41:02 UTC
*** Bug 48347 has been marked as a duplicate of this bug. ***
Comment 12 GCC Commits 2021-07-22 16:15:36 UTC
The master branch has been updated by Andrew Pinski <pinskia@gcc.gnu.org>:

https://gcc.gnu.org/g:8819419ba1d397c0444d89079ec16657a09914fb

commit r12-2473-g8819419ba1d397c0444d89079ec16657a09914fb
Author: Andrew Pinski <apinski@marvell.com>
Date:   Tue Jul 20 11:25:43 2021 -0700

    Fix PR 10153: tail recusion for vector types.
    
    The problem here is we try to an initialized value
    from a scalar constant. For vectors we need to do
    a vect_dup instead.  This fixes that issue by using
    build_{one,zero}_cst instead of integer_{one,zero}_node
    when calling create_tailcall_accumulator.
    
    Changes from v1:
    * v2: Use build_{one,zero}_cst and get the correct type before.
    
    OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions.
    
    gcc/ChangeLog:
    
            PR tree-optimization/10153
            * tree-tailcall.c (create_tailcall_accumulator):
            Don't call fold_convert as the type should be correct already.
            (tree_optimize_tail_calls_1): Use build_{one,zero}_cst instead
            of integer_{one,zero}_node for the call of create_tailcall_accumulator.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/10153
            * gcc.c-torture/compile/pr10153-1.c: New test.
            * gcc.c-torture/compile/pr10153-2.c: New test.
Comment 13 Alexandre Oliva 2024-03-23 06:51:40 UTC
FTR, the fix and the testcases were for bug 101534.