diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-01-20 17:36:22 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-01-20 17:36:22 +0000 |
| commit | b590e4f7e57c7105cd5b0289be8911724e0d7002 (patch) | |
| tree | 6b4df08b4ed37d589a1e50301cc6a47504cfb58c /llvm/lib/IR | |
| parent | 0e83f5dff115a621b0ac1413dcff85d081b31d5b (diff) | |
| download | bcm5719-llvm-b590e4f7e57c7105cd5b0289be8911724e0d7002.tar.gz bcm5719-llvm-b590e4f7e57c7105cd5b0289be8911724e0d7002.zip | |
[X86] Auto upgrade old style VPCOM/VPCOMU intrinsics to generic integer comparisons
We were upgrading these to the new style VPCOM/VPCOMU intrinsics (which includes the condition code immediate), but we'll be getting rid of those shortly, so convert these to generics first.
This causes a couple of changes in the upgrade tests as signed/unsigned eq/ne are equivalent and we constant fold true/false codes, these changes are the same as what we already do for avx512 cmp/ucmp.
Noticed while cleaning up vector integer comparison costs for PR40376.
llvm-svn: 351690
Diffstat (limited to 'llvm/lib/IR')
| -rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 321c8c3992f..b28e9f51507 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1052,6 +1052,45 @@ static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallInst &CI, return Res; } +static Value *upgradeX86vpcom(IRBuilder<> &Builder, CallInst &CI, unsigned Imm, + bool IsSigned) { + Type *Ty = CI.getType(); + Value *LHS = CI.getArgOperand(0); + Value *RHS = CI.getArgOperand(1); + + CmpInst::Predicate Pred; + switch (Imm) { + case 0x0: + Pred = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; + break; + case 0x1: + Pred = IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; + break; + case 0x2: + Pred = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + break; + case 0x3: + Pred = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; + break; + case 0x4: + Pred = ICmpInst::ICMP_EQ; + break; + case 0x5: + Pred = ICmpInst::ICMP_NE; + break; + case 0x6: + return Constant::getNullValue(Ty); // FALSE + case 0x7: + return Constant::getAllOnesValue(Ty); // TRUE + default: + llvm_unreachable("Unknown XOP vpcom/vpcomu predicate"); + } + + Value *Cmp = Builder.CreateICmp(Pred, LHS, RHS); + Value *Ext = Builder.CreateSExt(Cmp, Ty); + return Ext; +} + static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallInst &CI, bool IsShiftRight, bool ZeroMask) { Type *Ty = CI.getType(); @@ -1989,23 +2028,13 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { ResultTy); Rep = Builder.CreateCall(CSt, { CI->getArgOperand(1), Ptr, MaskVec }); } else if (IsX86 && Name.startswith("xop.vpcom")) { - Intrinsic::ID intID; - if (Name.endswith("ub")) - intID = Intrinsic::x86_xop_vpcomub; - else if (Name.endswith("uw")) - intID = Intrinsic::x86_xop_vpcomuw; - else if (Name.endswith("ud")) - intID = Intrinsic::x86_xop_vpcomud; - else if (Name.endswith("uq")) - intID = Intrinsic::x86_xop_vpcomuq; - else if (Name.endswith("b")) - intID = Intrinsic::x86_xop_vpcomb; - else if (Name.endswith("w")) - intID = Intrinsic::x86_xop_vpcomw; - else if (Name.endswith("d")) - intID = Intrinsic::x86_xop_vpcomd; - else if (Name.endswith("q")) - intID = Intrinsic::x86_xop_vpcomq; + bool IsSigned; + if (Name.endswith("ub") || Name.endswith("uw") || Name.endswith("ud") || + Name.endswith("uq")) + IsSigned = false; + else if (Name.endswith("b") || Name.endswith("w") || Name.endswith("d") || + Name.endswith("q")) + IsSigned = true; else llvm_unreachable("Unknown suffix"); @@ -2029,11 +2058,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Imm = 7; else llvm_unreachable("Unknown condition"); - - Function *VPCOM = Intrinsic::getDeclaration(F->getParent(), intID); - Rep = - Builder.CreateCall(VPCOM, {CI->getArgOperand(0), CI->getArgOperand(1), - Builder.getInt8(Imm)}); + Rep = upgradeX86vpcom(Builder, *CI, Imm, IsSigned); } else if (IsX86 && Name.startswith("xop.vpcmov")) { Value *Sel = CI->getArgOperand(2); Value *NotSel = Builder.CreateNot(Sel); |

