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)); }