[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