nickdesaulniers created this revision.
nickdesaulniers added reviewers: ahatanak, craig.topper.
Herald added subscribers: cfe-commits, dexonsmith.
Herald added a project: clang.
nickdesaulniers added a subscriber: dwmw2.

As pointed out by David Woodhouse and Akira Hatanaka in
https://bugs.llvm.org/show_bug.cgi?id=33587, Clang was inconsistent with
GCC validating inline asm constraints for -m32.  For -m32 Clang was
disallowing 64b inputs/outputs to inline asm with "q" constraints, but
not for "r" constraints.  This change improves Clang's validations to
match GCC's.

Adds a test case in x86_32-inline-asm.c, and fixes up previous tests
that used "r"+64b operands+32b x86 targets.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79804

Files:
  clang/lib/Basic/Targets/X86.h
  clang/test/CodeGen/mult-alt-generic.c
  clang/test/CodeGen/mult-alt-x86.c
  clang/test/CodeGen/x86_32-inline-asm.c
  clang/test/Parser/no-gnu-inline-asm.c

Index: clang/test/Parser/no-gnu-inline-asm.c
===================================================================
--- clang/test/Parser/no-gnu-inline-asm.c
+++ clang/test/Parser/no-gnu-inline-asm.c
@@ -12,7 +12,7 @@
 asm(" "); // Whitespace is OK
 
 void f (void) {
-  long long foo = 0, bar;
+  long foo = 0, bar;
   asm volatile("INST %0, %1" : "=r"(foo) : "r"(bar)); // expected-error {{GNU-style inline assembly is disabled}}
   asm (""); // Empty is OK
   return;
Index: clang/test/CodeGen/x86_32-inline-asm.c
===================================================================
--- clang/test/CodeGen/x86_32-inline-asm.c
+++ clang/test/CodeGen/x86_32-inline-asm.c
@@ -34,6 +34,7 @@
   unsigned int port;
   __asm__ volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); // No error expected.
 
+  __asm__ volatile("outb %0, %w1" : : "r" (val), "Nd" (port)); // expected-error {{invalid input size for constraint 'r'}}
   __asm__ volatile("outb %0, %w1" : : "R" (val), "Nd" (port)); // expected-error {{invalid input size for constraint 'R'}}
   __asm__ volatile("outb %0, %w1" : : "q" (val), "Nd" (port)); // expected-error {{invalid input size for constraint 'q'}}
   __asm__ volatile("outb %0, %w1" : : "Q" (val), "Nd" (port)); // expected-error {{invalid input size for constraint 'Q'}}
@@ -48,6 +49,7 @@
   __asm__ volatile("foo1 %0" : : "u" (val256)); // expected-error {{invalid input size for constraint 'u'}}
   __asm__ volatile("foo1 %0" : : "x" (val512)); // expected-error {{invalid input size for constraint 'x'}}
 
+  __asm__ volatile("foo1 %0" : "=r" (val)); // expected-error {{invalid output size for constraint '=r'}}
   __asm__ volatile("foo1 %0" : "=R" (val)); // expected-error {{invalid output size for constraint '=R'}}
   __asm__ volatile("foo1 %0" : "=q" (val)); // expected-error {{invalid output size for constraint '=q'}}
   __asm__ volatile("foo1 %0" : "=Q" (val)); // expected-error {{invalid output size for constraint '=Q'}}
Index: clang/test/CodeGen/mult-alt-x86.c
===================================================================
--- clang/test/CodeGen/mult-alt-x86.c
+++ clang/test/CodeGen/mult-alt-x86.c
@@ -4,6 +4,8 @@
 int mout0;
 int min1;
 int marray[2];
+float fout0;
+float fin1;
 double dout0;
 double din1;
 
