diff options
author | Bob Wilson <bob.wilson@apple.com> | 2010-09-17 22:59:05 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2010-09-17 22:59:05 +0000 |
commit | 75f0288b7dff1fcb24d9d61ea3e9547ba21382e4 (patch) | |
tree | 5091aa136523197a9f73e5a2185e09850c683355 /lib/Target/ARM/ARMISelLowering.cpp | |
parent | e6be85e9ff6bd28c599421a120a8491257c13ebd (diff) | |
download | external_llvm-75f0288b7dff1fcb24d9d61ea3e9547ba21382e4.zip external_llvm-75f0288b7dff1fcb24d9d61ea3e9547ba21382e4.tar.gz external_llvm-75f0288b7dff1fcb24d9d61ea3e9547ba21382e4.tar.bz2 |
Add target-specific DAG combiner for BUILD_VECTOR and VMOVRRD. An i64
value should be in GPRs when it's going to be used as a scalar, and we use
VMOVRRD to make that happen, but if the value is converted back to a vector
we need to fold to a simple bit_convert. Radar 8407927.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114233 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index fbfb472..3111ff5 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -326,6 +326,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setTargetDAGCombine(ISD::ZERO_EXTEND); setTargetDAGCombine(ISD::ANY_EXTEND); setTargetDAGCombine(ISD::SELECT_CC); + setTargetDAGCombine(ISD::BUILD_VECTOR); } computeRegisterProperties(); @@ -4342,6 +4343,31 @@ static SDValue PerformORCombine(SDNode *N, return SDValue(); } +/// PerformBUILD_VECTORCombine - Target-specific dag combine xforms for +/// ISD::BUILD_VECTOR. +static SDValue PerformBUILD_VECTORCombine(SDNode *N, SelectionDAG &DAG) { + // build_vector(N=ARMISD::VMOVRRD(X), N:1) -> bit_convert(X): + // VMOVRRD is introduced when legalizing i64 types. It forces the i64 value + // into a pair of GPRs, which is fine when the value is used as a scalar, + // but if the i64 value is converted to a vector, we need to undo the VMOVRRD. + if (N->getNumOperands() == 2) { + SDValue Op0 = N->getOperand(0); + SDValue Op1 = N->getOperand(1); + if (Op0.getOpcode() == ISD::BIT_CONVERT) + Op0 = Op0.getOperand(0); + if (Op1.getOpcode() == ISD::BIT_CONVERT) + Op1 = Op1.getOperand(0); + if (Op0.getOpcode() == ARMISD::VMOVRRD && + Op0.getNode() == Op1.getNode() && + Op0.getResNo() == 0 && Op1.getResNo() == 1) { + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + N->getValueType(0), Op0.getOperand(0)); + } + } + + return SDValue(); +} + /// PerformVMOVRRDCombine - Target-specific dag combine xforms for /// ARMISD::VMOVRRD. static SDValue PerformVMOVRRDCombine(SDNode *N, @@ -4760,6 +4786,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, case ISD::SUB: return PerformSUBCombine(N, DCI); case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget); case ISD::OR: return PerformORCombine(N, DCI, Subtarget); + case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI.DAG); case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI); case ARMISD::VDUPLANE: return PerformVDUPLANECombine(N, DCI); case ISD::INTRINSIC_WO_CHAIN: return PerformIntrinsicCombine(N, DCI.DAG); |