[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.

llvm-svn: 187397
This commit is contained in:
Quentin Colombet 2013-07-30 00:27:16 +00:00
parent 6bf4baa408
commit e2e0548d77
2 changed files with 56 additions and 1 deletions

View File

@ -89,6 +89,7 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
setTargetDAGCombine(ISD::FP_TO_SINT); setTargetDAGCombine(ISD::FP_TO_SINT);
setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
setTargetDAGCombine(ISD::SELECT_CC); setTargetDAGCombine(ISD::SELECT_CC);
setTargetDAGCombine(ISD::INSERT_VECTOR_ELT);
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
@ -1409,6 +1410,61 @@ SDValue R600TargetLowering::PerformDAGCombine(SDNode *N,
break; 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 // Extract_vec (Build_vector) generated by custom lowering
// also needs to be customly combined // also needs to be customly combined
case ISD::EXTRACT_VECTOR_ELT: { case ISD::EXTRACT_VECTOR_ELT: {

View File

@ -1,5 +1,4 @@
; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=EG-CHECK %s ; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=EG-CHECK %s
; XFAIL: *
;EG-CHECK: @main ;EG-CHECK: @main
;EG-CHECK: EXPORT T{{[0-9]+}}.XYXX ;EG-CHECK: EXPORT T{{[0-9]+}}.XYXX