alexfrol created this revision.
alexfrol added a reviewer: echristo.
alexfrol added a subscriber: cfe-commits.
alexfrol set the repository for this revision to rL LLVM.

Implement analysis of 5 new inline asm constraints: 'v', 'k', 'Y2', 'Yk', 'Yz'.

This adds front-end support for issues reported in http://llvm.org/PR13199 and 
http://llvm.org/PR22013 on x86 targets.
These constraints will need backend support.

Repository:
  rL LLVM

http://reviews.llvm.org/D11419

Files:
  lib/Basic/Targets.cpp
  test/CodeGen/mult-alt-x86.c

Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -3484,9 +3484,12 @@
     default:
       return false;
     case '0': // First SSE register.
-    case 't': // Any SSE register, when SSE2 is enabled.
+    case '2': // Any SSE register.
     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
+    case 'k': // k1-k7 mask registers, when AVX512F is enabled.
     case 'm': // Any MMX register, when inter-unit moves enabled.
+    case 't': // Any SSE register, when SSE2 is enabled.
+    case 'z': // xmm0 register.
       Info.setAllowsRegister();
       return true;
     }
@@ -3508,6 +3511,8 @@
   case 'q': // Any register accessible as [r]l: a, b, c, and d.
   case 'y': // Any MMX register.
   case 'x': // Any SSE register.
+  case 'v': // Any SSE register. This is AVX-512 specific.
+  case 'k': // Any mask register. This is AVX-512 specific.
   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
   case 'l': // "Index" registers: any general register that can be used as an
@@ -3547,6 +3552,10 @@
   case 't':
   case 'u':
     return Size <= 128;
+  case 'v':
+  case 'k':
+    // 'v' and 'k' constraints can be used if target supports AVX512F.
+    return SSELevel >= AVX512F && Size <= 512U;
   case 'x':
     if (SSELevel >= AVX512F)
       // 512-bit zmm registers can be used if target supports AVX512F.
@@ -3562,14 +3571,20 @@
     case 'm':
       // 'Ym' is synonymous with 'y'.
       return Size <= 64;
+    case 'z':
+    case '2':
     case 'i':
     case 't':
-      // 'Yi' and 'Yt' are synonymous with 'x' when SSE2 is enabled.
+      // 'Yz' constrains to xmm0.
+      // 'Y2', 'Yi' and 'Yt' are synonymous with 'x' when SSE2 is enabled.
       if (SSELevel >= AVX512F)
         return Size <= 512U;
       else if (SSELevel >= AVX)
         return Size <= 256U;
       return SSELevel >= SSE2 && Size <= 128U;
+    case 'k':
+      // 'Yk' denotes k1-k7 mask registers. This is AVX512F-only feature.
+      return SSELevel >= AVX512F && Size <= 512U;
     }
 
   }
Index: test/CodeGen/mult-alt-x86.c
===================================================================
--- test/CodeGen/mult-alt-x86.c
+++ test/CodeGen/mult-alt-x86.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple i686 -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -triple x86_64 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64 -target-feature +avx512f -DAVX512 -emit-llvm %s -o - | FileCheck %s
 
 int mout0;
 int min1;
@@ -109,14 +110,39 @@
   asm("foo %1,%0" : "=x" (dout0) : "x" (din1));
 }
 
+// CHECK: @single_v
+void single_v()
+{
+  // 'v' constraint is AVX-512 specific.
+#ifdef AVX512
+  // CHECK-AVX512: asm "foo $1,$0", "=v,v[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=v" (dout0) : "v" (din1));
+#endif // AVX512
+}
+
+// CHECK: @single_k
+void single_k()
+{
+  // 'k' constraint is AVX-512 specific.
+#ifdef AVX512
+  // CHECK-AVX512: asm "foo $1,$0", "=k,k[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=k" (dout0) : "k" (din1));
+#endif // AVX512
+}
+
 // CHECK: @single_Y
 void single_Y()
 {
-  // 'Y' constraint currently broken.
+  // 'Y' constraints are currently broken.
   //asm("foo %1,%0" : "=Y0" (mout0) : "Y0" (min1));
   //asm("foo %1,%0" : "=Yz" (mout0) : "Yz" (min1));
   //asm("foo %1,%0" : "=Yt" (mout0) : "Yt" (min1));
+  //asm("foo %1,%0" : "=Y2" (mout0) : "Y2" (min1));
   //asm("foo %1,%0" : "=Yi" (mout0) : "Yi" (min1));
+  // 'Yk' constraint is AVX-512 specific.
+#ifdef AVX512
+  //asm("foo %1,%0" : "=Yk" (mout0) : "Yk" (min1));
+#endif // AVX512
   //asm("foo %1,%0" : "=Ym" (mout0) : "Ym" (min1));
 }
 
@@ -296,14 +322,39 @@
   asm("foo %1,%0" : "=r,x,m" (dout0) : "r,x,m" (din1));
 }
 
+// CHECK: @multi_v
+void multi_v()
+{
+  // 'v' constraint is AVX-512 specific.
+#ifdef AVX512
+  // CHECK-AVX512: asm "foo $1,$0", "=*r|v|m,r|v|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=r,v,m" (dout0) : "r,v,m" (din1));
+#endif // AVX512
+}
+
+// CHECK: @multi_k
+void multi_k()
+{
+  // 'k' constraint is AVX-512 specific.
+#ifdef AVX512
+  // CHECK-AVX512: asm "foo $1,$0", "=*r|k|m,r|k|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}})
+  asm("foo %1,%0" : "=r,k,m" (dout0) : "r,k,m" (din1));
+#endif // AVX512
+}
+
 // CHECK: @multi_Y
-void multi_Y0()
+void multi_Y()
 {
-  // Y constraint currently broken.
+  // 'Y' constraints are currently broken.
   //asm("foo %1,%0" : "=r,Y0,m" (mout0) : "r,Y0,m" (min1));
   //asm("foo %1,%0" : "=r,Yz,m" (mout0) : "r,Yz,m" (min1));
   //asm("foo %1,%0" : "=r,Yt,m" (mout0) : "r,Yt,m" (min1));
+  //asm("foo %1,%0" : "=r,Y2,m" (mout0) : "r,Y2,m" (min1));
   //asm("foo %1,%0" : "=r,Yi,m" (mout0) : "r,Yi,m" (min1));
+  // 'Yk' constraint is AVX-512 specific.
+#ifdef AVX512
+  //asm("foo %1,%0" : "=r,Yk,m" (mout0) : "r,Yk,m" (min1));
+#endif // AVX512
   //asm("foo %1,%0" : "=r,Ym,m" (mout0) : "r,Ym,m" (min1));
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to