diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86FastISel.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86FastISel.cpp | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index ade4ff61762a..ff90b402b9b9 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -1376,7 +1376,6 @@ static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget) { /// If we have a comparison with RHS as the RHS of the comparison, return an /// opcode that works for the compare (e.g. CMP32ri) otherwise return 0. static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC) { - int64_t Val = RHSC->getSExtValue(); switch (VT.getSimpleVT().SimpleTy) { // Otherwise, we can't fold the immediate into this comparison. default: @@ -1384,21 +1383,13 @@ static unsigned X86ChooseCmpImmediateOpcode(EVT VT, const ConstantInt *RHSC) { case MVT::i8: return X86::CMP8ri; case MVT::i16: - if (isInt<8>(Val)) - return X86::CMP16ri8; return X86::CMP16ri; case MVT::i32: - if (isInt<8>(Val)) - return X86::CMP32ri8; return X86::CMP32ri; case MVT::i64: - if (isInt<8>(Val)) - return X86::CMP64ri8; // 64-bit comparisons are only valid if the immediate fits in a 32-bit sext // field. - if (isInt<32>(Val)) - return X86::CMP64ri32; - return 0; + return isInt<32>(RHSC->getSExtValue()) ? X86::CMP64ri32 : 0; } } @@ -3030,6 +3021,58 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { updateValueMap(II, ResultReg); return true; } + case Intrinsic::x86_sse42_crc32_32_8: + case Intrinsic::x86_sse42_crc32_32_16: + case Intrinsic::x86_sse42_crc32_32_32: + case Intrinsic::x86_sse42_crc32_64_64: { + if (!Subtarget->hasCRC32()) + return false; + + Type *RetTy = II->getCalledFunction()->getReturnType(); + + MVT VT; + if (!isTypeLegal(RetTy, VT)) + return false; + + unsigned Opc; + const TargetRegisterClass *RC = nullptr; + + switch (II->getIntrinsicID()) { + default: + llvm_unreachable("Unexpected intrinsic."); + case Intrinsic::x86_sse42_crc32_32_8: + Opc = X86::CRC32r32r8; + RC = &X86::GR32RegClass; + break; + case Intrinsic::x86_sse42_crc32_32_16: + Opc = X86::CRC32r32r16; + RC = &X86::GR32RegClass; + break; + case Intrinsic::x86_sse42_crc32_32_32: + Opc = X86::CRC32r32r32; + RC = &X86::GR32RegClass; + break; + case Intrinsic::x86_sse42_crc32_64_64: + Opc = X86::CRC32r64r64; + RC = &X86::GR64RegClass; + break; + } + + const Value *LHS = II->getArgOperand(0); + const Value *RHS = II->getArgOperand(1); + + Register LHSReg = getRegForValue(LHS); + Register RHSReg = getRegForValue(RHS); + if (!LHSReg || !RHSReg) + return false; + + Register ResultReg = fastEmitInst_rr(Opc, RC, LHSReg, RHSReg); + if (!ResultReg) + return false; + + updateValueMap(II, ResultReg); + return true; + } } } |