X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FAutoUpgrade.cpp;h=aeefa38f74d6cb6ebe4f1092020915339ce33700;hb=3f1c66ca7df09f54022f19f5233901dc049d5a0f;hp=43abdd2d1e8ecc1d637fedb691f79bb1c5e5c234;hpb=9584e07a9cf5261011e70951a3e6286d54643bb1;p=oota-llvm.git diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index 43abdd2d1e8..aeefa38f74d 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -129,6 +129,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name.startswith("x86.sse2.pcmpgt.") || Name.startswith("x86.avx2.pcmpeq.") || Name.startswith("x86.avx2.pcmpgt.") || + Name.startswith("x86.avx2.vbroadcast") || + Name.startswith("x86.avx2.pbroadcast") || Name.startswith("x86.avx.vpermil.") || Name == "x86.avx.vinsertf128.pd.256" || Name == "x86.avx.vinsertf128.ps.256" || @@ -229,6 +231,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { NewFn = nullptr; bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); + assert(F != NewFn && "Intrinsic function upgraded to the same function"); // Upgrade intrinsic attributes. This does not change the function. if (NewFn) @@ -431,7 +434,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { unsigned EltNum = VecTy->getVectorNumElements(); Value *Cast = Builder.CreateBitCast(CI->getArgOperand(0), EltTy->getPointerTo()); - Value *Load = Builder.CreateLoad(Cast); + Value *Load = Builder.CreateLoad(EltTy, Cast); Type *I32Ty = Type::getInt32Ty(C); Rep = UndefValue::get(VecTy); for (unsigned I = 0; I < EltNum; ++I) @@ -439,13 +442,21 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { ConstantInt::get(I32Ty, I)); } else if (Name == "llvm.x86.avx2.vbroadcasti128") { // Replace vbroadcasts with a vector shuffle. - Value *Op = Builder.CreatePointerCast( - CI->getArgOperand(0), - PointerType::getUnqual(VectorType::get(Type::getInt64Ty(C), 2))); - Value *Load = Builder.CreateLoad(Op); + Type *VT = VectorType::get(Type::getInt64Ty(C), 2); + Value *Op = Builder.CreatePointerCast(CI->getArgOperand(0), + PointerType::getUnqual(VT)); + Value *Load = Builder.CreateLoad(VT, Op); const int Idxs[4] = { 0, 1, 0, 1 }; Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()), Idxs); + } else if (Name.startswith("llvm.x86.avx2.pbroadcast") || + Name.startswith("llvm.x86.avx2.vbroadcast")) { + // Replace vp?broadcasts with a vector shuffle. + Value *Op = CI->getArgOperand(0); + unsigned NumElts = CI->getType()->getVectorNumElements(); + Type *MaskTy = VectorType::get(Type::getInt32Ty(C), NumElts); + Rep = Builder.CreateShuffleVector(Op, UndefValue::get(Op->getType()), + Constant::getNullValue(MaskTy)); } else if (Name == "llvm.x86.sse2.psll.dq") { // 128-bit shift left specified in bits. unsigned Shift = cast(CI->getArgOperand(1))->getZExtValue(); @@ -710,16 +721,14 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { // Upgrade the function and check if it is a totaly new function. Function *NewFn; if (UpgradeIntrinsicFunction(F, NewFn)) { - if (NewFn != F) { - // Replace all uses to the old function with the new one if necessary. - for (Value::user_iterator UI = F->user_begin(), UE = F->user_end(); - UI != UE; ) { - if (CallInst *CI = dyn_cast(*UI++)) - UpgradeIntrinsicCall(CI, NewFn); - } - // Remove old function, no longer used, from the module. - F->eraseFromParent(); + // Replace all uses to the old function with the new one if necessary. + for (Value::user_iterator UI = F->user_begin(), UE = F->user_end(); + UI != UE;) { + if (CallInst *CI = dyn_cast(*UI++)) + UpgradeIntrinsicCall(CI, NewFn); } + // Remove old function, no longer used, from the module. + F->eraseFromParent(); } }