@@ -52388,16 +52388,41 @@ static SDValue combineAddOrSubToADCOrSBB(bool IsSub, const SDLoc &DL, EVT VT,
52388
52388
// Do not flip "e > c", where "c" is a constant, because Cmp instruction
52389
52389
// cannot take an immediate as its first operand.
52390
52390
//
52391
- if (EFLAGS.getOpcode() == X86ISD::SUB && EFLAGS.getNode()->hasOneUse() &&
52392
- EFLAGS.getValueType().isInteger() &&
52393
- !isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
52394
- SDValue NewSub =
52395
- DAG.getNode(X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
52396
- EFLAGS.getOperand(1), EFLAGS.getOperand(0));
52397
- SDValue NewEFLAGS = NewSub.getValue(EFLAGS.getResNo());
52391
+ // If EFLAGS is from a CMP that compares the same operands as the earlier
52392
+ // SUB producing X (i.e. CMP X, Y), we can directly use the carry flag with
52393
+ // SBB/ADC without creating a flipped SUB.
52394
+ if (EFLAGS.getOpcode() == X86ISD::CMP &&
52395
+ EFLAGS.getValueType().isInteger() && X == EFLAGS.getOperand(0)) {
52398
52396
return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL,
52399
52397
DAG.getVTList(VT, MVT::i32), X,
52400
- DAG.getConstant(0, DL, VT), NewEFLAGS);
52398
+ DAG.getConstant(0, DL, VT), EFLAGS);
52399
+ }
52400
+
52401
+ if (EFLAGS.getOpcode() == X86ISD::SUB &&
52402
+ EFLAGS.getValueType().isInteger() &&
52403
+ !isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
52404
+ // Only create NewSub if we know one of the folds will succeed to avoid
52405
+ // introducing a temporary node that may persist and affect one-use checks
52406
+ // below.
52407
+ if (EFLAGS.getNode()->hasOneUse()) {
52408
+ SDValue NewSub = DAG.getNode(
52409
+ X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
52410
+ EFLAGS.getOperand(1), EFLAGS.getOperand(0));
52411
+ SDValue NewEFLAGS = NewSub.getValue(EFLAGS.getResNo());
52412
+ return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL,
52413
+ DAG.getVTList(VT, MVT::i32), X,
52414
+ DAG.getConstant(0, DL, VT), NewEFLAGS);
52415
+ }
52416
+
52417
+ if (IsSub && X == EFLAGS.getValue(0)) {
52418
+ SDValue NewSub = DAG.getNode(
52419
+ X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
52420
+ EFLAGS.getOperand(1), EFLAGS.getOperand(0));
52421
+ SDValue NewEFLAGS = NewSub.getValue(EFLAGS.getResNo());
52422
+ return DAG.getNode(X86ISD::SBB, DL, DAG.getVTList(VT, MVT::i32),
52423
+ EFLAGS.getOperand(0), EFLAGS.getOperand(1),
52424
+ NewEFLAGS);
52425
+ }
52401
52426
}
52402
52427
}
52403
52428
0 commit comments