aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2013-07-30 00:27:16 +0000
committerQuentin Colombet <qcolombet@apple.com>2013-07-30 00:27:16 +0000
commit15d1b85094cf4c1520fdfd12db2111cd36a194db (patch)
treed311acd461d93ab0ef068737aeef6fa114044b37
parent75c9433b49b1e4e2d7e61249c3cd0e3ce910d5c8 (diff)
downloadexternal_llvm-15d1b85094cf4c1520fdfd12db2111cd36a194db.zip
external_llvm-15d1b85094cf4c1520fdfd12db2111cd36a194db.tar.gz
external_llvm-15d1b85094cf4c1520fdfd12db2111cd36a194db.tar.bz2
[R600] Replicate old DAGCombiner behavior in target specific DAG combine.
build_vector is lowered to REG_SEQUENCE, which is something the register allocator does a good job at optimizing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187397 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/R600/R600ISelLowering.cpp56
-rw-r--r--test/CodeGen/R600/swizzle-export.ll1
2 files changed, 56 insertions, 1 deletions
diff --git a/lib/Target/R600/R600ISelLowering.cpp b/lib/Target/R600/R600ISelLowering.cpp
index a2bc2c3..5610924 100644
--- a/lib/Target/R600/R600ISelLowering.cpp
+++ b/lib/Target/R600/R600ISelLowering.cpp
@@ -89,6 +89,7 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
setTargetDAGCombine(ISD::FP_TO_SINT);
setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
setTargetDAGCombine(ISD::SELECT_CC);
+ setTargetDAGCombine(ISD::INSERT_VECTOR_ELT);
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
@@ -1409,6 +1410,61 @@ SDValue R600TargetLowering::PerformDAGCombine(SDNode *N,
break;
}
+
+ // insert_vector_elt (build_vector elt0, …, eltN), NewEltIdx, idx
+ // => build_vector elt0, …, NewEltIdx, …, eltN
+ case ISD::INSERT_VECTOR_ELT: {
+ SDValue InVec = N->getOperand(0);
+ SDValue InVal = N->getOperand(1);
+ SDValue EltNo = N->getOperand(2);
+ SDLoc dl(N);
+
+ // If the inserted element is an UNDEF, just use the input vector.
+ if (InVal.getOpcode() == ISD::UNDEF)
+ return InVec;
+
+ EVT VT = InVec.getValueType();
+
+ // If we can't generate a legal BUILD_VECTOR, exit
+ if (!isOperationLegal(ISD::BUILD_VECTOR, VT))
+ return SDValue();
+
+ // Check that we know which element is being inserted
+ if (!isa<ConstantSDNode>(EltNo))
+ return SDValue();
+ unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
+
+ // Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially
+ // be converted to a BUILD_VECTOR). Fill in the Ops vector with the
+ // vector elements.
+ SmallVector<SDValue, 8> Ops;
+ if (InVec.getOpcode() == ISD::BUILD_VECTOR) {
+ Ops.append(InVec.getNode()->op_begin(),
+ InVec.getNode()->op_end());
+ } else if (InVec.getOpcode() == ISD::UNDEF) {
+ unsigned NElts = VT.getVectorNumElements();
+ Ops.append(NElts, DAG.getUNDEF(InVal.getValueType()));
+ } else {
+ return SDValue();
+ }
+
+ // Insert the element
+ if (Elt < Ops.size()) {
+ // All the operands of BUILD_VECTOR must have the same type;
+ // we enforce that here.
+ EVT OpVT = Ops[0].getValueType();
+ if (InVal.getValueType() != OpVT)
+ InVal = OpVT.bitsGT(InVal.getValueType()) ?
+ DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) :
+ DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal);
+ Ops[Elt] = InVal;
+ }
+
+ // Return the new vector
+ return DAG.getNode(ISD::BUILD_VECTOR, dl,
+ VT, &Ops[0], Ops.size());
+ }
+
// Extract_vec (Build_vector) generated by custom lowering
// also needs to be customly combined
case ISD::EXTRACT_VECTOR_ELT: {
diff --git a/test/CodeGen/R600/swizzle-export.ll b/test/CodeGen/R600/swizzle-export.ll
index 11d2cb1..b2175af 100644
--- a/test/CodeGen/R600/swizzle-export.ll
+++ b/test/CodeGen/R600/swizzle-export.ll
@@ -1,5 +1,4 @@
; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=EG-CHECK %s
-; XFAIL: *
;EG-CHECK: @main
;EG-CHECK: EXPORT T{{[0-9]+}}.XYXX