Skip to content

Commit 786fff8

Browse files
committed
[AArch64] Eliminate Common SUBS by Reassociating Non-Constants
Commit 1eed469 added logic to reassociate a (add (add x y) -c) operand to a CSEL instruction with a comparison involving x and c (or a similar constant) in order to obtain a common (SUBS x c) instruction. This commit extends this logic to non-constants. In this way, we also reassociate a (sub (add x y) z) operand of a CSEL instruction to (add (sub x z) y) if the CSEL compares x and z, for example. Alive proof: https://alive2.llvm.org/ce/z/SEVpRm
1 parent 2863894 commit 786fff8

File tree

2 files changed

+102
-85
lines changed

2 files changed

+102
-85
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24899,16 +24899,36 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2489924899
SDValue SubsNode = N->getOperand(3);
2490024900
if (SubsNode.getOpcode() != AArch64ISD::SUBS || !SubsNode.hasOneUse())
2490124901
return SDValue();
24902-
auto *CmpOpConst = dyn_cast<ConstantSDNode>(SubsNode.getOperand(1));
24903-
if (!CmpOpConst)
24904-
return SDValue();
2490524902

24903+
SDValue CmpOpToMatch = SubsNode.getOperand(1);
2490624904
SDValue CmpOpOther = SubsNode.getOperand(0);
2490724905
EVT VT = N->getValueType(0);
2490824906

24907+
unsigned ExpectedOpcode;
24908+
std::function<bool(SDValue)> CheckOp;
24909+
std::function<SDValue()> BuildSubsOp;
24910+
auto *CmpOpConst = dyn_cast<ConstantSDNode>(CmpOpToMatch);
24911+
if (CmpOpConst) {
24912+
ExpectedOpcode = ISD::ADD;
24913+
CheckOp = [&](SDValue Op) {
24914+
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op);
24915+
return AddOpConst &&
24916+
AddOpConst->getAPIntValue() == -CmpOpConst->getAPIntValue();
24917+
};
24918+
BuildSubsOp = [&] {
24919+
return DAG.getConstant(CmpOpConst->getAPIntValue(), SDLoc(CmpOpConst),
24920+
CmpOpConst->getValueType(0));
24921+
};
24922+
} else {
24923+
ExpectedOpcode = ISD::SUB;
24924+
CheckOp = [&](SDValue Op) { return Op == CmpOpToMatch; };
24925+
BuildSubsOp = [&] { return CmpOpToMatch; };
24926+
}
24927+
2490924928
// Get the operand that can be reassociated with the SUBS instruction.
24910-
auto GetReassociationOp = [&](SDValue Op, APInt ExpectedConst) {
24911-
if (Op.getOpcode() != ISD::ADD)
24929+
auto GetReassociationOp = [&](SDValue Op,
24930+
std::function<bool(SDValue)> CheckOp) {
24931+
if (Op.getOpcode() != ExpectedOpcode)
2491224932
return SDValue();
2491324933
if (Op.getOperand(0).getOpcode() != ISD::ADD ||
2491424934
!Op.getOperand(0).hasOneUse())
@@ -24919,24 +24939,23 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2491924939
std::swap(X, Y);
2492024940
if (X != CmpOpOther)
2492124941
return SDValue();
24922-
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op.getOperand(1));
24923-
if (!AddOpConst || AddOpConst->getAPIntValue() != ExpectedConst)
24942+
if (!CheckOp(Op.getOperand(1)))
2492424943
return SDValue();
2492524944
return Y;
2492624945
};
2492724946

2492824947
// Try the reassociation using the given constant and condition code.
24929-
auto Fold = [&](APInt NewCmpConst, AArch64CC::CondCode NewCC) {
24930-
APInt ExpectedConst = -NewCmpConst;
24931-
SDValue TReassocOp = GetReassociationOp(N->getOperand(0), ExpectedConst);
24932-
SDValue FReassocOp = GetReassociationOp(N->getOperand(1), ExpectedConst);
24948+
auto Fold = [&](AArch64CC::CondCode NewCC,
24949+
std::function<bool(SDValue)> CheckOp,
24950+
std::function<SDValue()> BuildSubsOp) {
24951+
SDValue TReassocOp = GetReassociationOp(N->getOperand(0), CheckOp);
24952+
SDValue FReassocOp = GetReassociationOp(N->getOperand(1), CheckOp);
2493324953
if (!TReassocOp && !FReassocOp)
2493424954
return SDValue();
2493524955

24936-
SDValue NewCmp = DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
24937-
DAG.getVTList(VT, MVT_CC), CmpOpOther,
24938-
DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
24939-
CmpOpConst->getValueType(0)));
24956+
SDValue NewCmp =
24957+
DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
24958+
DAG.getVTList(VT, MVT_CC), CmpOpOther, BuildSubsOp());
2494024959

