diff options
| author | Craig Topper <craig.topper@intel.com> | 2018-12-10 06:07:50 +0000 | 
|---|---|---|
| committer | Craig Topper <craig.topper@intel.com> | 2018-12-10 06:07:50 +0000 | 
| commit | 02b614abc89f2270eb391c8c56247b5271bf10b7 (patch) | |
| tree | 301fcd6eea555a76ec9f7bc9b4ea2231ce974aeb /llvm/lib/IR | |
| parent | 118687278955c5c212754a87adb1e826fe8b7940 (diff) | |
| download | bcm5719-llvm-02b614abc89f2270eb391c8c56247b5271bf10b7.tar.gz bcm5719-llvm-02b614abc89f2270eb391c8c56247b5271bf10b7.zip  | |
[X86] Merge addcarryx/addcarry intrinsic into a single addcarry intrinsic.
Both intrinsics do the exact same thing so we really only need one.
Earlier in the 8.0 cycle we changed the signature of this intrinsic without renaming it. But it looks difficult to get the autoupgrade code to allow me to merge the intrinsics and change the signature at the same time. So I've renamed the intrinsic slightly for the new merged intrinsic. I'm skipping autoupgrading from the previous new to 8.0 signature. I've also renamed the subborrow for consistency.
llvm-svn: 348737
Diffstat (limited to 'llvm/lib/IR')
| -rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 99 | 
1 files changed, 40 insertions, 59 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 83fc4787cf9..39e29a2a093 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -65,24 +65,19 @@ static bool UpgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID,    return true;  } -static bool UpgradeADCSBBIntrinsic(Function *F, Intrinsic::ID IID, -                                   Function *&NewFn) { -  // If this intrinsic has 3 operands, it's the new version. -  if (F->getFunctionType()->getNumParams() == 3) -    return false; - -  rename(F); -  NewFn = Intrinsic::getDeclaration(F->getParent(), IID); -  return true; -} -  static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {    // All of the intrinsics matches below should be marked with which llvm    // version started autoupgrading them. At some point in the future we would    // like to use this information to remove upgrade code for some older    // intrinsics. It is currently undecided how we will determine that future    // point. -  if (Name.startswith("sse2.paddus.") || // Added in 8.0 +  if (Name == "addcarryx.u32" || // Added in 8.0 +      Name == "addcarryx.u64" || // Added in 8.0 +      Name == "addcarry.u32" || // Added in 8.0 +      Name == "addcarry.u64" || // Added in 8.0 +      Name == "subborrow.u32" || // Added in 8.0 +      Name == "subborrow.u64" || // Added in 8.0 +      Name.startswith("sse2.paddus.") || // Added in 8.0        Name.startswith("sse2.psubus.") || // Added in 8.0        Name.startswith("avx2.paddus.") || // Added in 8.0        Name.startswith("avx2.psubus.") || // Added in 8.0 @@ -382,19 +377,6 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name,      return true;    } -  if (Name == "addcarryx.u32") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_addcarryx_u32, NewFn); -  if (Name == "addcarryx.u64") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_addcarryx_u64, NewFn); -  if (Name == "addcarry.u32") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_addcarry_u32, NewFn); -  if (Name == "addcarry.u64") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_addcarry_u64, NewFn); -  if (Name == "subborrow.u32") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_subborrow_u32, NewFn); -  if (Name == "subborrow.u64") // Added in 8.0 -    return UpgradeADCSBBIntrinsic(F, Intrinsic::x86_subborrow_u64, NewFn); -    if (Name == "rdtscp") { // Added in 8.0      // If this intrinsic has 0 operands, it's the new version.      if (F->getFunctionType()->getNumParams() == 0) @@ -3277,6 +3259,39 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {        Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType())                                   : CI->getArgOperand(0);        Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, PassThru); +    } else if (IsX86 && (Name == "addcarryx.u32" || Name == "addcarryx.u64" || +                         Name == "addcarry.u32" || Name == "addcarry.u64" || +                         Name == "subborrow.u32" || Name == "subborrow.u64")) { +      Intrinsic::ID IID; +      if (Name[0] == 'a' && Name.back() == '2') +        IID = Intrinsic::x86_addcarry_32; +      else if (Name[0] == 'a' && Name.back() == '4') +        IID = Intrinsic::x86_addcarry_64; +      else if (Name[0] == 's' && Name.back() == '2') +        IID = Intrinsic::x86_subborrow_32; +      else if (Name[0] == 's' && Name.back() == '4') +        IID = Intrinsic::x86_subborrow_64; +      else +        llvm_unreachable("Unexpected intrinsic"); + +      // Make a call with 3 operands. +      Value *Args[] = { CI->getArgOperand(0), CI->getArgOperand(1), +                        CI->getArgOperand(2)}; +      Value *NewCall = Builder.CreateCall( +                                Intrinsic::getDeclaration(CI->getModule(), IID), +                                Args); + +      // Extract the second result and store it. +      Value *Data = Builder.CreateExtractValue(NewCall, 1); +      // Cast the pointer to the right type. +      Value *Ptr = Builder.CreateBitCast(CI->getArgOperand(3), +                                 llvm::PointerType::getUnqual(Data->getType())); +      Builder.CreateAlignedStore(Data, Ptr, 1); +      // Replace the original call result with the first result of the new call. +      Value *CF = Builder.CreateExtractValue(NewCall, 0); + +      CI->replaceAllUsesWith(CF); +      Rep = nullptr;      } else if (IsX86 && Name.startswith("avx512.mask.") &&                 upgradeAVX512MaskToSelect(Name, Builder, *CI, Rep)) {        // Rep will be updated by the call in the condition. @@ -3478,40 +3493,6 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {      return;    } -  case Intrinsic::x86_addcarryx_u32: -  case Intrinsic::x86_addcarryx_u64: -  case Intrinsic::x86_addcarry_u32: -  case Intrinsic::x86_addcarry_u64: -  case Intrinsic::x86_subborrow_u32: -  case Intrinsic::x86_subborrow_u64: { -    // This used to take 4 arguments. If we only have 3 arguments its already -    // upgraded. -    if (CI->getNumOperands() == 3) -      return; - -    // Make a call with 3 operands. -    NewCall = Builder.CreateCall(NewFn, { CI->getArgOperand(0), -                                          CI->getArgOperand(1), -                                          CI->getArgOperand(2)}); -    // Extract the second result and store it. -    Value *Data = Builder.CreateExtractValue(NewCall, 1); -    // Cast the pointer to the right type. -    Value *Ptr = Builder.CreateBitCast(CI->getArgOperand(3), -                                 llvm::PointerType::getUnqual(Data->getType())); -    Builder.CreateAlignedStore(Data, Ptr, 1); -    // Replace the original call result with the first result of the new call. -    Value *CF = Builder.CreateExtractValue(NewCall, 0); - -    std::string Name = CI->getName(); -    if (!Name.empty()) { -      CI->setName(Name + ".old"); -      NewCall->setName(Name); -    } -    CI->replaceAllUsesWith(CF); -    CI->eraseFromParent(); -    return; -  } -    case Intrinsic::x86_sse41_insertps:    case Intrinsic::x86_sse41_dppd:    case Intrinsic::x86_sse41_dpps:  | 

