Allow vector integer constants to be created with
authorDan Gohman <gohman@apple.com>
Wed, 12 Dec 2007 22:21:26 +0000 (22:21 +0000)
committerDan Gohman <gohman@apple.com>
Wed, 12 Dec 2007 22:21:26 +0000 (22:21 +0000)
SelectionDAG::getConstant, in the same way as vector floating-point
constants. This allows the legalize expansion code for @llvm.ctpop and
friends to be usable with vector types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44954 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/vec_ctbits.ll [new file with mode: 0644]

index a93a41dfc98afbee782eab6d6c3c984cfd042046..a1b1d971a3a59be9289221452ee465f0f79c7c6a 100644 (file)
@@ -687,22 +687,35 @@ SDOperand SelectionDAG::getString(const std::string &Val) {
 
 SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT, bool isT) {
   assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
-  assert(!MVT::isVector(VT) && "Cannot create Vector ConstantSDNodes!");
+
+  MVT::ValueType EltVT =
+    MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT;
   
   // Mask out any bits that are not valid for this constant.
-  Val &= MVT::getIntVTBitMask(VT);
+  Val &= MVT::getIntVTBitMask(EltVT);
 
   unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;
   FoldingSetNodeID ID;
-  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
+  AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
   ID.AddInteger(Val);
   void *IP = 0;
-  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
-    return SDOperand(E, 0);
-  SDNode *N = new ConstantSDNode(isT, Val, VT);
-  CSEMap.InsertNode(N, IP);
-  AllNodes.push_back(N);
-  return SDOperand(N, 0);
+  SDNode *N = NULL;
+  if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
+    if (!MVT::isVector(VT))
+      return SDOperand(N, 0);
+  if (!N) {
+    N = new ConstantSDNode(isT, Val, EltVT);
+    CSEMap.InsertNode(N, IP);
+    AllNodes.push_back(N);
+  }
+
+  SDOperand Result(N, 0);
+  if (MVT::isVector(VT)) {
+    SmallVector<SDOperand, 8> Ops;
+    Ops.assign(MVT::getVectorNumElements(VT), Result);
+    Result = getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
+  }
+  return Result;
 }
 
 SDOperand SelectionDAG::getConstantFP(const APFloat& V, MVT::ValueType VT,
index 67217fd992499dd8575921135cbc926742e49965..07e19aad34bd556cb908fd22448ca240807e6a27 100644 (file)
@@ -483,6 +483,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::CTPOP, (MVT::ValueType)VT, Expand);
     setOperationAction(ISD::CTTZ, (MVT::ValueType)VT, Expand);
     setOperationAction(ISD::CTLZ, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::SHL, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::SRA, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::SRL, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::ROTL, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::ROTR, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::BSWAP, (MVT::ValueType)VT, Expand);
   }
 
   if (Subtarget->hasMMX()) {
diff --git a/test/CodeGen/X86/vec_ctbits.ll b/test/CodeGen/X86/vec_ctbits.ll
new file mode 100644 (file)
index 0000000..bad8b22
--- /dev/null
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llc -march=x86-64
+
+declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>)
+declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>)
+declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
+
+define <2 x i64> @footz(<2 x i64> %a) {
+  %c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a)
+  ret <2 x i64> %c
+}
+define <2 x i64> @foolz(<2 x i64> %a) {
+  %c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a)
+  ret <2 x i64> %c
+}
+define <2 x i64> @foopop(<2 x i64> %a) {
+  %c = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+  ret <2 x i64> %c
+}