llvm.org GIT mirror llvm / 1a5cc71
Teach DAG combine to fold (buildvec (Xint2fp x)) to (Xint2fp (buildvec x)) - If more than 1 elemennts are defined and target supports the vectorized conversion, use the vectorized one instead to reduce the strength on conversion operation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166546 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Liao 7 years ago
2 changed file(s) with 85 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
270270 SDValue ReduceLoadOpStoreWidth(SDNode *N);
271271 SDValue TransformFPLoadStorePair(SDNode *N);
272272 SDValue reduceBuildVecExtToExtBuildVec(SDNode *N);
273 SDValue reduceBuildVecConvertToConvertBuildVec(SDNode *N);
273274
274275 SDValue GetDemandedBits(SDValue V, const APInt &Mask);
275276
84668467 return DAG.getNode(ISD::BITCAST, dl, VT, BV);
84678468 }
84688469
8470 SDValue DAGCombiner::reduceBuildVecConvertToConvertBuildVec(SDNode *N) {
8471 EVT VT = N->getValueType(0);
8472
8473 unsigned NumInScalars = N->getNumOperands();
8474 DebugLoc dl = N->getDebugLoc();
8475
8476 EVT SrcVT = MVT::Other;
8477 unsigned Opcode = ISD::DELETED_NODE;
8478 unsigned NumDefs = 0;
8479
8480 for (unsigned i = 0; i != NumInScalars; ++i) {
8481 SDValue In = N->getOperand(i);
8482 unsigned Opc = In.getOpcode();
8483
8484 if (Opc == ISD::UNDEF)
8485 continue;
8486
8487 // If all scalar values are floats and converted from integers.
8488 if (Opcode == ISD::DELETED_NODE &&
8489 (Opc == ISD::UINT_TO_FP || Opc == ISD::SINT_TO_FP)) {
8490 Opcode = Opc;
8491 // If not supported by target, bail out.
8492 if (TLI.getOperationAction(Opcode, VT) != TargetLowering::Legal &&
8493 TLI.getOperationAction(Opcode, VT) != TargetLowering::Custom)
8494 return SDValue();
8495 }
8496 if (Opc != Opcode)
8497 return SDValue();
8498
8499 EVT InVT = In.getOperand(0).getValueType();
8500
8501 // If all scalar values are typed differently, bail out. It's chosen to
8502 // simplify BUILD_VECTOR of integer types.
8503 if (SrcVT == MVT::Other)
8504 SrcVT = InVT;
8505 if (SrcVT != InVT)
8506 return SDValue();
8507 NumDefs++;
8508 }
8509
8510 // If the vector has just one element defined, it's not worth to fold it into
8511 // a vectorized one.
8512 if (NumDefs < 2)
8513 return SDValue();
8514
8515 assert((Opcode == ISD::UINT_TO_FP || Opcode == ISD::SINT_TO_FP)
8516 && "Should only handle conversion from integer to float.");
8517 assert(SrcVT != MVT::Other && "Cannot determine source type!");
8518
8519 EVT NVT = EVT::getVectorVT(*DAG.getContext(), SrcVT, NumInScalars);
8520 SmallVector Opnds;
8521 for (unsigned i = 0; i != NumInScalars; ++i) {
8522 SDValue In = N->getOperand(i);
8523
8524 if (In.getOpcode() == ISD::UNDEF)
8525 Opnds.push_back(DAG.getUNDEF(SrcVT));
8526 else
8527 Opnds.push_back(In.getOperand(0));
8528 }
8529 SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT,
8530 &Opnds[0], Opnds.size());
8531 AddToWorkList(BV.getNode());
8532
8533 return DAG.getNode(Opcode, dl, VT, BV);
8534 }
8535
84698536 SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
84708537 unsigned NumInScalars = N->getNumOperands();
84718538 DebugLoc dl = N->getDebugLoc();
84768543 return DAG.getUNDEF(VT);
84778544
84788545 SDValue V = reduceBuildVecExtToExtBuildVec(N);
8546 if (V.getNode())
8547 return V;
8548
8549 V = reduceBuildVecConvertToConvertBuildVec(N);
84798550 if (V.getNode())
84808551 return V;
84818552
0 ; RUN: llc < %s -mtriple=i686-linux-pc -mcpu=corei7 | FileCheck %s
1
2 define <2 x float> @foo(i32 %x, i32 %y, <2 x float> %v) {
3 %t1 = uitofp i32 %x to float
4 %t2 = insertelement <2 x float> undef, float %t1, i32 0
5 %t3 = uitofp i32 %y to float
6 %t4 = insertelement <2 x float> %t2, float %t3, i32 1
7 %t5 = fmul <2 x float> %v, %t4
8 ret <2 x float> %t5
9 ; CHECK: foo
10 ; CHECK: or
11 ; CHECK: subpd
12 ; CHECK: cvtpd2ps
13 ; CHECK: ret
14 }
115
216 define <2 x float> @bar(<2 x i32> %in) {
317 %r = uitofp <2 x i32> %in to <2 x float>