[llvm-commits] [llvm-gcc-4.2] r101333 - /llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
Eric Christopher
echristo at apple.com
Wed Apr 14 18:44:18 PDT 2010
Author: echristo
Date: Wed Apr 14 20:44:18 2010
New Revision: 101333
URL: http://llvm.org/viewvc/llvm-project?rev=101333&view=rev
Log:
Rewrite palignr and palignr128 handling to use vector shuffle if possible
instead of intrinsic.
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=101333&r1=101332&r2=101333&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Wed Apr 14 20:44:18 2010
@@ -607,16 +607,100 @@
Result = Builder.CreateLoad(Ptr);
return true;
}
- case IX86_BUILTIN_PALIGNR:
+ case IX86_BUILTIN_PALIGNR: {
+ if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[2])) {
+
+ // 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("%Hmask must be an immediate", &EXPR_LOCATION(exp));
+ Result = Ops[0];
+ return true;
+ }
+ }
case IX86_BUILTIN_PALIGNR128: {
if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[2])) {
- Function *palignr =
- Intrinsic::getDeclaration(TheModule, FnCode == IX86_BUILTIN_PALIGNR ?
- Intrinsic::x86_ssse3_palign_r :
- Intrinsic::x86_ssse3_palign_r_128);
- Value *Op2 = Builder.CreateTrunc(Ops[2], Type::getInt8Ty(Context));
- Value *CallOps[3] = { Ops[0], Ops[1], Op2 };
- Result = Builder.CreateCall(palignr, CallOps, CallOps+3);
+ 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("%Hmask must be an immediate", &EXPR_LOCATION(exp));
More information about the llvm-commits
mailing list