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
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits