[llvm-commits] [dragonegg] r101890 - /dragonegg/trunk/x86/llvm-target.cpp
Duncan Sands
baldrick at free.fr
Tue Apr 20 01:04:00 PDT 2010
Author: baldrick
Date: Tue Apr 20 03:04:00 2010
New Revision: 101890
URL: http://llvm.org/viewvc/llvm-project?rev=101890&view=rev
Log:
Port commit 101333 (echristo) from llvm-gcc:
Rewrite palignr and palignr128 handling to use vector shuffle if possible
instead of intrinsic.
Modified:
dragonegg/trunk/x86/llvm-target.cpp
Modified: dragonegg/trunk/x86/llvm-target.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/x86/llvm-target.cpp?rev=101890&r1=101889&r2=101890&view=diff
==============================================================================
--- dragonegg/trunk/x86/llvm-target.cpp (original)
+++ dragonegg/trunk/x86/llvm-target.cpp Tue Apr 20 03:04:00 2010
@@ -751,7 +751,6 @@
}
bool flip = false;
- Intrinsic::ID IntrID;
unsigned PredCode;
goto *Handler;
@@ -1248,25 +1247,107 @@
Result = Builder.CreateLoad(Ptr);
return true;
}
- IX86_BUILTIN_PALIGNR:
- IntrID = Intrinsic::x86_ssse3_palign_r;
- goto PALIGNR;
- IX86_BUILTIN_PALIGNR128:
- IntrID = Intrinsic::x86_ssse3_palign_r_128;
- goto PALIGNR;
- PALIGNR:
+ IX86_BUILTIN_PALIGNR: {
if (isa<ConstantInt>(Ops[2])) {
- Function *palignr =
- Intrinsic::getDeclaration(TheModule, IntrID);
- Value *Op2 = Builder.CreateTrunc(Ops[2], Type::getInt8Ty(Context));
- Value *CallOps[3] = { Ops[0], Ops[1], Op2 };
- Result = Builder.CreateCall(palignr, CallOps, CallOps+3);
+
+ // In the header we multiply by 8, correct that back now.
+ unsigned shiftVal = (cast<ConstantInt>(Ops[2])->getZExtValue())/8;
+
+ // If palignr is shifting the pair of input vectors less than 9 bytes,
+ // emit a shuffle instruction.
+ if (shiftVal <= 8) {
+ const llvm::Type *IntTy = Type::getInt32Ty(Context);
+ const llvm::Type *EltTy = Type::getInt8Ty(Context);
+ const llvm::Type *VecTy = VectorType::get(EltTy, 8);
+
+ Ops[1] = Builder.CreateBitCast(Ops[1], VecTy);
+ Ops[0] = Builder.CreateBitCast(Ops[0], VecTy);
+
+ SmallVector<Constant*, 8> Indices;
+ for (unsigned i = 0; i != 8; ++i)
+ Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
+
+ Value* SV = ConstantVector::get(Indices.begin(), Indices.size());
+ Result = Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
+ return true;
+ }
+
+ // If palignr is shifting the pair of input vectors more than 8 but less
+ // than 16 bytes, emit a logical right shift of the destination.
+ if (shiftVal < 16) {
+ // MMX has these as 1 x i64 vectors for some odd optimization reasons.
+ const llvm::Type *EltTy = Type::getInt64Ty(Context);
+ const llvm::Type *VecTy = VectorType::get(EltTy, 1);
+
+ Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
+ Ops[1] = ConstantInt::get(VecTy, (shiftVal-8) * 8);
+
+ // create i32 constant
+ Function *F = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::x86_mmx_psrl_q);
+ Result = Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
+ return true;
+ }
+
+ // If palignr is shifting the pair of vectors more than 32 bytes,
+ // emit zero.
+ Result = Constant::getNullValue(ResultType);
+ return true;
+ } else {
+ error_at(gimple_location(stmt), "mask must be an immediate");
+ Result = Ops[0];
+ return true;
+ }
+ }
+ IX86_BUILTIN_PALIGNR128: {
+ if (isa<ConstantInt>(Ops[2])) {
+ unsigned shiftVal = cast<ConstantInt>(Ops[2])->getZExtValue();
+
+ // If palignr is shifting the pair of input vectors less than 17 bytes,
+ // emit a shuffle instruction.
+ if (shiftVal <= 16) {
+ const llvm::Type *IntTy = Type::getInt32Ty(Context);
+ const llvm::Type *EltTy = Type::getInt8Ty(Context);
+ const llvm::Type *VecTy = VectorType::get(EltTy, 16);
+
+ Ops[1] = Builder.CreateBitCast(Ops[1], VecTy);
+ Ops[0] = Builder.CreateBitCast(Ops[0], VecTy);
+
+ llvm::SmallVector<Constant*, 16> Indices;
+ for (unsigned i = 0; i != 16; ++i)
+ Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
+
+ Value* SV = ConstantVector::get(Indices.begin(), Indices.size());
+ Result = Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
+ return true;
+ }
+
+ // If palignr is shifting the pair of input vectors more than 16 but less
+ // than 32 bytes, emit a logical right shift of the destination.
+ if (shiftVal < 32) {
+ const llvm::Type *EltTy = Type::getInt64Ty(Context);
+ const llvm::Type *VecTy = VectorType::get(EltTy, 2);
+ const llvm::Type *IntTy = Type::getInt32Ty(Context);
+
+ Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
+ Ops[1] = ConstantInt::get(IntTy, (shiftVal-16) * 8);
+
+ // create i32 constant
+ llvm::Function *F = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::x86_sse2_psrl_dq);
+ Result = Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
+ return true;
+ }
+
+ // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
+ Result = Constant::getNullValue(ResultType);
return true;
} else {
error_at(gimple_location(stmt), "mask must be an immediate");
Result = Ops[0];
return true;
}
+ }
}
/* These are defined in i386.c */
More information about the llvm-commits
mailing list