[PATCH] D38084: [ARM] add, or, shl combining
John Brawn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 17 04:20:23 PDT 2017
john.brawn added a comment.
This patch does three distinct things (swap CMP operands, separate out OR->BFI conversion, unfold shl) and I think it would make more sense to therefore do three separate patches.
================
Comment at: lib/Target/ARM/ARMISelLowering.cpp:3858-3861
+ } else if ((LHS->getOpcode() == ISD::SHL || LHS->getOpcode() == ISD::SRL ||
+ LHS->getOpcode() == ISD::SRA || LHS->getOpcode() == ISD::ROTR) &&
+ (RHS->getOpcode() != ISD::SHL && RHS->getOpcode() != ISD::SRL &&
+ RHS->getOpcode() != ISD::SRA && RHS->getOpcode() != ISD::ROTR)) {
----------------
This could be simplified using getShiftOpcForNode from ARMSelectionDAGInfo.h (check LHS is not no_shift, check RHS is no_shift).
================
Comment at: lib/Target/ARM/ARMISelLowering.cpp:3862
+ RHS->getOpcode() != ISD::SRA && RHS->getOpcode() != ISD::ROTR)) {
+ // Compare instructions can shift their second operand.
+ SwapOperands = true;
----------------
Not in 16-bit thumb, though it's probably harmless to swap them in that case. The comment should mention that though.
================
Comment at: lib/Target/ARM/ARMISelLowering.cpp:10269
+
+ // Try combining OR nodes to SMULWB, SMULWT.
if (!Subtarget->hasV6Ops() ||
----------------
Moving this comment looks a little odd.
================
Comment at: lib/Target/ARM/ARMISelLowering.cpp:10327
-/// PerformORCombine - Target-specific dag combine xforms for ISD::OR
-static SDValue PerformORCombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI,
- const ARMSubtarget *Subtarget) {
- // Attempt to use immediate-form VORR
- BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
- SelectionDAG &DAG = DCI.DAG;
-
- if(!DAG.getTargetLoweringInfo().isTypeLegal(VT))
- return SDValue();
-
- APInt SplatBits, SplatUndef;
- unsigned SplatBitSize;
- bool HasAnyUndefs;
- if (BVN && Subtarget->hasNEON() &&
- BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs)) {
- if (SplatBitSize <= 64) {
- EVT VorrVT;
- SDValue Val = isNEONModifiedImm(SplatBits.getZExtValue(),
- SplatUndef.getZExtValue(), SplatBitSize,
- DAG, dl, VorrVT, VT.is128BitVector(),
- OtherModImm);
- if (Val.getNode()) {
- SDValue Input =
- DAG.getNode(ISD::BITCAST, dl, VorrVT, N->getOperand(0));
- SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, Input, Val);
- return DAG.getNode(ISD::BITCAST, dl, VT, Vorr);
- }
- }
- }
-
- if (!Subtarget->isThumb1Only()) {
- // fold (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
- if (SDValue Result = combineSelectAndUseCommutative(N, false, DCI))
- return Result;
- if (SDValue Result = PerformORCombineToSMULWBT(N, DCI, Subtarget))
- return Result;
- }
-
- // The code below optimizes (or (and X, Y), Z).
- // The AND operand needs to have a single user to make these optimizations
- // profitable.
- SDValue N0 = N->getOperand(0);
- if (N0.getOpcode() != ISD::AND || !N0.hasOneUse())
- return SDValue();
- SDValue N1 = N->getOperand(1);
-
- // (or (and B, A), (and C, ~A)) => (VBSL A, B, C) when A is a constant.
- if (Subtarget->hasNEON() && N1.getOpcode() == ISD::AND && VT.isVector() &&
- DAG.getTargetLoweringInfo().isTypeLegal(VT)) {
- APInt SplatUndef;
- unsigned SplatBitSize;
- bool HasAnyUndefs;
-
- APInt SplatBits0, SplatBits1;
- BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(1));
- BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(1));
- // Ensure that the second operand of both ands are constants
- if (BVN0 && BVN0->isConstantSplat(SplatBits0, SplatUndef, SplatBitSize,
- HasAnyUndefs) && !HasAnyUndefs) {
- if (BVN1 && BVN1->isConstantSplat(SplatBits1, SplatUndef, SplatBitSize,
- HasAnyUndefs) && !HasAnyUndefs) {
- // Ensure that the bit width of the constants are the same and that
- // the splat arguments are logical inverses as per the pattern we
- // are trying to simplify.
- if (SplatBits0.getBitWidth() == SplatBits1.getBitWidth() &&
- SplatBits0 == ~SplatBits1) {
- // Canonicalize the vector type to make instruction selection
- // simpler.
- EVT CanonicalVT = VT.is128BitVector() ? MVT::v4i32 : MVT::v2i32;
- SDValue Result = DAG.getNode(ARMISD::VBSL, dl, CanonicalVT,
- N0->getOperand(1),
- N0->getOperand(0),
- N1->getOperand(0));
- return DAG.getNode(ISD::BITCAST, dl, VT, Result);
- }
- }
- }
- }
-
- // Try to use the ARM/Thumb2 BFI (bitfield insert) instruction when
- // reasonable.
+static SDValue PerformBFICombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
----------------
This should be called something else as there's already a PerformBFICombine and the name here violates the rule that the argument to PerformXCombine is a node of type X (here it's an OR of an AND). Probably PerformORCombineToBFI.
https://reviews.llvm.org/D38084
More information about the llvm-commits
mailing list