@@ -14742,6 +14742,106 @@ static SDValue tryLowerToSLI(SDNode *N, SelectionDAG &DAG) {
14742
14742
return ResultSLI;
14743
14743
}
14744
14744
14745
+ static SDValue tryCombineToBSL(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
14746
+ const AArch64TargetLowering &TLI) {
14747
+ EVT VT = N->getValueType(0);
14748
+ SelectionDAG &DAG = DCI.DAG;
14749
+ SDLoc DL(N);
14750
+ const auto &Subtarget = DAG.getSubtarget<AArch64Subtarget>();
14751
+
14752
+ if (!VT.isVector())
14753
+ return SDValue();
14754
+
14755
+ if (VT.isScalableVector() && !Subtarget.hasSVE2())
14756
+ return SDValue();
14757
+
14758
+ if (VT.isFixedLengthVector() &&
14759
+ (!Subtarget.isNeonAvailable() || TLI.useSVEForFixedLengthVectorVT(VT)))
14760
+ return SDValue();
14761
+
14762
+ SDValue N0 = N->getOperand(0);
14763
+ if (N0.getOpcode() != ISD::AND)
14764
+ return SDValue();
14765
+
14766
+ SDValue N1 = N->getOperand(1);
14767
+ if (N1.getOpcode() != ISD::AND)
14768
+ return SDValue();
14769
+
14770
+ // InstCombine does (not (neg a)) => (add a -1).
14771
+ // Try: (or (and (neg a) b) (and (add a -1) c)) => (bsl (neg a) b c)
14772
+ // Loop over all combinations of AND operands.
14773
+ for (int i = 1; i >= 0; --i) {
14774
+ for (int j = 1; j >= 0; --j) {
14775
+ SDValue O0 = N0->getOperand(i);
14776
+ SDValue O1 = N1->getOperand(j);
14777
+ SDValue Sub, Add, SubSibling, AddSibling;
14778
+
14779
+ // Find a SUB and an ADD operand, one from each AND.
14780
+ if (O0.getOpcode() == ISD::SUB && O1.getOpcode() == ISD::ADD) {
14781
+ Sub = O0;
14782
+ Add = O1;
14783
+ SubSibling = N0->getOperand(1 - i);
14784
+ AddSibling = N1->getOperand(1 - j);
14785
+ } else if (O0.getOpcode() == ISD::ADD && O1.getOpcode() == ISD::SUB) {
14786
+ Add = O0;
14787
+ Sub = O1;
14788
+ AddSibling = N0->getOperand(1 - i);
14789
+ SubSibling = N1->getOperand(1 - j);
14790
+ } else
14791
+ continue;
14792
+
14793
+ if (!ISD::isConstantSplatVectorAllZeros(Sub.getOperand(0).getNode()))
14794
+ continue;
14795
+
14796
+ // Constant ones is always righthand operand of the Add.
14797
+ if (!ISD::isConstantSplatVectorAllOnes(Add.getOperand(1).getNode()))
14798
+ continue;
14799
+
14800
+ if (Sub.getOperand(1) != Add.getOperand(0))
14801
+ continue;
14802
+
14803
+ return DAG.getNode(AArch64ISD::BSP, DL, VT, Sub, SubSibling, AddSibling);
14804
+ }
14805
+ }
14806
+
14807
+ // (or (and a b) (and (not a) c)) => (bsl a b c)
14808
+ // We only have to look for constant vectors here since the general, variable
14809
+ // case can be handled in TableGen.
14810
+ unsigned Bits = VT.getScalarSizeInBits();
14811
+ uint64_t BitMask = Bits == 64 ? -1ULL : ((1ULL << Bits) - 1);
14812
+ for (int i = 1; i >= 0; --i)
14813
+ for (int j = 1; j >= 0; --j) {
14814
+ APInt Val1, Val2;
14815
+
14816
+ if (ISD::isConstantSplatVector(N0->getOperand(i).getNode(), Val1) &&
14817
+ ISD::isConstantSplatVector(N1->getOperand(j).getNode(), Val2) &&
14818
+ (BitMask & ~Val1.getZExtValue()) == Val2.getZExtValue()) {
14819
+ return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
14820
+ N0->getOperand(1 - i), N1->getOperand(1 - j));
14821
+ }
14822
+ BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(i));
14823
+ BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(j));
14824
+ if (!BVN0 || !BVN1)
14825
+ continue;
14826
+
14827
+ bool FoundMatch = true;
14828
+ for (unsigned k = 0; k < VT.getVectorNumElements(); ++k) {
14829
+ ConstantSDNode *CN0 = dyn_cast<ConstantSDNode>(BVN0->getOperand(k));
14830
+ ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(BVN1->getOperand(k));
14831
+ if (!CN0 || !CN1 ||
14832
+ CN0->getZExtValue() != (BitMask & ~CN1->getZExtValue())) {
14833
+ FoundMatch = false;
14834
+ break;
14835
+ }
14836
+ }
14837
+ if (FoundMatch)
14838
+ return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
14839
+ N0->getOperand(1 - i), N1->getOperand(1 - j));
14840
+ }
14841
+
14842
+ return SDValue();
14843
+ }
14844
+
14745
14845
SDValue AArch64TargetLowering::LowerVectorOR(SDValue Op,
14746
14846
SelectionDAG &DAG) const {
14747
14847
if (useSVEForFixedLengthVectorVT(Op.getValueType(),
@@ -19419,106 +19519,6 @@ static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
19419
19519
return FixConv;
19420
19520
}
19421
19521
19422
- static SDValue tryCombineToBSL(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
19423
- const AArch64TargetLowering &TLI) {
19424
- EVT VT = N->getValueType(0);
19425
- SelectionDAG &DAG = DCI.DAG;
19426
- SDLoc DL(N);
19427
- const auto &Subtarget = DAG.getSubtarget<AArch64Subtarget>();
19428
-
19429
- if (!VT.isVector())
19430
- return SDValue();
19431
-
19432
- if (VT.isScalableVector() && !Subtarget.hasSVE2())
19433
- return SDValue();
19434
-
19435
- if (VT.isFixedLengthVector() &&
19436
- (!Subtarget.isNeonAvailable() || TLI.useSVEForFixedLengthVectorVT(VT)))
19437
- return SDValue();
19438
-
19439
- SDValue N0 = N->getOperand(0);
19440
- if (N0.getOpcode() != ISD::AND)
19441
- return SDValue();
19442
-
19443
- SDValue N1 = N->getOperand(1);
19444
- if (N1.getOpcode() != ISD::AND)
19445
- return SDValue();
19446
-
19447
- // InstCombine does (not (neg a)) => (add a -1).
19448
- // Try: (or (and (neg a) b) (and (add a -1) c)) => (bsl (neg a) b c)
19449
- // Loop over all combinations of AND operands.
19450
- for (int i = 1; i >= 0; --i) {
19451
- for (int j = 1; j >= 0; --j) {
19452
- SDValue O0 = N0->getOperand(i);
19453
- SDValue O1 = N1->getOperand(j);
19454
- SDValue Sub, Add, SubSibling, AddSibling;
19455
-
19456
- // Find a SUB and an ADD operand, one from each AND.
19457
- if (O0.getOpcode() == ISD::SUB && O1.getOpcode() == ISD::ADD) {
19458
- Sub = O0;
19459
- Add = O1;
19460
- SubSibling = N0->getOperand(1 - i);
19461
- AddSibling = N1->getOperand(1 - j);
19462
- } else if (O0.getOpcode() == ISD::ADD && O1.getOpcode() == ISD::SUB) {
19463
- Add = O0;
19464
- Sub = O1;
19465
- AddSibling = N0->getOperand(1 - i);
19466
- SubSibling = N1->getOperand(1 - j);
19467
- } else
19468
- continue;
19469
-
19470
- if (!ISD::isConstantSplatVectorAllZeros(Sub.getOperand(0).getNode()))
19471
- continue;
19472
-
19473
- // Constant ones is always righthand operand of the Add.
19474
- if (!ISD::isConstantSplatVectorAllOnes(Add.getOperand(1).getNode()))
19475
- continue;
19476
-
19477
- if (Sub.getOperand(1) != Add.getOperand(0))
19478
- continue;
19479
-
19480
- return DAG.getNode(AArch64ISD::BSP, DL, VT, Sub, SubSibling, AddSibling);
19481
- }
19482
- }
19483
-
19484
- // (or (and a b) (and (not a) c)) => (bsl a b c)
19485
- // We only have to look for constant vectors here since the general, variable
19486
- // case can be handled in TableGen.
19487
- unsigned Bits = VT.getScalarSizeInBits();
19488
- uint64_t BitMask = Bits == 64 ? -1ULL : ((1ULL << Bits) - 1);
19489
- for (int i = 1; i >= 0; --i)
19490
- for (int j = 1; j >= 0; --j) {
19491
- APInt Val1, Val2;
19492
-
19493
- if (ISD::isConstantSplatVector(N0->getOperand(i).getNode(), Val1) &&
19494
- ISD::isConstantSplatVector(N1->getOperand(j).getNode(), Val2) &&
19495
- (BitMask & ~Val1.getZExtValue()) == Val2.getZExtValue()) {
19496
- return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
19497
- N0->getOperand(1 - i), N1->getOperand(1 - j));
19498
- }
19499
- BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(i));
19500
- BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(j));
19501
- if (!BVN0 || !BVN1)
19502
- continue;
19503
-
19504
- bool FoundMatch = true;
19505
- for (unsigned k = 0; k < VT.getVectorNumElements(); ++k) {
19506
- ConstantSDNode *CN0 = dyn_cast<ConstantSDNode>(BVN0->getOperand(k));
19507
- ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(BVN1->getOperand(k));
19508
- if (!CN0 || !CN1 ||
19509
- CN0->getZExtValue() != (BitMask & ~CN1->getZExtValue())) {
19510
- FoundMatch = false;
19511
- break;
19512
- }
19513
- }
19514
- if (FoundMatch)
19515
- return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
19516
- N0->getOperand(1 - i), N1->getOperand(1 - j));
19517
- }
19518
-
19519
- return SDValue();
19520
- }
19521
-
19522
19522
// Given a tree of and/or(csel(0, 1, cc0), csel(0, 1, cc1)), we may be able to
19523
19523
// convert to csel(ccmp(.., cc0)), depending on cc1:
19524
19524
0 commit comments