summaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-09-01 23:50:19 +0000
committerBob Wilson <bob.wilson@apple.com>2010-09-01 23:50:19 +0000
commitd0b69cf1198dadbb7bdfc385334b67f60f756539 (patch)
treea859ccd0b1fbc03df8dd39a7a8d3b0805fd6ae8e /lib/VMCore
parenta2259e17b7c657ddeb0c3a03a5ca291ca4e0dc7e (diff)
downloadllvm-d0b69cf1198dadbb7bdfc385334b67f60f756539.tar.gz
llvm-d0b69cf1198dadbb7bdfc385334b67f60f756539.tar.bz2
llvm-d0b69cf1198dadbb7bdfc385334b67f60f756539.tar.xz
Remove NEON vmull, vmlal, and vmlsl intrinsics, replacing them with multiply,
add, and subtract operations with zero-extended or sign-extended vectors. Update tests. Add auto-upgrade support for the old intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112773 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AutoUpgrade.cpp73
1 files changed, 52 insertions, 21 deletions
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index c994339653..e625d413f5 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -90,6 +90,12 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
(Name.compare(19, 2, "s.", 2) == 0 ||
Name.compare(19, 2, "u.", 2) == 0)) ||
+ ((Name.compare(14, 5, "vmull", 5) == 0 ||
+ Name.compare(14, 5, "vmlal", 5) == 0 ||
+ Name.compare(14, 5, "vmlsl", 5) == 0) &&
+ (Name.compare(19, 2, "s.", 2) == 0 ||
+ Name.compare(19, 2, "u.", 2) == 0)) ||
+
(Name.compare(14, 6, "vmovn.", 6) == 0)) {
// Calls to these are transformed into IR without intrinsics.
@@ -359,6 +365,32 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
return Upgraded;
}
+/// ExtendNEONArgs - For NEON "long" and "wide" operations, where the results
+/// have vector elements twice as big as one or both source operands, do the
+/// sign- or zero-extension that used to be handled by intrinsics. The
+/// extended values are returned via V0 and V1.
+static void ExtendNEONArgs(CallInst *CI, Value *Arg0, Value *Arg1,
+ Value *&V0, Value *&V1) {
+ Function *F = CI->getCalledFunction();
+ const std::string& Name = F->getName();
+ bool isLong = (Name.at(18) == 'l');
+ bool isSigned = (Name.at(19) == 's');
+
+ if (isSigned) {
+ if (isLong)
+ V0 = new SExtInst(Arg0, CI->getType(), "", CI);
+ else
+ V0 = Arg0;
+ V1 = new SExtInst(Arg1, CI->getType(), "", CI);
+ } else {
+ if (isLong)
+ V0 = new ZExtInst(Arg0, CI->getType(), "", CI);
+ else
+ V0 = Arg0;
+ V1 = new ZExtInst(Arg1, CI->getType(), "", CI);
+ }
+}
+
// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
// upgraded intrinsic. All argument and return casting must be provided in
// order to seamlessly integrate with existing context.
@@ -376,33 +408,32 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Upgrade ARM NEON intrinsics.
if (Name.compare(5, 9, "arm.neon.", 9) == 0) {
Instruction *NewI;
+ Value *V0, *V1;
if (Name.compare(14, 7, "vmovls.", 7) == 0) {
NewI = new SExtInst(CI->getArgOperand(0), CI->getType(),
"upgraded." + CI->getName(), CI);
} else if (Name.compare(14, 7, "vmovlu.", 7) == 0) {
NewI = new ZExtInst(CI->getArgOperand(0), CI->getType(),
"upgraded." + CI->getName(), CI);
-
- } else if (Name.compare(14, 4, "vadd", 4) == 0 ||
- Name.compare(14, 4, "vsub", 4) == 0) {
- // Extend one (vaddw/vsubw) or both (vaddl/vsubl) operands.
- Value *V0 = CI->getArgOperand(0);
- Value *V1 = CI->getArgOperand(1);
- if (Name.at(19) == 's') {
- if (Name.at(18) == 'l')
- V0 = new SExtInst(CI->getArgOperand(0), CI->getType(), "", CI);
- V1 = new SExtInst(CI->getArgOperand(1), CI->getType(), "", CI);
- } else {
- assert(Name.at(19) == 'u' && "unexpected vadd/vsub intrinsic");
- if (Name.at(18) == 'l')
- V0 = new ZExtInst(CI->getArgOperand(0), CI->getType(), "", CI);
- V1 = new ZExtInst(CI->getArgOperand(1), CI->getType(), "", CI);
- }
- if (Name.compare(14, 4, "vadd", 4) == 0)
- NewI = BinaryOperator::CreateAdd(V0, V1,"upgraded."+CI->getName(),CI);
- else
- NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI);
-
+ } else if (Name.compare(14, 4, "vadd", 4) == 0) {
+ ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
+ NewI = BinaryOperator::CreateAdd(V0, V1, "upgraded."+CI->getName(), CI);
+ } else if (Name.compare(14, 4, "vsub", 4) == 0) {
+ ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
+ NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI);
+ } else if (Name.compare(14, 4, "vmul", 4) == 0) {
+ ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1);
+ NewI = BinaryOperator::CreateMul(V0, V1,"upgraded."+CI->getName(),CI);
+ } else if (Name.compare(14, 4, "vmla", 4) == 0) {
+ ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1);
+ Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI);
+ NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), MulI,
+ "upgraded."+CI->getName(), CI);
+ } else if (Name.compare(14, 4, "vmls", 4) == 0) {
+ ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1);
+ Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI);
+ NewI = BinaryOperator::CreateSub(CI->getArgOperand(0), MulI,
+ "upgraded."+CI->getName(), CI);
} else if (Name.compare(14, 6, "vmovn.", 6) == 0) {
NewI = new TruncInst(CI->getArgOperand(0), CI->getType(),
"upgraded." + CI->getName(), CI);