Correctly vectorize powi.

The powi intrinsic requires special handling because it always takes a single
integer power regardless of the result type. As a result, we can vectorize
only if the powers are equal. Fixes PR12364.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153797 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel
2012-03-31 03:38:40 +00:00
parent 9f2a9d741f
commit 6173ed95da
2 changed files with 77 additions and 11 deletions

View File

@@ -647,6 +647,20 @@ namespace {
// FIXME: We may want to vectorize non-constant shuffles also.
}
// The powi intrinsic is special because only the first argument is
// vectorized, the second arguments must be equal.
CallInst *CI = dyn_cast<CallInst>(I);
Function *FI;
if (CI && (FI = CI->getCalledFunction()) &&
FI->getIntrinsicID() == Intrinsic::powi) {
Value *A1I = CI->getArgOperand(1),
*A1J = cast<CallInst>(J)->getArgOperand(1);
const SCEV *A1ISCEV = SE->getSCEV(A1I),
*A1JSCEV = SE->getSCEV(A1J);
return (A1ISCEV == A1JSCEV);
}
return true;
}
@@ -1518,19 +1532,27 @@ namespace {
ReplacedOperands[o] = getReplacementPointerInput(Context, I, J, o,
FlipMemInputs);
continue;
} else if (isa<CallInst>(I) && o == NumOperands-1) {
} else if (isa<CallInst>(I)) {
Function *F = cast<CallInst>(I)->getCalledFunction();
unsigned IID = F->getIntrinsicID();
BasicBlock &BB = *I->getParent();
Module *M = BB.getParent()->getParent();
Type *ArgType = I->getType();
Type *VArgType = getVecTypeForPair(ArgType);
// FIXME: is it safe to do this here?
ReplacedOperands[o] = Intrinsic::getDeclaration(M,
(Intrinsic::ID) IID, VArgType);
continue;
if (o == NumOperands-1) {
BasicBlock &BB = *I->getParent();
Module *M = BB.getParent()->getParent();
Type *ArgType = I->getType();
Type *VArgType = getVecTypeForPair(ArgType);
// FIXME: is it safe to do this here?
ReplacedOperands[o] = Intrinsic::getDeclaration(M,
(Intrinsic::ID) IID, VArgType);
continue;
} else if (IID == Intrinsic::powi && o == 1) {
// The second argument of powi is a single integer and we've already
// checked that both arguments are equal. As a result, we just keep
// I's second argument.
ReplacedOperands[o] = I->getOperand(o);
continue;
}
} else if (isa<ShuffleVectorInst>(I) && o == NumOperands-1) {
ReplacedOperands[o] = getReplacementShuffleMask(Context, I, J);
continue;