@@ -1529,7 +1529,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
15291529 setOperationAction(ISD::VECREDUCE_AND, VT, Custom);
15301530 setOperationAction(ISD::VECREDUCE_OR, VT, Custom);
15311531 setOperationAction(ISD::VECREDUCE_XOR, VT, Custom);
1532- setOperationAction(ISD::OR, VT, Custom);
15331532
15341533 setOperationAction(ISD::SELECT_CC, VT, Expand);
15351534 setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Custom);
@@ -13940,128 +13939,8 @@ static SDValue tryLowerToSLI(SDNode *N, SelectionDAG &DAG) {
1394013939 return ResultSLI;
1394113940}
1394213941
13943- /// Try to lower the construction of a pointer alias mask to a WHILEWR.
13944- /// The mask's enabled lanes represent the elements that will not overlap across
13945- /// one loop iteration. This tries to match:
13946- /// or (splat (setcc_lt (sub ptrA, ptrB), -(element_size - 1))),
13947- /// (get_active_lane_mask 0, (div (sub ptrA, ptrB), element_size))
13948- SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
13949- const AArch64Subtarget &Subtarget) {
13950- if (!Subtarget.hasSVE2())
13951- return SDValue();
13952- SDValue LaneMask = Op.getOperand(0);
13953- SDValue Splat = Op.getOperand(1);
13954-
13955- if (Splat.getOpcode() != ISD::SPLAT_VECTOR)
13956- std::swap(LaneMask, Splat);
13957-
13958- if (LaneMask.getOpcode() != ISD::INTRINSIC_WO_CHAIN ||
13959- LaneMask.getConstantOperandVal(0) != Intrinsic::get_active_lane_mask ||
13960- Splat.getOpcode() != ISD::SPLAT_VECTOR)
13961- return SDValue();
13962-
13963- SDValue Cmp = Splat.getOperand(0);
13964- if (Cmp.getOpcode() != ISD::SETCC)
13965- return SDValue();
13966-
13967- CondCodeSDNode *Cond = cast<CondCodeSDNode>(Cmp.getOperand(2));
13968-
13969- auto ComparatorConst = dyn_cast<ConstantSDNode>(Cmp.getOperand(1));
13970- if (!ComparatorConst || ComparatorConst->getSExtValue() > 0 ||
13971- Cond->get() != ISD::CondCode::SETLT)
13972- return SDValue();
13973- unsigned CompValue = std::abs(ComparatorConst->getSExtValue());
13974- unsigned EltSize = CompValue + 1;
13975- if (!isPowerOf2_64(EltSize) || EltSize > 8)
13976- return SDValue();
13977-
13978- SDValue Diff = Cmp.getOperand(0);
13979- if (Diff.getOpcode() != ISD::SUB || Diff.getValueType() != MVT::i64)
13980- return SDValue();
13981-
13982- if (!isNullConstant(LaneMask.getOperand(1)) ||
13983- (EltSize != 1 && LaneMask.getOperand(2).getOpcode() != ISD::SRA))
13984- return SDValue();
13985-
13986- // The number of elements that alias is calculated by dividing the positive
13987- // difference between the pointers by the element size. An alias mask for i8
13988- // elements omits the division because it would just divide by 1
13989- if (EltSize > 1) {
13990- SDValue DiffDiv = LaneMask.getOperand(2);
13991- auto DiffDivConst = dyn_cast<ConstantSDNode>(DiffDiv.getOperand(1));
13992- if (!DiffDivConst || DiffDivConst->getZExtValue() != Log2_64(EltSize))
13993- return SDValue();
13994- if (EltSize > 2) {
13995- // When masking i32 or i64 elements, the positive value of the
13996- // possibly-negative difference comes from a select of the difference if
13997- // it's positive, otherwise the difference plus the element size if it's
13998- // negative: pos_diff = diff < 0 ? (diff + 7) : diff
13999- SDValue Select = DiffDiv.getOperand(0);
14000- // Make sure the difference is being compared by the select
14001- if (Select.getOpcode() != ISD::SELECT_CC || Select.getOperand(3) != Diff)
14002- return SDValue();
14003- // Make sure it's checking if the difference is less than 0
14004- if (!isNullConstant(Select.getOperand(1)) ||
14005- cast<CondCodeSDNode>(Select.getOperand(4))->get() !=
14006- ISD::CondCode::SETLT)
14007- return SDValue();
14008- // An add creates a positive value from the negative difference
14009- SDValue Add = Select.getOperand(2);
14010- if (Add.getOpcode() != ISD::ADD || Add.getOperand(0) != Diff)
14011- return SDValue();
14012- if (auto *AddConst = dyn_cast<ConstantSDNode>(Add.getOperand(1));
14013- !AddConst || AddConst->getZExtValue() != EltSize - 1)
14014- return SDValue();
14015- } else {
14016- // When masking i16 elements, this positive value comes from adding the
14017- // difference's sign bit to the difference itself. This is equivalent to
14018- // the 32 bit and 64 bit case: pos_diff = diff + sign_bit (diff)
14019- SDValue Add = DiffDiv.getOperand(0);
14020- if (Add.getOpcode() != ISD::ADD || Add.getOperand(0) != Diff)
14021- return SDValue();
14022- // A logical right shift by 63 extracts the sign bit from the difference
14023- SDValue Shift = Add.getOperand(1);
14024- if (Shift.getOpcode() != ISD::SRL || Shift.getOperand(0) != Diff)
14025- return SDValue();
14026- if (auto *ShiftConst = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
14027- !ShiftConst || ShiftConst->getZExtValue() != 63)
14028- return SDValue();
14029- }
14030- } else if (LaneMask.getOperand(2) != Diff)
14031- return SDValue();
14032-
14033- SDValue StorePtr = Diff.getOperand(0);
14034- SDValue ReadPtr = Diff.getOperand(1);
14035-
14036- unsigned IntrinsicID = 0;
14037- switch (EltSize) {
14038- case 1:
14039- IntrinsicID = Intrinsic::aarch64_sve_whilewr_b;
14040- break;
14041- case 2:
14042- IntrinsicID = Intrinsic::aarch64_sve_whilewr_h;
14043- break;
14044- case 4:
14045- IntrinsicID = Intrinsic::aarch64_sve_whilewr_s;
14046- break;
14047- case 8:
14048- IntrinsicID = Intrinsic::aarch64_sve_whilewr_d;
14049- break;
14050- default:
14051- return SDValue();
14052- }
14053- SDLoc DL(Op);
14054- SDValue ID = DAG.getConstant(IntrinsicID, DL, MVT::i32);
14055- return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, Op.getValueType(), ID,
14056- StorePtr, ReadPtr);
14057- }
14058-
1405913942SDValue AArch64TargetLowering::LowerVectorOR(SDValue Op,
1406013943 SelectionDAG &DAG) const {
14061- if (SDValue SV =
14062- tryWhileWRFromOR(Op, DAG, DAG.getSubtarget<AArch64Subtarget>()))
14063- return SV;
14064-
1406513944 if (useSVEForFixedLengthVectorVT(Op.getValueType(),
1406613945 !Subtarget->isNeonAvailable()))
1406713946 return LowerToScalableOp(Op, DAG);
0 commit comments