Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -31929,7 +31929,19 @@ /// Given a constraint letter, return the type of constraint for this target. X86TargetLowering::ConstraintType X86TargetLowering::getConstraintType(StringRef Constraint) const { - if (Constraint.size() == 1) { + if (Constraint.size() == 2) { + switch (Constraint[0]) { + default: + break; + case 'Y': + switch (Constraint[1]) { + default: + break; + case 'k': + return C_Register; + } + } + } else if (Constraint.size() == 1) { switch (Constraint[0]) { case 'R': case 'q': @@ -31942,6 +31954,7 @@ case 'Y': case 'l': return C_RegisterClass; + case 'k': // AVX512 masking registers. case 'a': case 'b': case 'c': @@ -32008,12 +32021,24 @@ if (type->isX86_MMXTy() && Subtarget.hasMMX()) weight = CW_SpecificReg; break; - case 'x': case 'Y': + // Impliment Y (two letters variant) constraints handle here. + if (constraint[1] == 'k') { + // Support for 'Yk' (similarly to the 'k' variant below). + weight = CW_SpecificReg; + break; + } + // Else fall through. + case 'x': + //'x' or 'Y' constraint treatment. 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(info.CallOperandVal)) { if (C->getZExtValue() <= 31) @@ -32290,6 +32315,21 @@ // 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. + if (VT == MVT::i32) + return std::make_pair(0U, &X86::VK32RegClass); + if (VT == MVT::i16) + return std::make_pair(0U, &X86::VK16RegClass); + if (VT == MVT::i8) + return std::make_pair(0U, &X86::VK8RegClass); + if (VT == MVT::i1) + return std::make_pair(0U, &X86::VK1RegClass); + if (VT == 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) @@ -32381,6 +32421,26 @@ } break; } + } else if (Constraint.size() == 2 && Constraint[0] == 'Y') { + switch (Constraint[1]) { + default: + break; + case 'k': + // This regiter class doesn't allocate k0 for masked vector operation. + if (Subtarget.hasAVX512()) { // Only supported in AVX512. + if (VT == MVT::i32) + return std::make_pair(0U, &X86::VK32WMRegClass); + if (VT == MVT::i16) + return std::make_pair(0U, &X86::VK16WMRegClass); + if (VT == MVT::i8) + return std::make_pair(0U, &X86::VK8WMRegClass); + if (VT == MVT::i1) + return std::make_pair(0U, &X86::VK1WMRegClass); + if (VT == MVT::i64) + return std::make_pair(0U, &X86::VK64WMRegClass); + } + break; + } } // Use the default implementation in TargetLowering to convert the register