aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp31
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp6
-rw-r--r--test/CodeGen/X86/vec_ctbits.ll18
3 files changed, 46 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index a93a41dfc9..a1b1d971a3 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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,
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 67217fd992..07e19aad34 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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
index 0000000000..bad8b2221e
--- /dev/null
+++ b/test/CodeGen/X86/vec_ctbits.ll
@@ -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
+}