diff mbox

[RFA,i386] : Warn for 64-bit values in general-reg asm operands and error out for 8-bit values in invalid GR asm operand

Message ID CAFULd4ZM+MZ-eaMihtPA9DCAjm7y8Kf2UVKP9z3D3q0Y9zzOJw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak March 1, 2017, 7:26 p.m. UTC
On Wed, Mar 1, 2017 at 11:41 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Mar 1, 2017 at 10:00 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Wed, Mar 1, 2017 at 9:48 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>> On Wed, Mar 01, 2017 at 09:34:53AM +0100, Uros Bizjak wrote:
>>>> Some more thoughts on 64-bit reg on 32-bit targets warning.
>>>>
>>>> Actually, we never *print* register name for instruction that use "A"
>>>> constraint, since %eax/%edx is always implicit  The warning does not
>>>> deal with constraints, so unless we want to output DImode register
>>>> name, there is no warning.
>>>
>>> Ah, indeed, we don't have a modifier that would print the high register
>>> of a register pair (i.e. essentially print REGNO (x) + 1 instead of REGNO
>>> (x)), guess that might be useful not just for 64-bit GPR operands in 32-bit
>>> code, but also 128-bit GPR operands in 64-bit code.
>>
>> The issue here is that (modulo ax/dx with "A" constraint) we don't
>> guarantee double-register sequence order, so any change in register
>> allocation order would break any assumptions. For implicit ax/dx, user
>> should explicitly use register name (e.g. DImode operand in "rdtscp;
>> mov %0, mem" asm should be corrected to use %%eax instead of %0).
>>
>> And, yes - we should add similar warning for 128-bit GPRs. The only
>> way to use register pair with  width > machine_mode is with implicit
>> operands or with explicit regnames.
>
> Something like the following patch I'm testing:

Attached is the patch I have committed to mainline SVN after a full
bootstrap and regression test.

2017-03-01  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.c (print_reg): Warn for values of
    unsupported size in integer register.

testsuite/ChangeLog:

2017-03-01  Uros Bizjak  <ubizjak@gmail.com>

    * gcc.target/i386/invsize-2.c: New test.
    * gcc.target/i386/invsize-3.c: Ditto.
    * gcc.target/i386/invsize-4.c: Ditto.
    * gcc.target/i386/pr66274.c: Expect "unsuported size" warning.
    * gcc.target/i386/stackalign/asm-1.c: Ditto.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline.

Uros.
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 245811)
+++ config/i386/i386.c	(working copy)
@@ -17646,13 +17646,16 @@  print_reg (rtx x, int code, FILE *file)
 
   switch (msize)
     {
+    case 16:
+    case 12:
     case 8:
+      if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
+	warning (0, "unsupported size for integer register");
+      /* FALLTHRU */
     case 4:
       if (LEGACY_INT_REGNO_P (regno))
-	putc (msize == 8 && TARGET_64BIT ? 'r' : 'e', file);
+	putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
       /* FALLTHRU */
-    case 16:
-    case 12:
     case 2:
     normal:
       reg = hi_reg_name[regno];
Index: testsuite/gcc.target/i386/invsize-2.c
===================================================================
--- testsuite/gcc.target/i386/invsize-2.c	(nonexistent)
+++ testsuite/gcc.target/i386/invsize-2.c	(working copy)
@@ -0,0 +1,7 @@ 
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "" } */
+
+void foo (long long x)
+{
+  __asm__ volatile ("# %0" : : "r" (x));
+} /* { dg-warning "unsupported size" }  */
Index: testsuite/gcc.target/i386/invsize-3.c
===================================================================
--- testsuite/gcc.target/i386/invsize-3.c	(nonexistent)
+++ testsuite/gcc.target/i386/invsize-3.c	(working copy)
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void foo (long double x)
+{
+  __asm__ volatile ("# %0" : : "r" (x));
+} /* { dg-warning "unsupported size" }  */
Index: testsuite/gcc.target/i386/invsize-4.c
===================================================================
--- testsuite/gcc.target/i386/invsize-4.c	(nonexistent)
+++ testsuite/gcc.target/i386/invsize-4.c	(working copy)
@@ -0,0 +1,7 @@ 
+/* { dg-do compile { target int128 } } */
+/* { dg-options "" } */
+
+void foo (__int128 x)
+{
+  __asm__ volatile ("# %0" : : "r" (x));
+} /* { dg-warning "unsupported size" }  */
Index: testsuite/gcc.target/i386/pr66274.c
===================================================================
--- testsuite/gcc.target/i386/pr66274.c	(revision 245811)
+++ testsuite/gcc.target/i386/pr66274.c	(working copy)
@@ -3,7 +3,7 @@ 
 
 void f()
 {
-  asm ("push %0" : : "r" ((unsigned long long) 456));
-}
+  asm ("push %0" : : "r" ((unsigned long long) 456 >> 32));
+} /* { dg-warning "unsupported size" }  */
 
-/* { dg-final { scan-assembler-not "push %r" } } */
+/* { dg-final { scan-assembler-not "push\[ \t]+%r" } } */
Index: testsuite/gcc.target/i386/stackalign/asm-1.c
===================================================================
--- testsuite/gcc.target/i386/stackalign/asm-1.c	(revision 245811)
+++ testsuite/gcc.target/i386/stackalign/asm-1.c	(working copy)
@@ -4,4 +4,4 @@ 
 
 /* This case is to detect a compile time regression introduced in stack
    branch development. */
-void f(){asm("%0"::"r"(1.5F));}void g(){asm("%0"::"r"(1.5));}
+void f(){asm("%0"::"r"(1.5F));}void g(){asm("%0"::"r"(1.5));} /* { dg-warning "unsupported size" }  */