summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r--gnu/llvm/lib/IR/AutoUpgrade.cpp246
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) {