@@ -12456,127 +12456,27 @@ SDValue DAGCombiner::visitSETCC(SDNode *N) {
12456
12456
12457
12457
ISD::CondCode Cond = cast<CondCodeSDNode>(N->getOperand(2))->get();
12458
12458
EVT VT = N->getValueType(0);
12459
- SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
12460
-
12461
- SDValue Combined = SimplifySetCC(VT, N0, N1, Cond, SDLoc(N), !PreferSetCC);
12462
12459
12463
- if (Combined) {
12464
- // If we prefer to have a setcc, and we don't, we'll try our best to
12465
- // recreate one using rebuildSetCC.
12466
- if (PreferSetCC && Combined.getOpcode() != ISD::SETCC) {
12467
- SDValue NewSetCC = rebuildSetCC(Combined);
12460
+ SDValue Combined = SimplifySetCC(VT, N->getOperand(0), N->getOperand(1), Cond,
12461
+ SDLoc(N), !PreferSetCC);
12468
12462
12469
- // We don't have anything interesting to combine to.
12470
- if (NewSetCC.getNode() == N)
12471
- return SDValue();
12463
+ if (!Combined)
12464
+ return SDValue();
12472
12465
12473
- if (NewSetCC)
12474
- return NewSetCC;
12475
- }
12476
- return Combined;
12477
- }
12466
+ // If we prefer to have a setcc, and we don't, we'll try our best to
12467
+ // recreate one using rebuildSetCC.
12468
+ if (PreferSetCC && Combined.getOpcode() != ISD::SETCC) {
12469
+ SDValue NewSetCC = rebuildSetCC(Combined);
12478
12470
12479
- // Optimize
12480
- // 1) (icmp eq/ne (and X, C0), (shift X, C1))
12481
- // or
12482
- // 2) (icmp eq/ne X, (rotate X, C1))
12483
- // If C0 is a mask or shifted mask and the shift amt (C1) isolates the
12484
- // remaining bits (i.e something like `(x64 & UINT32_MAX) == (x64 >> 32)`)
12485
- // Then:
12486
- // If C1 is a power of 2, then the rotate and shift+and versions are
12487
- // equivilent, so we can interchange them depending on target preference.
12488
- // Otherwise, if we have the shift+and version we can interchange srl/shl
12489
- // which inturn affects the constant C0. We can use this to get better
12490
- // constants again determined by target preference.
12491
- if (Cond == ISD::SETNE || Cond == ISD::SETEQ) {
12492
- auto IsAndWithShift = [](SDValue A, SDValue B) {
12493
- return A.getOpcode() == ISD::AND &&
12494
- (B.getOpcode() == ISD::SRL || B.getOpcode() == ISD::SHL) &&
12495
- A.getOperand(0) == B.getOperand(0);
12496
- };
12497
- auto IsRotateWithOp = [](SDValue A, SDValue B) {
12498
- return (B.getOpcode() == ISD::ROTL || B.getOpcode() == ISD::ROTR) &&
12499
- B.getOperand(0) == A;
12500
- };
12501
- SDValue AndOrOp = SDValue(), ShiftOrRotate = SDValue();
12502
- bool IsRotate = false;
12503
-
12504
- // Find either shift+and or rotate pattern.
12505
- if (IsAndWithShift(N0, N1)) {
12506
- AndOrOp = N0;
12507
- ShiftOrRotate = N1;
12508
- } else if (IsAndWithShift(N1, N0)) {
12509
- AndOrOp = N1;
12510
- ShiftOrRotate = N0;
12511
- } else if (IsRotateWithOp(N0, N1)) {
12512
- IsRotate = true;
12513
- AndOrOp = N0;
12514
- ShiftOrRotate = N1;
12515
- } else if (IsRotateWithOp(N1, N0)) {
12516
- IsRotate = true;
12517
- AndOrOp = N1;
12518
- ShiftOrRotate = N0;
12519
- }
12520
-
12521
- if (AndOrOp && ShiftOrRotate && ShiftOrRotate.hasOneUse() &&
12522
- (IsRotate || AndOrOp.hasOneUse())) {
12523
- EVT OpVT = N0.getValueType();
12524
- // Get constant shift/rotate amount and possibly mask (if its shift+and
12525
- // variant).
12526
- auto GetAPIntValue = [](SDValue Op) -> std::optional<APInt> {
12527
- ConstantSDNode *CNode = isConstOrConstSplat(Op, /*AllowUndefs*/ false,
12528
- /*AllowTrunc*/ false);
12529
- if (CNode == nullptr)
12530
- return std::nullopt;
12531
- return CNode->getAPIntValue();
12532
- };
12533
- std::optional<APInt> AndCMask =
12534
- IsRotate ? std::nullopt : GetAPIntValue(AndOrOp.getOperand(1));
12535
- std::optional<APInt> ShiftCAmt =
12536
- GetAPIntValue(ShiftOrRotate.getOperand(1));
12537
- unsigned NumBits = OpVT.getScalarSizeInBits();
12538
-
12539
- // We found constants.
12540
- if (ShiftCAmt && (IsRotate || AndCMask) && ShiftCAmt->ult(NumBits)) {
12541
- unsigned ShiftOpc = ShiftOrRotate.getOpcode();
12542
- // Check that the constants meet the constraints.
12543
- bool CanTransform =
12544
- IsRotate ||
12545
- (*ShiftCAmt == (~*AndCMask).popcount() && ShiftOpc == ISD::SHL
12546
- ? (~*AndCMask).isMask()
12547
- : AndCMask->isMask());
12548
-
12549
- // See if target prefers another shift/rotate opcode.
12550
- unsigned NewShiftOpc = TLI.preferedOpcodeForCmpEqPiecesOfOperand(
12551
- OpVT, ShiftOpc, ShiftCAmt->isPowerOf2(), *ShiftCAmt, AndCMask);
12552
- // Transform is valid and we have a new preference.
12553
- if (CanTransform && NewShiftOpc != ShiftOpc) {
12554
- SDLoc DL(N);
12555
- SDValue NewShiftOrRotate =
12556
- DAG.getNode(NewShiftOpc, DL, OpVT, ShiftOrRotate.getOperand(0),
12557
- ShiftOrRotate.getOperand(1));
12558
- SDValue NewAndOrOp = SDValue();
12559
-
12560
- if (NewShiftOpc == ISD::SHL || NewShiftOpc == ISD::SRL) {
12561
- APInt NewMask =
12562
- NewShiftOpc == ISD::SHL
12563
- ? APInt::getHighBitsSet(NumBits,
12564
- NumBits - ShiftCAmt->getZExtValue())
12565
- : APInt::getLowBitsSet(NumBits,
12566
- NumBits - ShiftCAmt->getZExtValue());
12567
- NewAndOrOp =
12568
- DAG.getNode(ISD::AND, DL, OpVT, ShiftOrRotate.getOperand(0),
12569
- DAG.getConstant(NewMask, DL, OpVT));
12570
- } else {
12571
- NewAndOrOp = ShiftOrRotate.getOperand(0);
12572
- }
12471
+ // We don't have anything interesting to combine to.
12472
+ if (NewSetCC.getNode() == N)
12473
+ return SDValue();
12573
12474
12574
- return DAG.getSetCC(DL, VT, NewAndOrOp, NewShiftOrRotate, Cond);
12575
- }
12576
- }
12577
- }
12475
+ if (NewSetCC)
12476
+ return NewSetCC;
12578
12477
}
12579
- return SDValue();
12478
+
12479
+ return Combined;
12580
12480
}
12581
12481
12582
12482
SDValue DAGCombiner::visitSETCCCARRY(SDNode *N) {
0 commit comments