summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Zuckerman <Michael.zuckerman@intel.com>2016-10-31 16:19:58 +0000
committerMichael Zuckerman <Michael.zuckerman@intel.com>2016-10-31 16:19:58 +0000
commitbff25831e0231f9bab9f5750e844917bf2aece26 (patch)
tree486b81b7fc8e38cc740735df75f0140722889e38 /lib
parent86d93952ed625036fdfb652cc25c41757862d815 (diff)
[x86][inline-asm][AVX512][llvm][PART-2]
Introducing "k" and "Yk" constraints for extended inline assembly, enabling use of AVX512 masked vectorized instructions. Commit on behalf of mharoush Extending inline assembly support, compatible with GCC as folowing: "k" constraint hints the compiler to select any of AVX512 k0-k7 registers. "Yk" constraint is a subset of "k" excluding k0 which is not allowd to be used as a mask. Reviewer: 1. rnk Differential Revision: https://reviews.llvm.org/D25062 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285591 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp69
1 files changed, 68 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 4ab3bd97377..243bd825132 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -32319,6 +32319,7 @@ X86TargetLowering::getConstraintType(StringRef Constraint) const {
case 'Y':
case 'l':
return C_RegisterClass;
+ case 'k': // AVX512 masking registers.
case 'a':
case 'b':
case 'c':
@@ -32342,6 +32343,19 @@ X86TargetLowering::getConstraintType(StringRef Constraint) const {
break;
}
}
+ else if (Constraint.size() == 2) {
+ switch (Constraint[0]) {
+ default:
+ break;
+ case 'Y':
+ switch (Constraint[1]) {
+ default:
+ break;
+ case 'k':
+ return C_Register;
+ }
+ }
+ }
return TargetLowering::getConstraintType(Constraint);
}
@@ -32385,16 +32399,28 @@ TargetLowering::ConstraintWeight
if (type->isX86_MMXTy() && Subtarget.hasMMX())
weight = CW_SpecificReg;
break;
+ case 'Y':
+ // Other "Y<x>" (e.g. "Yk") constraints should be implemented below.
+ if (constraint[1] == 'k') {
+ // Support for 'Yk' (similarly to the 'k' variant below).
+ weight = CW_SpecificReg;
+ break;
+ }
+ // Else fall through (handle "Y" constraint).
+ LLVM_FALLTHROUGH;
case 'v':
if ((type->getPrimitiveSizeInBits() == 512) && Subtarget.hasAVX512())
weight = CW_Register;
LLVM_FALLTHROUGH;
case 'x':
- case 'Y':
if (((type->getPrimitiveSizeInBits() == 128) && Subtarget.hasSSE1()) ||
((type->getPrimitiveSizeInBits() == 256) && Subtarget.hasFp256()))
weight = CW_Register;
break;
+ case 'k':
+ // Enable conditional vector operations using %k<#> registers.
+ weight = CW_SpecificReg;
+ break;
case 'I':
if (ConstantInt *C = dyn_cast<ConstantInt>(info.CallOperandVal)) {
if (C->getZExtValue() <= 31)
@@ -32671,6 +32697,24 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
// TODO: Slight differences here in allocation order and leaving
// RIP in the class. Do they matter any more here than they do
// in the normal allocation?
+ case 'k':
+ if (Subtarget.hasAVX512()) {
+ // Only supported in AVX512 or later.
+ switch (VT.SimpleTy) {
+ default: break;
+ case MVT::i32:
+ return std::make_pair(0U, &X86::VK32RegClass);
+ case MVT::i16:
+ return std::make_pair(0U, &X86::VK16RegClass);
+ case MVT::i8:
+ return std::make_pair(0U, &X86::VK8RegClass);
+ case MVT::i1:
+ return std::make_pair(0U, &X86::VK1RegClass);
+ case MVT::i64:
+ return std::make_pair(0U, &X86::VK64RegClass);
+ }
+ }
+ break;
case 'q': // GENERAL_REGS in 64-bit mode, Q_REGS in 32-bit mode.
if (Subtarget.is64Bit()) {
if (VT == MVT::i32 || VT == MVT::f32)
@@ -32772,6 +32816,29 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
}
break;
}
+ } else if (Constraint.size() == 2 && Constraint[0] == 'Y') {
+ switch (Constraint[1]) {
+ default:
+ break;
+ case 'k':
+ // This register class doesn't allocate k0 for masked vector operation.
+ if (Subtarget.hasAVX512()) { // Only supported in AVX512.
+ switch (VT.SimpleTy) {
+ default: break;
+ case MVT::i32:
+ return std::make_pair(0U, &X86::VK32WMRegClass);
+ case MVT::i16:
+ return std::make_pair(0U, &X86::VK16WMRegClass);
+ case MVT::i8:
+ return std::make_pair(0U, &X86::VK8WMRegClass);
+ case MVT::i1:
+ return std::make_pair(0U, &X86::VK1WMRegClass);
+ case MVT::i64:
+ return std::make_pair(0U, &X86::VK64WMRegClass);
+ }
+ }
+ break;
+ }
}
// Use the default implementation in TargetLowering to convert the register