Skip to content

Commit f2222fe

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 d40c111 commit f2222fe

File tree

2 files changed

+95
-84
lines changed

2 files changed

+95
-84
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

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

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

24906+
unsigned ExpectedOpcode;
24907+
std::function<bool(SDValue)> CheckOp;
24908+
SDValue SubsOp;
24909+
auto *CmpOpConst = dyn_cast<ConstantSDNode>(CmpOpToMatch);
24910+
if (CmpOpConst) {
24911+
ExpectedOpcode = ISD::ADD;
24912+
CheckOp = [&](SDValue Op) {
24913+
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op);
24914+
return AddOpConst &&
24915+
AddOpConst->getAPIntValue() == -CmpOpConst->getAPIntValue();
24916+
};
24917+
SubsOp = DAG.getConstant(CmpOpConst->getAPIntValue(), SDLoc(CmpOpConst),
24918+
CmpOpConst->getValueType(0));
24919+
} else {
24920+
ExpectedOpcode = ISD::SUB;
24921+
CheckOp = [&](SDValue Op) { return Op == CmpOpToMatch; };
24922+
SubsOp = CmpOpToMatch;
24923+
}
24924+
2490824925
// Get the operand that can be reassociated with the SUBS instruction.
24909-
auto GetReassociationOp = [&](SDValue Op, APInt ExpectedConst) {
24910-
if (Op.getOpcode() != ISD::ADD)
24926+
auto GetReassociationOp = [&](SDValue Op,
24927+
std::function<bool(SDValue)> CheckOp) {
24928+
if (Op.getOpcode() != ExpectedOpcode)
2491124929
return SDValue();
2491224930
if (Op.getOperand(0).getOpcode() != ISD::ADD ||
2491324931
!Op.getOperand(0).hasOneUse())
@@ -24918,24 +24936,21 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2491824936
std::swap(X, Y);
2491924937
if (X != CmpOpOther)
2492024938
return SDValue();
24921-
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op.getOperand(1));
24922-
if (!AddOpConst || AddOpConst->getAPIntValue() != ExpectedConst)
24939+
if (!CheckOp(Op.getOperand(1)))
2492324940
return SDValue();
2492424941
return Y;
2492524942
};
2492624943

2492724944
// Try the reassociation using the given constant and condition code.
24928-
auto Fold = [&](APInt NewCmpConst, AArch64CC::CondCode NewCC) {
24929-
APInt ExpectedConst = -NewCmpConst;
24930-
SDValue TReassocOp = GetReassociationOp(N->getOperand(0), ExpectedConst);
24931-
SDValue FReassocOp = GetReassociationOp(N->getOperand(1), ExpectedConst);
24945+
auto Fold = [&](AArch64CC::CondCode NewCC,
24946+
std::function<bool(SDValue)> CheckOp, SDValue SubsOp) {
24947+
SDValue TReassocOp = GetReassociationOp(N->getOperand(0), CheckOp);
24948+
SDValue FReassocOp = GetReassociationOp(N->getOperand(1), CheckOp);
2493224949
if (!TReassocOp && !FReassocOp)
2493324950
return SDValue();
2493424951

2493524952
SDValue NewCmp = DAG.getNode(AArch64ISD::SUBS, SDLoc(SubsNode),
24936-
DAG.getVTList(VT, MVT_CC), CmpOpOther,
24937-
DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
24938-
CmpOpConst->getValueType(0)));
24953+
DAG.getVTList(VT, MVT_CC), CmpOpOther, SubsOp);
2493924954

2494024955
auto Reassociate = [&](SDValue ReassocOp, unsigned OpNum) {
2494124956
if (!ReassocOp)
@@ -24957,9 +24972,19 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2495724972

2495824973
// First, try to eliminate the compare instruction by searching for a
2495924974
// subtraction with the same constant.
24960-
if (SDValue R = Fold(CmpOpConst->getAPIntValue(), CC))
24975+
if (SDValue R = Fold(CC, CheckOp, SubsOp))
2496124976
return R;
2496224977

24978+
if (!CmpOpConst) {
24979+
// Try again with the operands of the SUBS instruction and the condition
24980+
// swapped. Due to canonicalization, this only helps for non-constant
24981+
// operands of the SUBS instruction.
24982+
std::swap(CmpOpToMatch, CmpOpOther);
24983+
if (SDValue R = Fold(getSwappedCondition(CC), CheckOp, CmpOpToMatch))
24984+
return R;
24985+
return SDValue();
24986+
}
24987+
2496324988
if ((CC == AArch64CC::EQ || CC == AArch64CC::NE) && !CmpOpConst->isZero())
2496424989
return SDValue();
2496524990

@@ -24971,7 +24996,13 @@ static SDValue reassociateCSELOperandsForCSE(SDNode *N, SelectionDAG &DAG) {
2497124996
// them here but check for them nevertheless to be on the safe side.
2497224997
auto CheckedFold = [&](bool Check, APInt NewCmpConst,
2497324998
AArch64CC::CondCode NewCC) {
24974-
return Check ? Fold(NewCmpConst, NewCC) : SDValue();
24999+
auto CheckOp = [=](SDValue Op) {
25000+
auto *AddOpConst = dyn_cast<ConstantSDNode>(Op);
25001+
return AddOpConst && AddOpConst->getAPIntValue() == -NewCmpConst;
25002+
};
25003+
auto SubsOp = DAG.getConstant(NewCmpConst, SDLoc(CmpOpConst),
25004+
CmpOpConst->getValueType(0));
25005+
return Check ? Fold(NewCC, CheckOp, SubsOp) : SDValue();
2497525006
};
2497625007
switch (CC) {
2497725008
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)