diff options
Diffstat (limited to 'gnu/llvm/lib/IR/AutoUpgrade.cpp')
| -rw-r--r-- | gnu/llvm/lib/IR/AutoUpgrade.cpp | 246 |
1 files changed, 220 insertions, 26 deletions
diff --git a/gnu/llvm/lib/IR/AutoUpgrade.cpp b/gnu/llvm/lib/IR/AutoUpgrade.cpp index 80640def955..c56a022c670 100644 --- a/gnu/llvm/lib/IR/AutoUpgrade.cpp +++ b/gnu/llvm/lib/IR/AutoUpgrade.cpp @@ -15,8 +15,6 @@ #include "llvm/IR/AutoUpgrade.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/IR/CFG.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfo.h" @@ -24,9 +22,9 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include <cstring> @@ -72,12 +70,23 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) { // 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.pcmpeq.") || // Added in 3.1 + if (Name=="ssse3.pabs.b.128" || // Added in 6.0 + Name=="ssse3.pabs.w.128" || // Added in 6.0 + Name=="ssse3.pabs.d.128" || // Added in 6.0 + Name.startswith("avx512.mask.shuf.i") || // Added in 6.0 + Name.startswith("avx512.mask.shuf.f") || // Added in 6.0 + Name.startswith("avx2.pabs.") || // Added in 6.0 + Name.startswith("avx512.mask.pabs.") || // Added in 6.0 + Name.startswith("avx512.broadcastm") || // Added in 6.0 + Name.startswith("avx512.mask.pbroadcast") || // Added in 6.0 + Name.startswith("sse2.pcmpeq.") || // Added in 3.1 Name.startswith("sse2.pcmpgt.") || // Added in 3.1 Name.startswith("avx2.pcmpeq.") || // Added in 3.1 Name.startswith("avx2.pcmpgt.") || // Added in 3.1 Name.startswith("avx512.mask.pcmpeq.") || // Added in 3.9 Name.startswith("avx512.mask.pcmpgt.") || // Added in 3.9 + Name.startswith("avx.vperm2f128.") || // Added in 6.0 + Name == "avx2.vperm2i128" || // Added in 6.0 Name == "sse.add.ss" || // Added in 4.0 Name == "sse2.add.sd" || // Added in 4.0 Name == "sse.sub.ss" || // Added in 4.0 @@ -239,12 +248,19 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) { Name.startswith("avx2.pblendd.") || // Added in 3.7 Name.startswith("avx.vbroadcastf128") || // Added in 4.0 Name == "avx2.vbroadcasti128" || // Added in 3.7 + Name.startswith("avx512.mask.broadcastf") || // Added in 6.0 + Name.startswith("avx512.mask.broadcasti") || // Added in 6.0 Name == "xop.vpcmov" || // Added in 3.8 Name == "xop.vpcmov.256" || // Added in 5.0 Name.startswith("avx512.mask.move.s") || // Added in 4.0 Name.startswith("avx512.cvtmask2") || // Added in 5.0 (Name.startswith("xop.vpcom") && // Added in 3.2 - F->arg_size() == 2)) + F->arg_size() == 2) || + Name.startswith("avx512.ptestm") || //Added in 6.0 + Name.startswith("avx512.ptestnm") || //Added in 6.0 + Name.startswith("sse2.pavg") || // Added in 6.0 + Name.startswith("avx2.pavg") || // Added in 6.0 + Name.startswith("avx512.mask.pavg")) // Added in 6.0 return true; return false; @@ -420,6 +436,14 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; } + case 'd': { + if (Name == "dbg.value" && F->arg_size() == 4) { + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); + return true; + } + break; + } case 'i': case 'l': { bool IsLifetimeStart = Name.startswith("lifetime.start"); @@ -774,6 +798,20 @@ static Value *UpgradeMaskedLoad(IRBuilder<> &Builder, return Builder.CreateMaskedLoad(Ptr, Align, Mask, Passthru); } +static Value *upgradeAbs(IRBuilder<> &Builder, CallInst &CI) { + Value *Op0 = CI.getArgOperand(0); + llvm::Type *Ty = Op0->getType(); + Value *Zero = llvm::Constant::getNullValue(Ty); + Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_SGT, Op0, Zero); + Value *Neg = Builder.CreateNeg(Op0); + Value *Res = Builder.CreateSelect(Cmp, Op0, Neg); + + if (CI.getNumArgOperands() == 3) + Res = EmitX86Select(Builder,CI.getArgOperand(2), Res, CI.getArgOperand(1)); + + return Res; +} + static Value *upgradeIntMinMax(IRBuilder<> &Builder, CallInst &CI, ICmpInst::Predicate Pred) { Value *Op0 = CI.getArgOperand(0); @@ -787,6 +825,26 @@ static Value *upgradeIntMinMax(IRBuilder<> &Builder, CallInst &CI, return Res; } +// Applying mask on vector of i1's and make sure result is at least 8 bits wide. +static Value *ApplyX86MaskOn1BitsVec(IRBuilder<> &Builder,Value *Vec, Value *Mask, + unsigned NumElts) { + const auto *C = dyn_cast<Constant>(Mask); + if (!C || !C->isAllOnesValue()) + Vec = Builder.CreateAnd(Vec, getX86MaskVec(Builder, Mask, NumElts)); + + if (NumElts < 8) { + uint32_t Indices[8]; + for (unsigned i = 0; i != NumElts; ++i) + Indices[i] = i; + for (unsigned i = NumElts; i != 8; ++i) + Indices[i] = NumElts + i % NumElts; + Vec = Builder.CreateShuffleVector(Vec, + Constant::getNullValue(Vec->getType()), + Indices); + } + return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U))); +} + static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI, unsigned CC, bool Signed) { Value *Op0 = CI.getArgOperand(0); @@ -812,22 +870,8 @@ static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI, } Value *Mask = CI.getArgOperand(CI.getNumArgOperands() - 1); - const auto *C = dyn_cast<Constant>(Mask); - if (!C || !C->isAllOnesValue()) - Cmp = Builder.CreateAnd(Cmp, getX86MaskVec(Builder, Mask, NumElts)); - if (NumElts < 8) { - uint32_t Indices[8]; - for (unsigned i = 0; i != NumElts; ++i) - Indices[i] = i; - for (unsigned i = NumElts; i != 8; ++i) - Indices[i] = NumElts + i % NumElts; - Cmp = Builder.CreateShuffleVector(Cmp, - Constant::getNullValue(Cmp->getType()), - Indices); - } - return Builder.CreateBitCast(Cmp, IntegerType::get(CI.getContext(), - std::max(NumElts, 8U))); + return ApplyX86MaskOn1BitsVec(Builder, Cmp, Mask, NumElts); } // Replace a masked intrinsic with an older unmasked intrinsic. @@ -991,6 +1035,33 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Rep = Builder.CreateICmp(CmpEq ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_SGT, CI->getArgOperand(0), CI->getArgOperand(1)); Rep = Builder.CreateSExt(Rep, CI->getType(), ""); + } else if (IsX86 && (Name.startswith("avx512.broadcastm"))) { + Type *ExtTy = Type::getInt32Ty(C); + if (CI->getOperand(0)->getType()->isIntegerTy(8)) + ExtTy = Type::getInt64Ty(C); + unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() / + ExtTy->getPrimitiveSizeInBits(); + Rep = Builder.CreateZExt(CI->getArgOperand(0), ExtTy); + Rep = Builder.CreateVectorSplat(NumElts, Rep); + } else if (IsX86 && (Name.startswith("avx512.ptestm") || + Name.startswith("avx512.ptestnm"))) { + Value *Op0 = CI->getArgOperand(0); + Value *Op1 = CI->getArgOperand(1); + Value *Mask = CI->getArgOperand(2); + Rep = Builder.CreateAnd(Op0, Op1); + llvm::Type *Ty = Op0->getType(); + Value *Zero = llvm::Constant::getNullValue(Ty); + ICmpInst::Predicate Pred = + Name.startswith("avx512.ptestm") ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ; + Rep = Builder.CreateICmp(Pred, Rep, Zero); + unsigned NumElts = Op0->getType()->getVectorNumElements(); + Rep = ApplyX86MaskOn1BitsVec(Builder, Rep, Mask, NumElts); + } else if (IsX86 && (Name.startswith("avx512.mask.pbroadcast"))){ + unsigned NumElts = + CI->getArgOperand(1)->getType()->getVectorNumElements(); + Rep = Builder.CreateVectorSplat(NumElts, CI->getArgOperand(0)); + Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep, + CI->getArgOperand(1)); } else if (IsX86 && (Name == "sse.add.ss" || Name == "sse2.add.sd")) { Type *I32Ty = Type::getInt32Ty(C); Value *Elt0 = Builder.CreateExtractElement(CI->getArgOperand(0), @@ -1037,6 +1108,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { } else if (IsX86 && Name.startswith("avx512.mask.ucmp")) { unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); Rep = upgradeMaskedCompare(Builder, *CI, Imm, false); + } else if(IsX86 && (Name == "ssse3.pabs.b.128" || + Name == "ssse3.pabs.w.128" || + Name == "ssse3.pabs.d.128" || + Name.startswith("avx2.pabs") || + Name.startswith("avx512.mask.pabs"))) { + Rep = upgradeAbs(Builder, *CI); } else if (IsX86 && (Name == "sse41.pmaxsb" || Name == "sse2.pmaxs.w" || Name == "sse41.pmaxsd" || @@ -1213,6 +1290,43 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { else Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()), { 0, 1, 2, 3, 0, 1, 2, 3 }); + } else if (IsX86 && (Name.startswith("avx512.mask.shuf.i") || + Name.startswith("avx512.mask.shuf.f"))) { + unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); + Type *VT = CI->getType(); + unsigned NumLanes = VT->getPrimitiveSizeInBits() / 128; + unsigned NumElementsInLane = 128 / VT->getScalarSizeInBits(); + unsigned ControlBitsMask = NumLanes - 1; + unsigned NumControlBits = NumLanes / 2; + SmallVector<uint32_t, 8> ShuffleMask(0); + + for (unsigned l = 0; l != NumLanes; ++l) { + unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask; + // We actually need the other source. + if (l >= NumLanes / 2) + LaneMask += NumLanes; + for (unsigned i = 0; i != NumElementsInLane; ++i) + ShuffleMask.push_back(LaneMask * NumElementsInLane + i); + } + Rep = Builder.CreateShuffleVector(CI->getArgOperand(0), + CI->getArgOperand(1), ShuffleMask); + Rep = EmitX86Select(Builder, CI->getArgOperand(4), Rep, + CI->getArgOperand(3)); + }else if (IsX86 && (Name.startswith("avx512.mask.broadcastf") || + Name.startswith("avx512.mask.broadcasti"))) { + unsigned NumSrcElts = + CI->getArgOperand(0)->getType()->getVectorNumElements(); + unsigned NumDstElts = CI->getType()->getVectorNumElements(); + + SmallVector<uint32_t, 8> ShuffleMask(NumDstElts); + for (unsigned i = 0; i != NumDstElts; ++i) + ShuffleMask[i] = i % NumSrcElts; + + Rep = Builder.CreateShuffleVector(CI->getArgOperand(0), + CI->getArgOperand(0), + ShuffleMask); + Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep, + CI->getArgOperand(1)); } else if (IsX86 && (Name.startswith("avx2.pbroadcast") || Name.startswith("avx2.vbroadcast") || Name.startswith("avx512.pbroadcast") || @@ -1367,6 +1481,42 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { if (CI->getNumArgOperands() == 4) Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, CI->getArgOperand(2)); + } else if (IsX86 && (Name.startswith("avx.vperm2f128.") || + Name == "avx2.vperm2i128")) { + // The immediate permute control byte looks like this: + // [1:0] - select 128 bits from sources for low half of destination + // [2] - ignore + // [3] - zero low half of destination + // [5:4] - select 128 bits from sources for high half of destination + // [6] - ignore + // [7] - zero high half of destination + + uint8_t Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); + + unsigned NumElts = CI->getType()->getVectorNumElements(); + unsigned HalfSize = NumElts / 2; + SmallVector<uint32_t, 8> ShuffleMask(NumElts); + + // Determine which operand(s) are actually in use for this instruction. + Value *V0 = (Imm & 0x02) ? CI->getArgOperand(1) : CI->getArgOperand(0); + Value *V1 = (Imm & 0x20) ? CI->getArgOperand(1) : CI->getArgOperand(0); + + // If needed, replace operands based on zero mask. + V0 = (Imm & 0x08) ? ConstantAggregateZero::get(CI->getType()) : V0; + V1 = (Imm & 0x80) ? ConstantAggregateZero::get(CI->getType()) : V1; + + // Permute low half of result. + unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0; + for (unsigned i = 0; i < HalfSize; ++i) + ShuffleMask[i] = StartIndex + i; + + // Permute high half of result. + StartIndex = (Imm & 0x10) ? HalfSize : 0; + for (unsigned i = 0; i < HalfSize; ++i) + ShuffleMask[i + HalfSize] = NumElts + StartIndex + i; + + Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask); + } else if (IsX86 && (Name.startswith("avx.vpermil.") || Name == "sse2.pshuf.d" || Name.startswith("avx512.mask.vpermil.p") || @@ -1941,6 +2091,25 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { LoadInst *LI = Builder.CreateAlignedLoad(BC, VTy->getBitWidth() / 8); LI->setMetadata(M->getMDKindID("nontemporal"), Node); Rep = LI; + } else if (IsX86 && + (Name.startswith("sse2.pavg") || Name.startswith("avx2.pavg") || + Name.startswith("avx512.mask.pavg"))) { + // llvm.x86.sse2.pavg.b/w, llvm.x86.avx2.pavg.b/w, + // llvm.x86.avx512.mask.pavg.b/w + Value *A = CI->getArgOperand(0); + Value *B = CI->getArgOperand(1); + VectorType *ZextType = VectorType::getExtendedElementVectorType( + cast<VectorType>(A->getType())); + Value *ExtendedA = Builder.CreateZExt(A, ZextType); + Value *ExtendedB = Builder.CreateZExt(B, ZextType); + Value *Sum = Builder.CreateAdd(ExtendedA, ExtendedB); + Value *AddOne = Builder.CreateAdd(Sum, ConstantInt::get(ZextType, 1)); + Value *ShiftR = Builder.CreateLShr(AddOne, ConstantInt::get(ZextType, 1)); + Rep = Builder.CreateTrunc(ShiftR, A->getType()); + if (CI->getNumArgOperands() > 2) { + Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep, + CI->getArgOperand(2)); + } } else if (IsNVVM && (Name == "abs.i" || Name == "abs.ll")) { Value *Arg = CI->getArgOperand(0); Value *Neg = Builder.CreateNeg(Arg, "neg"); @@ -2055,6 +2224,20 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)}); break; + case Intrinsic::dbg_value: + // Upgrade from the old version that had an extra offset argument. + assert(CI->getNumArgOperands() == 4); + // Drop nonzero offsets instead of attempting to upgrade them. + if (auto *Offset = dyn_cast_or_null<Constant>(CI->getArgOperand(1))) + if (Offset->isZeroValue()) { + NewCall = Builder.CreateCall( + NewFn, + {CI->getArgOperand(0), CI->getArgOperand(2), CI->getArgOperand(3)}); + break; + } + CI->eraseFromParent(); + return; + case Intrinsic::x86_xop_vfrcz_ss: case Intrinsic::x86_xop_vfrcz_sd: NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)}); @@ -2227,15 +2410,26 @@ Value *llvm::UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy) { /// info. Return true if module is modified. bool llvm::UpgradeDebugInfo(Module &M) { unsigned Version = getDebugMetadataVersionFromModule(M); - if (Version == DEBUG_METADATA_VERSION) - return false; - - bool RetCode = StripDebugInfo(M); - if (RetCode) { + if (Version == DEBUG_METADATA_VERSION) { + bool BrokenDebugInfo = false; + if (verifyModule(M, &llvm::errs(), &BrokenDebugInfo)) + report_fatal_error("Broken module found, compilation aborted!"); + if (!BrokenDebugInfo) + // Everything is ok. + return false; + else { + // Diagnose malformed debug info. + DiagnosticInfoIgnoringInvalidDebugMetadata Diag(M); + M.getContext().diagnose(Diag); + } + } + bool Modified = StripDebugInfo(M); + if (Modified && Version != DEBUG_METADATA_VERSION) { + // Diagnose a version mismatch. DiagnosticInfoDebugMetadataVersion DiagVersion(M, Version); M.getContext().diagnose(DiagVersion); } - return RetCode; + return Modified; } bool llvm::UpgradeModuleFlags(Module &M) { |
