diff options
author | Craig Topper <craig.topper@gmail.com> | 2012-06-13 07:18:53 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2012-06-13 07:18:53 +0000 |
commit | cc95b57d42a4af1cbb0a0e4a4efc2133116dd21c (patch) | |
tree | c5200cf87afd379d7f5cf5f233f150956c023aee /lib | |
parent | 79248299f6ca12926088a4adebbbbe00b05a2642 (diff) |
Fix intrinsics for XOP frczss/sd instructions. These instructions only take one source register and zero the upper bits of the destination rather than preserving them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158396 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86InstrXOP.td | 18 | ||||
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 23 |
2 files changed, 28 insertions, 13 deletions
diff --git a/lib/Target/X86/X86InstrXOP.td b/lib/Target/X86/X86InstrXOP.td index 16a7a1a88a..8ec2c688d3 100644 --- a/lib/Target/X86/X86InstrXOP.td +++ b/lib/Target/X86/X86InstrXOP.td @@ -39,22 +39,16 @@ let isAsmParserOnly = 1 in { } // Scalar load 2 addr operand instructions -let Constraints = "$src1 = $dst" in { multiclass xop2opsld<bits<8> opc, string OpcodeStr, Intrinsic Int, Operand memop, ComplexPattern mem_cpat> { - def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, - VR128:$src2), - !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"), - [(set VR128:$dst, (Int VR128:$src1, VR128:$src2))]>, VEX; - def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, - memop:$src2), - !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"), - [(set VR128:$dst, (Int VR128:$src1, - (bitconvert mem_cpat:$src2)))]>, VEX; + def rr : IXOP<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), + !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), + [(set VR128:$dst, (Int VR128:$src))]>, VEX; + def rm : IXOP<opc, MRMSrcMem, (outs VR128:$dst), (ins memop:$src), + !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), + [(set VR128:$dst, (Int (bitconvert mem_cpat:$src)))]>, VEX; } -} // Constraints = "$src1 = $dst" - let isAsmParserOnly = 1 in { defm VFRCZSS : xop2opsld<0x82, "vfrczss", int_x86_xop_vfrcz_ss, ssmem, sse_load_f32>; diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 4976c22ad5..5c2d63bc7c 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -89,6 +89,19 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { if (Name == "x86.sse41.ptestnzc") return UpgradeSSE41Function(F, Intrinsic::x86_sse41_ptestnzc, NewFn); } + // frcz.ss/sd may need to have an argument dropped + if (Name.startswith("x86.xop.vfrcz.ss") && F->arg_size() == 2) { + F->setName(Name + ".old"); + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::x86_xop_vfrcz_ss); + return true; + } + if (Name.startswith("x86.xop.vfrcz.sd") && F->arg_size() == 2) { + F->setName(Name + ".old"); + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::x86_xop_vfrcz_sd); + return true; + } // Fix the FMA4 intrinsics to remove the 4 if (Name.startswith("x86.fma4.")) { F->setName("llvm.x86.fma" + Name.substr(8)); @@ -282,9 +295,16 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); return; + case Intrinsic::x86_xop_vfrcz_ss: + case Intrinsic::x86_xop_vfrcz_sd: + CI->replaceAllUsesWith(Builder.CreateCall(NewFn, CI->getArgOperand(1), + Name)); + CI->eraseFromParent(); + return; + case Intrinsic::x86_sse41_ptestc: case Intrinsic::x86_sse41_ptestz: - case Intrinsic::x86_sse41_ptestnzc: + case Intrinsic::x86_sse41_ptestnzc: { // The arguments for these intrinsics used to be v4f32, and changed // to v2i64. This is purely a nop, since those are bitwise intrinsics. // So, the only thing required is a bitcast for both arguments. @@ -310,6 +330,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); return; } + } } // This tests each Function to determine if it needs upgrading. When we find |