@@ -285,15 +287,15 @@
 // CHECK: @multi_y
 void multi_y()
 {
-  // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}})
-  asm("foo %1,%0" : "=r,y,m" (dout0) : "r,y,m" (din1));
+  // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](float* @fout0, float {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=r,y,m" (fout0) : "r,y,m" (fin1));
 }
 
 // CHECK: @multi_x
 void multi_x()
 {
-  // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}})
-  asm("foo %1,%0" : "=r,x,m" (dout0) : "r,x,m" (din1));
+  // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](float* @fout0, float {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=r,x,m" (fout0) : "r,x,m" (fin1));
 }
 
 // CHECK: @multi_Y
@@ -352,15 +354,15 @@
 // CHECK: @multi_G
 void multi_G()
 {
-  // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}})
-  asm("foo %1,%0" : "=r,m,m" (mout0) : "r,G,m" (1.0));
+  // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* @mout0, float {{1.[0]+e[+]*[0]+}})
+  asm("foo %1,%0" : "=r,m,m" (mout0) : "r,G,m" (1.0f));
 }
 
 // CHECK: @multi_C
 void multi_C()
 {
-  // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}})
-  asm("foo %1,%0" : "=r,m,m" (mout0) : "r,C,m" (1.0));
+  // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* @mout0, float {{1.[0]+e[+]*[0]+}})
+  asm("foo %1,%0" : "=r,m,m" (mout0) : "r,C,m" (1.0f));
 }
 
 // CHECK: @multi_e
Index: clang/test/CodeGen/mult-alt-generic.c
===================================================================
--- clang/test/CodeGen/mult-alt-generic.c
+++ clang/test/CodeGen/mult-alt-generic.c
@@ -86,17 +86,17 @@
 // CHECK: @single_E
 void single_E()
 {
-  register double out0 = 0.0;
-  // CHECK: call double asm "foo $1,$0", "=r,E[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r" (out0) : "E" (1.0e+01));
+  register float out0 = 0.0f;
+  // CHECK: call float asm "foo $1,$0", "=r,E[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r" (out0) : "E" (1.0e+01f));
 }
 
 // CHECK: @single_F
 void single_F()
 {
-  register double out0 = 0.0;
-  // CHECK: call double asm "foo $1,$0", "=r,F[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r" (out0) : "F" (1.0));
+  register float out0 = 0.0f;
+  // CHECK: call float asm "foo $1,$0", "=r,F[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r" (out0) : "F" (1.0f));
 }
 
 // CHECK: @single_s
@@ -219,17 +219,17 @@
 // CHECK: @multi_E
 void multi_E()
 {
-  register double out0 = 0.0;
-  // CHECK: call double asm "foo $1,$0", "=r|r,r|E[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r,r" (out0) : "r,E" (1.0e+01));
+  register float out0 = 0.0f;
+  // CHECK: call float asm "foo $1,$0", "=r|r,r|E[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r,r" (out0) : "r,E" (1.0e+01f));
 }
 
 // CHECK: @multi_F
 void multi_F()
 {
-  register double out0 = 0.0;
-  // CHECK: call double asm "foo $1,$0", "=r|r,r|F[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r,r" (out0) : "r,F" (1.0));
+  register float out0 = 0.0f;
+  // CHECK: call float asm "foo $1,$0", "=r|r,r|F[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r,r" (out0) : "r,F" (1.0f));
 }
 
 // CHECK: @multi_s
@@ -265,10 +265,10 @@
   asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1));
   // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i{{32|64}} 0, i{{32|64}} 0))
   asm("foo %1,%0" : "=r,r" (out0) : "r,X" (marray));
-  // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0e+01));
-  // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}})
-  asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0));
+  // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0e+01f));
+  // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](float {{[0-9.eE+-]+}})
+  asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0f));
 }
 
 // CHECK: @multi_p
Index: clang/lib/Basic/Targets/X86.h
===================================================================
--- clang/lib/Basic/Targets/X86.h
+++ clang/lib/Basic/Targets/X86.h
@@ -412,6 +412,7 @@
     switch (Constraint[0]) {
     default:
       break;
+    case 'r':
     case 'R':
     case 'q':
     case 'Q':
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D79804: [x86] pre... Nick Desaulniers via Phabricator via cfe-commits

Reply via email to