2494124960
auto Reassociate = [&](SDValue ReassocOp, unsigned OpNum) {
2494224961
if (!ReassocOp)
@@ -24958,9 +24977,19 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2495824977

2495924978
// First, try to eliminate the compare instruction by searching for a
2496024979
// subtraction with the same constant.
24961-
if (SDValue R = Fold(CmpOpConst->getAPIntValue(), CC))
24980+
if (SDValue R = Fold(CC, CheckOp, BuildSubsOp))
2496224981
return R;
2496324982

24983+
if (!CmpOpConst) {
24984+
// Try again with the operands of the SUBS instruction and the condition
24985+
// swapped. Due to canonicalization, this only helps for non-constant
24986+
// operands of the SUBS instruction.
24987+
std::swap(CmpOpToMatch, CmpOpOther);
24988+
if (SDValue R = Fold(getSwappedCondition(CC), CheckOp, BuildSubsOp))
24989+
return R;
24990+
return SDValue();
24991+
}
24992+
2496424993
if ((CC == AArch64CC::EQ || CC == AArch64CC::NE) && !CmpOpConst->isZero())
2496524994
return SDValue();
2496624995

@@ -24972,7 +25001,15 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2497225001
// them here but check for them nevertheless to be on the safe side.
2497325002
auto CheckedFold = [&](bool Check, APInt NewCmpConst,
2497425003
AArch64CC::CondCode NewCC) {
24975-
return Check ? Fold(NewCmpConst, NewCC) : SDValue();
25004+
auto CheckOp = [=](SDValue Op) {
25005+
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op);
25006+
return AddOpConst && AddOpConst->getAPIntValue() == -NewCmpConst;
25007+
};
25008+
auto BuildSubsOp = [&, CmpOpConst] {
25009+
return DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
25010+
CmpOpConst->getValueType(0));
25011+
};
25012+
return Check ? Fold(NewCC, CheckOp, BuildSubsOp) : SDValue();
2497625013
};
2497725014
switch (CC) {
2497825015
case AArch64CC::EQ:

llvm/test/CodeGen/AArch64/csel-cmp-cse.ll

Lines changed: 48 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,8 @@ define i32 @test_eq0_multi_use_sub_i32(i32 %x0, i32 %x1) {
338338
define i32 @test_eq_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
339339
; CHECK-LABEL: test_eq_nonconst_sub_add_i32:
340340
; CHECK: // %bb.0:
341-
; CHECK-NEXT: add w8, w0, w1
342-
; CHECK-NEXT: cmp w1, w2
343-
; CHECK-NEXT: sub w8, w8, w2
341+
; CHECK-NEXT: subs w8, w1, w2
342+
; CHECK-NEXT: add w8, w8, w0
344343
; CHECK-NEXT: csel w0, wzr, w8, eq
345344
; CHECK-NEXT: ret
346345
%cmp = icmp eq i32 %x1, %x2
@@ -353,9 +352,8 @@ define i32 @test_eq_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
353352
define i32 @test_ne_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
354353
; CHECK-LABEL: test_ne_nonconst_sub_add_i32:
355354
; CHECK: // %bb.0:
356-
; CHECK-NEXT: add w8, w0, w1
357-
; CHECK-NEXT: cmp w1, w2
358-
; CHECK-NEXT: sub w8, w8, w2
355+
; CHECK-NEXT: subs w8, w1, w2
356+
; CHECK-NEXT: add w8, w8, w0
359357
; CHECK-NEXT: csel w0, wzr, w8, ne
360358
; CHECK-NEXT: ret
361359
%cmp = icmp ne i32 %x1, %x2
@@ -368,9 +366,8 @@ define i32 @test_ne_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
368366
define i32 @test_ult_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
369367
; CHECK-LABEL: test_ult_nonconst_i32:
370368
; CHECK: // %bb.0:
371-
; CHECK-NEXT: add w8, w0, w1
372-
; CHECK-NEXT: cmp w1, w2
373-
; CHECK-NEXT: sub w8, w8, w2
369+
; CHECK-NEXT: subs w8, w1, w2
370+
; CHECK-NEXT: add w8, w8, w0
374371
; CHECK-NEXT: csel w0, wzr, w8, lo
375372
; CHECK-NEXT: ret
376373
%cmp = icmp ult i32 %x1, %x2
@@ -383,9 +380,8 @@ define i32 @test_ult_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
383380
define i32 @test_ule_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
384381
; CHECK-LABEL: test_ule_nonconst_i32:
385382
; CHECK: // %bb.0:
386-
; CHECK-NEXT: add w8, w0, w1
387-
; CHECK-NEXT: cmp w1, w2
388-
; CHECK-NEXT: sub w8, w8, w2
383+
; CHECK-NEXT: subs w8, w1, w2
384+
; CHECK-NEXT: add w8, w8, w0
389385
; CHECK-NEXT: csel w0, wzr, w8, ls
390386
; CHECK-NEXT: ret
391387
%cmp = icmp ule i32 %x1, %x2
@@ -398,9 +394,8 @@ define i32 @test_ule_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
398394
define i32 @test_ugt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
399395
; CHECK-LABEL: test_ugt_nonconst_i32:
400396
; CHECK: // %bb.0:
401-
; CHECK-NEXT: add w8, w0, w1
402-
; CHECK-NEXT: cmp w1, w2
403-
; CHECK-NEXT: sub w8, w8, w2
397+
; CHECK-NEXT: subs w8, w1, w2
398+
; CHECK-NEXT: add w8, w8, w0
404399
; CHECK-NEXT: csel w0, wzr, w8, hi
405400
; CHECK-NEXT: ret
406401
%cmp = icmp ugt i32 %x1, %x2
@@ -413,9 +408,8 @@ define i32 @test_ugt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
413408
define i32 @test_uge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
414409
; CHECK-LABEL: test_uge_nonconst_i32:
415410
; CHECK: // %bb.0:
416-
; CHECK-NEXT: add w8, w0, w1
417-
; CHECK-NEXT: cmp w1, w2
418-
; CHECK-NEXT: sub w8, w8, w2
411+
; CHECK-NEXT: subs w8, w1, w2
412+
; CHECK-NEXT: add w8, w8, w0
419413
; CHECK-NEXT: csel w0, wzr, w8, hs
420414
; CHECK-NEXT: ret
421415
%cmp = icmp uge i32 %x1, %x2
@@ -428,9 +422,8 @@ define i32 @test_uge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
428422
define i32 @test_slt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
429423
; CHECK-LABEL: test_slt_nonconst_i32:
430424
; CHECK: // %bb.0:
431-
; CHECK-NEXT: add w8, w0, w1
432-
; CHECK-NEXT: cmp w1, w2
433-
; CHECK-NEXT: sub w8, w8, w2
425+
; CHECK-NEXT: subs w8, w1, w2
426+
; CHECK-NEXT: add w8, w8, w0
434427
; CHECK-NEXT: csel w0, wzr, w8, lt
435428
; CHECK-NEXT: ret
436429
%cmp = icmp slt i32 %x1, %x2
@@ -443,9 +436,8 @@ define i32 @test_slt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
443436
define i32 @test_sle_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
444437
; CHECK-LABEL: test_sle_nonconst_i32:
445438
; CHECK: // %bb.0:
446-
; CHECK-NEXT: add w8, w0, w1
447-
; CHECK-NEXT: cmp w1, w2
448-
; CHECK-NEXT: sub w8, w8, w2
439+
; CHECK-NEXT: subs w8, w1, w2
440+
; CHECK-NEXT: add w8, w8, w0
449441
; CHECK-NEXT: csel w0, wzr, w8, le
450442
; CHECK-NEXT: ret
451443
%cmp = icmp sle i32 %x1, %x2
@@ -458,9 +450,8 @@ define i32 @test_sle_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
458450
define i32 @test_sgt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
459451
; CHECK-LABEL: test_sgt_nonconst_i32:
460452
; CHECK: // %bb.0:
461-
; CHECK-NEXT: add w8, w0, w1
462-
; CHECK-NEXT: cmp w1, w2
463-
; CHECK-NEXT: sub w8, w8, w2
453+
; CHECK-NEXT: subs w8, w1, w2
454+
; CHECK-NEXT: add w8, w8, w0
464455
; CHECK-NEXT: csel w0, wzr, w8, gt
465456
; CHECK-NEXT: ret
466457
%cmp = icmp sgt i32 %x1, %x2
@@ -473,9 +464,8 @@ define i32 @test_sgt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
473464
define i32 @test_sge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
474465
; CHECK-LABEL: test_sge_nonconst_i32:
475466
; CHECK: // %bb.0:
476-
; CHECK-NEXT: add w8, w0, w1
477-
; CHECK-NEXT: cmp w1, w2
478-
; CHECK-NEXT: sub w8, w8, w2
467+
; CHECK-NEXT: subs w8, w1, w2
468+
; CHECK-NEXT: add w8, w8, w0
479469
; CHECK-NEXT: csel w0, wzr, w8, ge
480470
; CHECK-NEXT: ret
481471
%cmp = icmp sge i32 %x1, %x2
@@ -488,9 +478,8 @@ define i32 @test_sge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
488478
define i32 @test_eq_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
489479
; CHECK-LABEL: test_eq_nonconst_sub_add_comm_i32:
490480
; CHECK: // %bb.0:
491-
; CHECK-NEXT: add w8, w0, w1
492-
; CHECK-NEXT: cmp w2, w1
493-
; CHECK-NEXT: sub w8, w8, w2
481+
; CHECK-NEXT: subs w8, w1, w2
482+
; CHECK-NEXT: add w8, w8, w0
494483
; CHECK-NEXT: csel w0, wzr, w8, eq
495484
; CHECK-NEXT: ret
496485
%cmp = icmp eq i32 %x2, %x1
@@ -503,9 +492,8 @@ define i32 @test_eq_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
503492
define i32 @test_ne_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
504493
; CHECK-LABEL: test_ne_nonconst_sub_add_comm_i32:
505494
; CHECK: // %bb.0:
506-
; CHECK-NEXT: add w8, w0, w1
507-
; CHECK-NEXT: cmp w2, w1
508-
; CHECK-NEXT: sub w8, w8, w2
495+
; CHECK-NEXT: subs w8, w1, w2
496+
; CHECK-NEXT: add w8, w8, w0
509497
; CHECK-NEXT: csel w0, wzr, w8, ne
510498
; CHECK-NEXT: ret
511499
%cmp = icmp ne i32 %x2, %x1
@@ -518,10 +506,9 @@ define i32 @test_ne_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
518506
define i32 @test_ult_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
519507
; CHECK-LABEL: test_ult_nonconst_sub_add_comm_i32:
520508
; CHECK: // %bb.0:
521-
; CHECK-NEXT: add w8, w0, w1
522-
; CHECK-NEXT: cmp w2, w1
523-
; CHECK-NEXT: sub w8, w8, w2
524-
; CHECK-NEXT: csel w0, wzr, w8, lo
509+
; CHECK-NEXT: subs w8, w1, w2
510+
; CHECK-NEXT: add w8, w8, w0
511+
; CHECK-NEXT: csel w0, wzr, w8, hi
525512
; CHECK-NEXT: ret
526513
%cmp = icmp ult i32 %x2, %x1
527514
%add = add nuw i32 %x0, %x1
@@ -533,10 +520,9 @@ define i32 @test_ult_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
533520
define i32 @test_ule_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
534521
; CHECK-LABEL: test_ule_nonconst_sub_add_comm_i32:
535522
; CHECK: // %bb.0:
536-
; CHECK-NEXT: add w8, w0, w1
537-
; CHECK-NEXT: cmp w2, w1
538-
; CHECK-NEXT: sub w8, w8, w2
539-
; CHECK-NEXT: csel w0, wzr, w8, ls
523+
; CHECK-NEXT: subs w8, w1, w2
524+
; CHECK-NEXT: add w8, w8, w0
525+
; CHECK-NEXT: csel w0, wzr, w8, hs
540526
; CHECK-NEXT: ret
541527
%cmp = icmp ule i32 %x2, %x1
542528
%add = add nuw i32 %x0, %x1
@@ -548,10 +534,9 @@ define i32 @test_ule_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
548534
define i32 @test_ugt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
549535
; CHECK-LABEL: test_ugt_nonconst_sub_add_comm_i32:
550536
; CHECK: // %bb.0:
551-
; CHECK-NEXT: add w8, w0, w1
552-
; CHECK-NEXT: cmp w2, w1
553-
; CHECK-NEXT: sub w8, w8, w2
554-
; CHECK-NEXT: csel w0, wzr, w8, hi
537+
; CHECK-NEXT: subs w8, w1, w2
538+
; CHECK-NEXT: add w8, w8, w0
539+
; CHECK-NEXT: csel w0, wzr, w8, lo
555540
; CHECK-NEXT: ret
556541
%cmp = icmp ugt i32 %x2, %x1
557542
%add = add nuw i32 %x0, %x1
@@ -563,10 +548,9 @@ define i32 @test_ugt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
563548
define i32 @test_uge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
564549
; CHECK-LABEL: test_uge_nonconst_sub_add_comm_i32:
565550
; CHECK: // %bb.0:
566-
; CHECK-NEXT: add w8, w0, w1
567-
; CHECK-NEXT: cmp w2, w1
568-
; CHECK-NEXT: sub w8, w8, w2
569-
; CHECK-NEXT: csel w0, wzr, w8, hs
551+
; CHECK-NEXT: subs w8, w1, w2
552+
; CHECK-NEXT: add w8, w8, w0
553+
; CHECK-NEXT: csel w0, wzr, w8, ls
570554
; CHECK-NEXT: ret
571555
%cmp = icmp uge i32 %x2, %x1
572556
%add = add nuw i32 %x0, %x1
@@ -578,10 +562,9 @@ define i32 @test_uge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
578562
define i32 @test_slt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
579563
; CHECK-LABEL: test_slt_nonconst_sub_add_comm_i32:
580564
; CHECK: // %bb.0:
581-
; CHECK-NEXT: add w8, w0, w1
582-
; CHECK-NEXT: cmp w2, w1
583-
; CHECK-NEXT: sub w8, w8, w2
584-
; CHECK-NEXT: csel w0, wzr, w8, lt
565+
; CHECK-NEXT: subs w8, w1, w2
566+
; CHECK-NEXT: add w8, w8, w0
567+
; CHECK-NEXT: csel w0, wzr, w8, gt
585568
; CHECK-NEXT: ret
586569
%cmp = icmp slt i32 %x2, %x1
587570
%add = add nuw i32 %x0, %x1
@@ -593,10 +576,9 @@ define i32 @test_slt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
593576
define i32 @test_sle_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
594577
; CHECK-LABEL: test_sle_nonconst_sub_add_comm_i32:
595578
; CHECK: // %bb.0:
596-
; CHECK-NEXT: add w8, w0, w1
597-
; CHECK-NEXT: cmp w2, w1
598-
; CHECK-NEXT: sub w8, w8, w2
599-
; CHECK-NEXT: csel w0, wzr, w8, le
579+
; CHECK-NEXT: subs w8, w1, w2
580+
; CHECK-NEXT: add w8, w8, w0
581+
; CHECK-NEXT: csel w0, wzr, w8, ge
600582
; CHECK-NEXT: ret
601583
%cmp = icmp sle i32 %x2, %x1
602584
%add = add nuw i32 %x0, %x1
@@ -608,10 +590,9 @@ define i32 @test_sle_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
608590
define i32 @test_sgt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
609591
; CHECK-LABEL: test_sgt_nonconst_sub_add_comm_i32:
610592
; CHECK: // %bb.0:
611-
; CHECK-NEXT: add w8, w0, w1
612-
; CHECK-NEXT: cmp w2, w1
613-
; CHECK-NEXT: sub w8, w8, w2
614-
; CHECK-NEXT: csel w0, wzr, w8, gt
593+
; CHECK-NEXT: subs w8, w1, w2
594+
; CHECK-NEXT: add w8, w8, w0
595+
; CHECK-NEXT: csel w0, wzr, w8, lt
615596
; CHECK-NEXT: ret
616597
%cmp = icmp sgt i32 %x2, %x1
617598
%add = add nuw i32 %x0, %x1
@@ -623,10 +604,9 @@ define i32 @test_sgt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
623604
define i32 @test_sge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
624605
; CHECK-LABEL: test_sge_nonconst_sub_add_comm_i32:
625606
; CHECK: // %bb.0:
626-
; CHECK-NEXT: add w8, w0, w1
627-
; CHECK-NEXT: cmp w2, w1
628-
; CHECK-NEXT: sub w8, w8, w2
629-
; CHECK-NEXT: csel w0, wzr, w8, ge
607+
; CHECK-NEXT: subs w8, w1, w2
608+
; CHECK-NEXT: add w8, w8, w0
609+
; CHECK-NEXT: csel w0, wzr, w8, le
630610
; CHECK-NEXT: ret
631611
%cmp = icmp sge i32 %x2, %x1
632612
%add = add nuw i32 %x0, %x1

0 commit comments

Comments
 (0)