diff options
author | Sam Parker <sam.parker@arm.com> | 2019-12-12 14:30:09 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2019-12-12 14:34:00 +0000 |
commit | 1274ac3dc235dd596cc1ace2145c2b1e3c970b29 (patch) | |
tree | 027d98937098d8cb9f6c5a83f7d4dda417829484 /llvm/lib/Target/ARM/ARMISelLowering.cpp | |
parent | 6ce1a897b6a82e18059fd3b75b8d52ff12c2a605 (diff) | |
download | bcm5719-llvm-1274ac3dc235dd596cc1ace2145c2b1e3c970b29.tar.gz bcm5719-llvm-1274ac3dc235dd596cc1ace2145c2b1e3c970b29.zip |
[ARM][MVE] Sink vector shift operand
Recommit e0b966643fc2. sub instructions were being generated for the
negated value, and for some reason they were the register only ones.
I think the problem was because I was grabbing the 'zero' from
vmovimm, which is a target constant. Now I'm just generating a new
Constant zero and so rsb instructions are now generated.
Original commit message:
The shift amount operand can be provided in a general purpose
register so sink it. Flip the vdup and negate so the existing
patterns can be used for matching.
Differential Revision: https://reviews.llvm.org/D70841
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index c08f748c129..e38ce70a8dc 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -11814,7 +11814,8 @@ static SDValue PerformADDCombine(SDNode *N, /// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB. /// static SDValue PerformSUBCombine(SDNode *N, - TargetLowering::DAGCombinerInfo &DCI) { + TargetLowering::DAGCombinerInfo &DCI, + const ARMSubtarget *Subtarget) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -11823,7 +11824,28 @@ static SDValue PerformSUBCombine(SDNode *N, if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI)) return Result; - return SDValue(); + if (!Subtarget->hasMVEIntegerOps() || !N->getValueType(0).isVector()) + return SDValue(); + + // Fold (sub (ARMvmovImm 0), (ARMvdup x)) -> (ARMvdup (sub 0, x)) + // so that we can readily pattern match more mve instructions which can use + // a scalar operand. + SDValue VDup = N->getOperand(1); + if (VDup->getOpcode() != ARMISD::VDUP) + return SDValue(); + + SDValue VMov = N->getOperand(0); + if (VMov->getOpcode() == ISD::BITCAST) + VMov = VMov->getOperand(0); + + if (VMov->getOpcode() != ARMISD::VMOVIMM || !isZeroVector(VMov)) + return SDValue(); + + SDLoc dl(N); + SDValue Negate = DCI.DAG.getNode(ISD::SUB, dl, MVT::i32, + DCI.DAG.getConstant(0, dl, MVT::i32), + VDup->getOperand(0)); + return DCI.DAG.getNode(ARMISD::VDUP, dl, N->getValueType(0), Negate); } /// PerformVMULCombine @@ -14508,7 +14530,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, case ARMISD::ADDE: return PerformADDECombine(N, DCI, Subtarget); case ARMISD::UMLAL: return PerformUMLALCombine(N, DCI.DAG, Subtarget); case ISD::ADD: return PerformADDCombine(N, DCI, Subtarget); - case ISD::SUB: return PerformSUBCombine(N, DCI); + case ISD::SUB: return PerformSUBCombine(N, DCI, Subtarget); case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget); case ISD::OR: return PerformORCombine(N, DCI, Subtarget); case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget); @@ -14866,6 +14888,9 @@ bool ARMTargetLowering::shouldSinkOperands(Instruction *I, case Instruction::Mul: return true; case Instruction::Sub: + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: return Operand == 1; default: return false; |