aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r--contrib/llvm/lib/IR/AutoUpgrade.cpp399
1 files changed, 291 insertions, 108 deletions
diff --git a/contrib/llvm/lib/IR/AutoUpgrade.cpp b/contrib/llvm/lib/IR/AutoUpgrade.cpp
index 27064154221f..a2d820352825 100644
--- a/contrib/llvm/lib/IR/AutoUpgrade.cpp
+++ b/contrib/llvm/lib/IR/AutoUpgrade.cpp
@@ -1,9 +1,8 @@
//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -199,14 +198,14 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name.startswith("avx512.mask.pmull.") || // Added in 4.0
Name.startswith("avx512.mask.cvtdq2pd.") || // Added in 4.0
Name.startswith("avx512.mask.cvtudq2pd.") || // Added in 4.0
- Name == "avx512.mask.cvtudq2ps.128" || // Added in 7.0
- Name == "avx512.mask.cvtudq2ps.256" || // Added in 7.0
- Name == "avx512.mask.cvtqq2pd.128" || // Added in 7.0
- Name == "avx512.mask.cvtqq2pd.256" || // Added in 7.0
- Name == "avx512.mask.cvtuqq2pd.128" || // Added in 7.0
- Name == "avx512.mask.cvtuqq2pd.256" || // Added in 7.0
- Name == "avx512.mask.cvtdq2ps.128" || // Added in 7.0
- Name == "avx512.mask.cvtdq2ps.256" || // Added in 7.0
+ Name.startswith("avx512.mask.cvtudq2ps.") || // Added in 7.0 updated 9.0
+ Name.startswith("avx512.mask.cvtqq2pd.") || // Added in 7.0 updated 9.0
+ Name.startswith("avx512.mask.cvtuqq2pd.") || // Added in 7.0 updated 9.0
+ Name.startswith("avx512.mask.cvtdq2ps.") || // Added in 7.0 updated 9.0
+ Name == "avx512.mask.cvtqq2ps.256" || // Added in 9.0
+ Name == "avx512.mask.cvtqq2ps.512" || // Added in 9.0
+ Name == "avx512.mask.cvtuqq2ps.256" || // Added in 9.0
+ Name == "avx512.mask.cvtuqq2ps.512" || // Added in 9.0
Name == "avx512.mask.cvtpd2dq.256" || // Added in 7.0
Name == "avx512.mask.cvtpd2ps.256" || // Added in 7.0
Name == "avx512.mask.cvttpd2dq.256" || // Added in 7.0
@@ -216,7 +215,6 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name == "avx512.mask.cvtps2pd.256" || // Added in 7.0
Name == "avx512.cvtusi2sd" || // Added in 7.0
Name.startswith("avx512.mask.permvar.") || // Added in 7.0
- Name.startswith("avx512.mask.permvar.") || // Added in 7.0
Name == "sse2.pmulu.dq" || // Added in 7.0
Name == "sse41.pmuldq" || // Added in 7.0
Name == "avx2.pmulu.dq" || // Added in 7.0
@@ -300,6 +298,11 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name.startswith("avx512.mask.fpclass.p") || // Added in 7.0
Name.startswith("avx512.mask.vpshufbitqmb.") || // Added in 8.0
Name.startswith("avx512.mask.pmultishift.qb.") || // Added in 8.0
+ Name.startswith("avx512.mask.conflict.") || // Added in 9.0
+ Name == "avx512.mask.pmov.qd.256" || // Added in 9.0
+ Name == "avx512.mask.pmov.qd.512" || // Added in 9.0
+ Name == "avx512.mask.pmov.wb.256" || // Added in 9.0
+ Name == "avx512.mask.pmov.wb.512" || // Added in 9.0
Name == "sse.cvtsi2ss" || // Added in 7.0
Name == "sse.cvtsi642ss" || // Added in 7.0
Name == "sse2.cvtsi2sd" || // Added in 7.0
@@ -338,6 +341,16 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name.startswith("avx512.mask.load.") || // Added in 3.9
Name.startswith("avx512.mask.expand.load.") || // Added in 7.0
Name.startswith("avx512.mask.compress.store.") || // Added in 7.0
+ Name.startswith("avx512.mask.expand.b") || // Added in 9.0
+ Name.startswith("avx512.mask.expand.w") || // Added in 9.0
+ Name.startswith("avx512.mask.expand.d") || // Added in 9.0
+ Name.startswith("avx512.mask.expand.q") || // Added in 9.0
+ Name.startswith("avx512.mask.expand.p") || // Added in 9.0
+ Name.startswith("avx512.mask.compress.b") || // Added in 9.0
+ Name.startswith("avx512.mask.compress.w") || // Added in 9.0
+ Name.startswith("avx512.mask.compress.d") || // Added in 9.0
+ Name.startswith("avx512.mask.compress.q") || // Added in 9.0
+ Name.startswith("avx512.mask.compress.p") || // Added in 9.0
Name == "sse42.crc32.64.8" || // Added in 3.4
Name.startswith("avx.vbroadcast.s") || // Added in 3.5
Name.startswith("avx512.vbroadcast.s") || // Added in 7.0
@@ -362,8 +375,7 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
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) ||
+ Name.startswith("xop.vpcom") || // Added in 3.2, Updated in 9.0
Name.startswith("xop.vprot") || // Added in 8.0
Name.startswith("avx512.prol") || // Added in 8.0
Name.startswith("avx512.pror") || // Added in 8.0
@@ -373,8 +385,6 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) {
Name.startswith("avx512.mask.prol.") || // Added in 8.0
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;
@@ -480,6 +490,12 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name,
static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
assert(F && "Illegal to upgrade a non-existent Function.");
+ // Upgrade intrinsics "clang.arc.use" which doesn't start with "llvm.".
+ if (F->getName() == "clang.arc.use") {
+ NewFn = nullptr;
+ return true;
+ }
+
// Quickly eliminate it, if it's not a candidate.
StringRef Name = F->getName();
if (Name.size() <= 8 || !Name.startswith("llvm."))
@@ -549,6 +565,17 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer);
return true;
}
+ if (Name.startswith("aarch64.neon.addp")) {
+ if (F->arg_size() != 2)
+ break; // Invalid IR.
+ auto fArgs = F->getFunctionType()->params();
+ VectorType *ArgTy = dyn_cast<VectorType>(fArgs[0]);
+ if (ArgTy && ArgTy->getElementType()->isFloatingPointTy()) {
+ NewFn = Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::aarch64_neon_faddp, fArgs);
+ return true;
+ }
+ }
break;
}
@@ -575,6 +602,26 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
}
+ case 'e': {
+ SmallVector<StringRef, 2> Groups;
+ Regex R("^experimental.vector.reduce.([a-z]+)\\.[fi][0-9]+");
+ if (R.match(Name, &Groups)) {
+ Intrinsic::ID ID = Intrinsic::not_intrinsic;
+ if (Groups[1] == "fadd")
+ ID = Intrinsic::experimental_vector_reduce_v2_fadd;
+ if (Groups[1] == "fmul")
+ ID = Intrinsic::experimental_vector_reduce_v2_fmul;
+
+ if (ID != Intrinsic::not_intrinsic) {
+ rename(F);
+ auto Args = F->getFunctionType()->params();
+ Type *Tys[] = {F->getFunctionType()->getReturnType(), Args[1]};
+ NewFn = Intrinsic::getDeclaration(F->getParent(), ID, Tys);
+ return true;
+ }
+ }
+ break;
+ }
case 'i':
case 'l': {
bool IsLifetimeStart = Name.startswith("lifetime.start");
@@ -717,6 +764,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
.Cases("clz.ll", "popc.ll", "h2f", true)
.Cases("max.i", "max.ll", "max.ui", "max.ull", true)
.Cases("min.i", "min.ll", "min.ui", "min.ull", true)
+ .StartsWith("atomic.load.add.f32.p", true)
+ .StartsWith("atomic.load.add.f64.p", true)
.Default(false);
if (Expand) {
NewFn = nullptr;
@@ -730,7 +779,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
// address space.
if (Name.startswith("objectsize.")) {
Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
- if (F->arg_size() == 2 ||
+ if (F->arg_size() == 2 || F->arg_size() == 3 ||
F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) {
rename(F);
NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
@@ -778,9 +827,35 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
return Upgraded;
}
-bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
- // Nothing to do yet.
- return false;
+GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
+ if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" ||
+ GV->getName() == "llvm.global_dtors")) ||
+ !GV->hasInitializer())
+ return nullptr;
+ ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType());
+ if (!ATy)
+ return nullptr;
+ StructType *STy = dyn_cast<StructType>(ATy->getElementType());
+ if (!STy || STy->getNumElements() != 2)
+ return nullptr;
+
+ LLVMContext &C = GV->getContext();
+ IRBuilder<> IRB(C);
+ auto EltTy = StructType::get(STy->getElementType(0), STy->getElementType(1),
+ IRB.getInt8PtrTy());
+ Constant *Init = GV->getInitializer();
+ unsigned N = Init->getNumOperands();
+ std::vector<Constant *> NewCtors(N);
+ for (unsigned i = 0; i != N; ++i) {
+ auto Ctor = cast<Constant>(Init->getOperand(i));
+ NewCtors[i] = ConstantStruct::get(
+ EltTy, Ctor->getAggregateElement(0u), Ctor->getAggregateElement(1),
+ Constant::getNullValue(IRB.getInt8PtrTy()));
+ }
+ Constant *NewInit = ConstantArray::get(ArrayType::get(EltTy, N), NewCtors);
+
+ return new GlobalVariable(NewInit->getType(), false, GV->getLinkage(),
+ NewInit, GV->getName());
}
// Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them
@@ -1054,6 +1129,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();
@@ -1111,16 +1225,16 @@ static Value *UpgradeMaskedStore(IRBuilder<> &Builder,
static Value *UpgradeMaskedLoad(IRBuilder<> &Builder,
Value *Ptr, Value *Passthru, Value *Mask,
bool Aligned) {
+ Type *ValTy = Passthru->getType();
// Cast the pointer to the right type.
- Ptr = Builder.CreateBitCast(Ptr,
- llvm::PointerType::getUnqual(Passthru->getType()));
+ Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(ValTy));
unsigned Align =
Aligned ? cast<VectorType>(Passthru->getType())->getBitWidth() / 8 : 1;
// If the mask is all ones just emit a regular store.
if (const auto *C = dyn_cast<Constant>(Mask))
if (C->isAllOnesValue())
- return Builder.CreateAlignedLoad(Ptr, Align);
+ return Builder.CreateAlignedLoad(ValTy, Ptr, Align);
// Convert the mask from an integer type to a vector of i1.
unsigned NumElts = Passthru->getType()->getVectorNumElements();
@@ -1463,6 +1577,36 @@ static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder,
IID = Intrinsic::x86_avx512_pmultishift_qb_512;
else
llvm_unreachable("Unexpected intrinsic");
+ } else if (Name.startswith("conflict.")) {
+ if (Name[9] == 'd' && VecWidth == 128)
+ IID = Intrinsic::x86_avx512_conflict_d_128;
+ else if (Name[9] == 'd' && VecWidth == 256)
+ IID = Intrinsic::x86_avx512_conflict_d_256;
+ else if (Name[9] == 'd' && VecWidth == 512)
+ IID = Intrinsic::x86_avx512_conflict_d_512;
+ else if (Name[9] == 'q' && VecWidth == 128)
+ IID = Intrinsic::x86_avx512_conflict_q_128;
+ else if (Name[9] == 'q' && VecWidth == 256)
+ IID = Intrinsic::x86_avx512_conflict_q_256;
+ else if (Name[9] == 'q' && VecWidth == 512)
+ IID = Intrinsic::x86_avx512_conflict_q_512;
+ else
+ llvm_unreachable("Unexpected intrinsic");
+ } else if (Name.startswith("pavg.")) {
+ if (Name[5] == 'b' && VecWidth == 128)
+ IID = Intrinsic::x86_sse2_pavg_b;
+ else if (Name[5] == 'b' && VecWidth == 256)
+ IID = Intrinsic::x86_avx2_pavg_b;
+ else if (Name[5] == 'b' && VecWidth == 512)
+ IID = Intrinsic::x86_avx512_pavg_b_512;
+ else if (Name[5] == 'w' && VecWidth == 128)
+ IID = Intrinsic::x86_sse2_pavg_w;
+ else if (Name[5] == 'w' && VecWidth == 256)
+ IID = Intrinsic::x86_avx2_pavg_w;
+ else if (Name[5] == 'w' && VecWidth == 512)
+ IID = Intrinsic::x86_avx512_pavg_w_512;
+ else
+ llvm_unreachable("Unexpected intrinsic");
} else
return false;
@@ -1504,6 +1648,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Get the Function's name.
StringRef Name = F->getName();
+ // clang.arc.use is an old name for llvm.arc.clang.arc.use. It is dropped
+ // from upgrader because the optimizer now only recognizes intrinsics for
+ // ARC runtime calls.
+ if (Name == "clang.arc.use") {
+ CI->eraseFromParent();
+ return;
+ }
+
assert(Name.startswith("llvm.") && "Intrinsic doesn't start with 'llvm.'");
Name = Name.substr(5);
@@ -1918,38 +2070,47 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Name == "avx.cvtdq2.ps.256" ||
Name.startswith("avx512.mask.cvtdq2pd.") ||
Name.startswith("avx512.mask.cvtudq2pd.") ||
- Name == "avx512.mask.cvtdq2ps.128" ||
- Name == "avx512.mask.cvtdq2ps.256" ||
- Name == "avx512.mask.cvtudq2ps.128" ||
- Name == "avx512.mask.cvtudq2ps.256" ||
- Name == "avx512.mask.cvtqq2pd.128" ||
- Name == "avx512.mask.cvtqq2pd.256" ||
- Name == "avx512.mask.cvtuqq2pd.128" ||
- Name == "avx512.mask.cvtuqq2pd.256" ||
+ Name.startswith("avx512.mask.cvtdq2ps.") ||
+ Name.startswith("avx512.mask.cvtudq2ps.") ||
+ Name.startswith("avx512.mask.cvtqq2pd.") ||
+ Name.startswith("avx512.mask.cvtuqq2pd.") ||
+ Name == "avx512.mask.cvtqq2ps.256" ||
+ Name == "avx512.mask.cvtqq2ps.512" ||
+ Name == "avx512.mask.cvtuqq2ps.256" ||
+ Name == "avx512.mask.cvtuqq2ps.512" ||
Name == "sse2.cvtps2pd" ||
Name == "avx.cvt.ps2.pd.256" ||
Name == "avx512.mask.cvtps2pd.128" ||
Name == "avx512.mask.cvtps2pd.256")) {
Type *DstTy = CI->getType();
Rep = CI->getArgOperand(0);
+ Type *SrcTy = Rep->getType();
unsigned NumDstElts = DstTy->getVectorNumElements();
- if (NumDstElts < Rep->getType()->getVectorNumElements()) {
+ if (NumDstElts < SrcTy->getVectorNumElements()) {
assert(NumDstElts == 2 && "Unexpected vector size");
uint32_t ShuffleMask[2] = { 0, 1 };
Rep = Builder.CreateShuffleVector(Rep, Rep, ShuffleMask);
}
- bool IsPS2PD = (StringRef::npos != Name.find("ps2"));
+ bool IsPS2PD = SrcTy->getVectorElementType()->isFloatTy();
bool IsUnsigned = (StringRef::npos != Name.find("cvtu"));
if (IsPS2PD)
Rep = Builder.CreateFPExt(Rep, DstTy, "cvtps2pd");
- else if (IsUnsigned)
- Rep = Builder.CreateUIToFP(Rep, DstTy, "cvt");
- else
- Rep = Builder.CreateSIToFP(Rep, DstTy, "cvt");
+ else if (CI->getNumArgOperands() == 4 &&
+ (!isa<ConstantInt>(CI->getArgOperand(3)) ||
+ cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue() != 4)) {
+ Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round
+ : Intrinsic::x86_avx512_sitofp_round;
+ Function *F = Intrinsic::getDeclaration(CI->getModule(), IID,
+ { DstTy, SrcTy });
+ Rep = Builder.CreateCall(F, { Rep, CI->getArgOperand(3) });
+ } else {
+ Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy, "cvt")
+ : Builder.CreateSIToFP(Rep, DstTy, "cvt");
+ }
- if (CI->getNumArgOperands() == 3)
+ if (CI->getNumArgOperands() >= 3)
Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
CI->getArgOperand(1));
} else if (IsX86 && (Name.startswith("avx512.mask.loadu."))) {
@@ -1990,52 +2151,56 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Intrinsic::masked_compressstore,
ResultTy);
Rep = Builder.CreateCall(CSt, { CI->getArgOperand(1), Ptr, MaskVec });
+ } else if (IsX86 && (Name.startswith("avx512.mask.compress.") ||
+ Name.startswith("avx512.mask.expand."))) {
+ Type *ResultTy = CI->getType();
+
+ Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2),
+ ResultTy->getVectorNumElements());
+
+ bool IsCompress = Name[12] == 'c';
+ Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
+ : Intrinsic::x86_avx512_mask_expand;
+ Function *Intr = Intrinsic::getDeclaration(F->getParent(), IID, ResultTy);
+ Rep = Builder.CreateCall(Intr, { CI->getOperand(0), CI->getOperand(1),
+ 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");
- Name = Name.substr(9); // strip off "xop.vpcom"
unsigned Imm;
- if (Name.startswith("lt"))
- Imm = 0;
- else if (Name.startswith("le"))
- Imm = 1;
- else if (Name.startswith("gt"))
- Imm = 2;
- else if (Name.startswith("ge"))
- Imm = 3;
- else if (Name.startswith("eq"))
- Imm = 4;
- else if (Name.startswith("ne"))
- Imm = 5;
- else if (Name.startswith("false"))
- Imm = 6;
- else if (Name.startswith("true"))
- Imm = 7;
- else
- llvm_unreachable("Unknown condition");
+ if (CI->getNumArgOperands() == 3) {
+ Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
+ } else {
+ Name = Name.substr(9); // strip off "xop.vpcom"
+ if (Name.startswith("lt"))
+ Imm = 0;
+ else if (Name.startswith("le"))
+ Imm = 1;
+ else if (Name.startswith("gt"))
+ Imm = 2;
+ else if (Name.startswith("ge"))
+ Imm = 3;
+ else if (Name.startswith("eq"))
+ Imm = 4;
+ else if (Name.startswith("ne"))
+ Imm = 5;
+ else if (Name.startswith("false"))
+ Imm = 6;
+ else if (Name.startswith("true"))
+ 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);
@@ -2104,6 +2269,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
if (CI->getNumArgOperands() == 3)
Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
CI->getArgOperand(1));
+ } else if (Name == "avx512.mask.pmov.qd.256" ||
+ Name == "avx512.mask.pmov.qd.512" ||
+ Name == "avx512.mask.pmov.wb.256" ||
+ Name == "avx512.mask.pmov.wb.512") {
+ Type *Ty = CI->getArgOperand(1)->getType();
+ Rep = Builder.CreateTrunc(CI->getArgOperand(0), Ty);
+ Rep = EmitX86Select(Builder, CI->getArgOperand(2), Rep,
+ CI->getArgOperand(1));
} else if (IsX86 && (Name.startswith("avx.vbroadcastf128") ||
Name == "avx2.vbroadcasti128")) {
// Replace vbroadcastf128/vbroadcasti128 with a vector load+shuffle.
@@ -2112,7 +2285,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Type *VT = VectorType::get(EltTy, NumSrcElts);
Value *Op = Builder.CreatePointerCast(CI->getArgOperand(0),
PointerType::getUnqual(VT));
- Value *Load = Builder.CreateAlignedLoad(Op, 1);
+ Value *Load = Builder.CreateAlignedLoad(VT, Op, 1);
if (NumSrcElts == 2)
Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()),
{ 0, 1, 0, 1 });
@@ -2858,28 +3031,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Convert the type of the pointer to a pointer to the stored type.
Value *BC =
Builder.CreateBitCast(Ptr, PointerType::getUnqual(VTy), "cast");
- LoadInst *LI = Builder.CreateAlignedLoad(BC, VTy->getBitWidth() / 8);
+ LoadInst *LI = Builder.CreateAlignedLoad(VTy, 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 (IsX86 && (Name.startswith("fma.vfmadd.") ||
Name.startswith("fma.vfmsub.") ||
Name.startswith("fma.vfnmadd.") ||
@@ -3274,6 +3428,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *Cmp = Builder.CreateICmpSGE(
Arg, llvm::Constant::getNullValue(Arg->getType()), "abs.cond");
Rep = Builder.CreateSelect(Cmp, Arg, Neg, "abs");
+ } else if (IsNVVM && (Name.startswith("atomic.load.add.f32.p") ||
+ Name.startswith("atomic.load.add.f64.p"))) {
+ Value *Ptr = CI->getArgOperand(0);
+ Value *Val = CI->getArgOperand(1);
+ Rep = Builder.CreateAtomicRMW(AtomicRMWInst::FAdd, Ptr, Val,
+ AtomicOrdering::SequentiallyConsistent);
} else if (IsNVVM && (Name == "max.i" || Name == "max.ll" ||
Name == "max.ui" || Name == "max.ull")) {
Value *Arg0 = CI->getArgOperand(0);
@@ -3335,7 +3495,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
DefaultCase();
return;
}
-
+ case Intrinsic::experimental_vector_reduce_v2_fmul: {
+ SmallVector<Value *, 2> Args;
+ if (CI->isFast())
+ Args.push_back(ConstantFP::get(CI->getOperand(0)->getType(), 1.0));
+ else
+ Args.push_back(CI->getOperand(0));
+ Args.push_back(CI->getOperand(1));
+ NewCall = Builder.CreateCall(NewFn, Args);
+ cast<Instruction>(NewCall)->copyFastMathFlags(CI);
+ break;
+ }
+ case Intrinsic::experimental_vector_reduce_v2_fadd: {
+ SmallVector<Value *, 2> Args;
+ if (CI->isFast())
+ Args.push_back(Constant::getNullValue(CI->getOperand(0)->getType()));
+ else
+ Args.push_back(CI->getOperand(0));
+ Args.push_back(CI->getOperand(1));
+ NewCall = Builder.CreateCall(NewFn, Args);
+ cast<Instruction>(NewCall)->copyFastMathFlags(CI);
+ break;
+ }
case Intrinsic::arm_neon_vld1:
case Intrinsic::arm_neon_vld2:
case Intrinsic::arm_neon_vld3:
@@ -3372,8 +3553,10 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Value *NullIsUnknownSize = CI->getNumArgOperands() == 2
? Builder.getFalse()
: CI->getArgOperand(2);
+ Value *Dynamic =
+ CI->getNumArgOperands() < 4 ? Builder.getFalse() : CI->getArgOperand(3);
NewCall = Builder.CreateCall(
- NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize});
+ NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic});
break;
}
@@ -3650,8 +3833,8 @@ bool llvm::UpgradeDebugInfo(Module &M) {
bool llvm::UpgradeRetainReleaseMarker(Module &M) {
bool Changed = false;
- NamedMDNode *ModRetainReleaseMarker =
- M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker");
+ const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+ NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
if (ModRetainReleaseMarker) {
MDNode *Op = ModRetainReleaseMarker->getOperand(0);
if (Op) {
@@ -3661,11 +3844,11 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) {
ID->getString().split(ValueComp, "#");
if (ValueComp.size() == 2) {
std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();
- Metadata *Ops[1] = {MDString::get(M.getContext(), NewValue)};
- ModRetainReleaseMarker->setOperand(0,
- MDNode::get(M.getContext(), Ops));
- Changed = true;
+ ID = MDString::get(M.getContext(), NewValue);
}
+ M.addModuleFlag(Module::Error, MarkerKey, ID);
+ M.eraseNamedMetadata(ModRetainReleaseMarker);
+ Changed = true;
}
}
}