[llvm] [AArch64] Add should be adjusted to zero for GlobalISel (PR #195941)

via llvm-commits llvm-commits at lists.llvm.org
Tue May 5 14:09:08 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: LumioseSil (LumioseSil)

<details>
<summary>Changes</summary>

Realized that we can also get more out of it if it is pl/mi regardless of and, so I put that in SelectionDAG too.

---

Patch is 39.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/195941.diff


7 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+2-5) 
- (modified) llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp (+57-27) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir (+4-4) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-swap-compare-operands.mir (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/arm64-csel.ll (+9-18) 
- (modified) llvm/test/CodeGen/AArch64/cmp-to-cmn.ll (+305-335) 
- (modified) llvm/test/CodeGen/AArch64/select-constant-xor.ll (+6-6) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f5082b779d1db..8f6354fa06faa 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4169,11 +4169,8 @@ static unsigned getCmpOperandFoldingProfit(SDValue Op) {
 // with 0. Note that this only works for signed comparisons because of how ANDS
 // works.
 static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
-  // Only works for ANDS and AND.
-  if (LHS.getOpcode() != ISD::AND && LHS.getOpcode() != AArch64ISD::ANDS)
-    return false;
-
-  if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
+  if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE) &&
+      (LHS.getOpcode() == ISD::AND || LHS.getOpcode() == AArch64ISD::ANDS)) {
     CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
     return true;
   }
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 58aa2cc37c9b2..a26cd99af38a3 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -604,6 +604,31 @@ void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
   MI.eraseFromParent();
 }
 
+bool isLegalCmpImmed(APInt C) {
+  // Works for negative immediates too, as it can be written as an ADDS
+  // instruction with a negated immediate.
+  return isLegalArithImmed(C.abs().getZExtValue());
+}
+
+/// Adjust compares against 1/-1 to a compare against 0.
+static bool shouldBeAdjustedToZero(Register LHS, APInt C, CmpInst::Predicate &P,
+                                   const MachineRegisterInfo &MRI) {
+  MachineInstr *LHSDef = getDefIgnoringCopies(LHS, MRI);
+  const bool IsAndLHS = LHSDef && LHSDef->getOpcode() == TargetOpcode::G_AND;
+
+  if (C.isOne() && (P == CmpInst::ICMP_SLT || P == CmpInst::ICMP_SGE)) {
+    if (!IsAndLHS)
+      return false;
+    P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
+    return true;
+  }
+  if (C.isAllOnes() && (P == CmpInst::ICMP_SLE || P == CmpInst::ICMP_SGT)) {
+    P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
+    return true;
+  }
+  return false;
+}
+
 /// Determine if it is possible to modify the \p RHS and predicate \p P of a
 /// G_ICMP instruction such that the right-hand side is an arithmetic immediate.
 ///
@@ -612,7 +637,7 @@ void applyVAshrLshrImm(MachineInstr &MI, MachineRegisterInfo &MRI,
 ///
 /// \note This assumes that the comparison has been legalized.
 std::optional<std::pair<uint64_t, CmpInst::Predicate>>
-tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
+tryAdjustICmpImmAndPred(Register LHS, Register RHS, CmpInst::Predicate P,
                         const MachineRegisterInfo &MRI) {
   const auto &Ty = MRI.getType(RHS);
   if (Ty.isVector())
@@ -625,9 +650,12 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
   auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS, MRI);
   if (!ValAndVReg)
     return std::nullopt;
-  uint64_t OriginalC = ValAndVReg->Value.getZExtValue();
-  uint64_t C = OriginalC;
-  if (isLegalArithImmed(C))
+  APInt C = ValAndVReg->Value;
+  APInt OriginalC = C;
+  if (shouldBeAdjustedToZero(LHS, C, P, MRI))
+    return {{0, P}};
+
+  if (isLegalCmpImmed(C))
     return std::nullopt;
 
   // We have a non-arithmetic immediate. Check if adjusting the immediate and
@@ -643,11 +671,10 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x sge c => x sgt c - 1
     //
     // When c is not the smallest possible negative number.
-    if ((Size == 64 && static_cast<int64_t>(C) == INT64_MIN) ||
-        (Size == 32 && static_cast<int32_t>(C) == INT32_MIN))
+    if (C.isMinSignedValue())
       return std::nullopt;
     P = (P == CmpInst::ICMP_SLT) ? CmpInst::ICMP_SLE : CmpInst::ICMP_SGT;
-    C -= 1;
+    C = C - 1;
     break;
   case CmpInst::ICMP_ULT:
   case CmpInst::ICMP_UGE:
@@ -657,9 +684,9 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x uge c => x ugt c - 1
     //
     // When c is not zero.
-    assert(C != 0 && "C should not be zero here!");
+    assert(!C.isZero() && "C should not be zero here!");
     P = (P == CmpInst::ICMP_ULT) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
-    C -= 1;
+    C = C - 1;
     break;
   case CmpInst::ICMP_SLE:
   case CmpInst::ICMP_SGT:
@@ -669,11 +696,10 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x sgt c => s sge c + 1
     //
     // When c is not the largest possible signed integer.
-    if ((Size == 32 && static_cast<int32_t>(C) == INT32_MAX) ||
-        (Size == 64 && static_cast<int64_t>(C) == INT64_MAX))
+    if (C.isMaxSignedValue())
       return std::nullopt;
     P = (P == CmpInst::ICMP_SLE) ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGE;
-    C += 1;
+    C = C + 1;
     break;
   case CmpInst::ICMP_ULE:
   case CmpInst::ICMP_UGT:
@@ -683,20 +709,17 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     // x ugt c => s uge c + 1
     //
     // When c is not the largest possible unsigned integer.
-    if ((Size == 32 && static_cast<uint32_t>(C) == UINT32_MAX) ||
-        (Size == 64 && C == UINT64_MAX))
+    if (C.isAllOnes())
       return std::nullopt;
     P = (P == CmpInst::ICMP_ULE) ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
-    C += 1;
+    C = C + 1;
     break;
   }
 
   // Check if the new constant is valid, and return the updated constant and
   // predicate if it is.
-  if (Size == 32)
-    C = static_cast<uint32_t>(C);
-  if (isLegalArithImmed(C))
-    return {{C, P}};
+  if (isLegalCmpImmed(C))
+    return {{C.getZExtValue(), P}};
 
   auto NumberOfInstrToLoadImm = [=](uint64_t Imm) {
     SmallVector<AArch64_IMM::ImmInsnModel> Insn;
@@ -704,8 +727,9 @@ tryAdjustICmpImmAndPred(Register RHS, CmpInst::Predicate P,
     return Insn.size();
   };
 
-  if (NumberOfInstrToLoadImm(OriginalC) > NumberOfInstrToLoadImm(C))
-    return {{C, P}};
+  if (NumberOfInstrToLoadImm(OriginalC.getZExtValue()) >
+      NumberOfInstrToLoadImm(C.getZExtValue()))
+    return {{C.getZExtValue(), P}};
 
   return std::nullopt;
 }
@@ -722,9 +746,10 @@ bool matchAdjustICmpImmAndPred(
     MachineInstr &MI, const MachineRegisterInfo &MRI,
     std::pair<uint64_t, CmpInst::Predicate> &MatchInfo) {
   assert(MI.getOpcode() == TargetOpcode::G_ICMP);
+  Register LHS = MI.getOperand(2).getReg();
   Register RHS = MI.getOperand(3).getReg();
   auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
-  if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(RHS, Pred, MRI)) {
+  if (auto MaybeNewImmAndPred = tryAdjustICmpImmAndPred(LHS, RHS, Pred, MRI)) {
     MatchInfo = *MaybeNewImmAndPred;
     return true;
   }
@@ -933,15 +958,18 @@ bool trySwapICmpOperands(MachineInstr &MI, MachineRegisterInfo &MRI) {
   // can be turned into:
   //    cmp     w12, w11, lsl #1
 
-  // Don't swap if there's a constant on the RHS, because we know we can fold
-  // that.
+  // Don't swap if there's a constant on the RHS and it is a legal compare
+  // immediate, because we know we can fold that.
   Register RHS = MI.getOperand(3).getReg();
   auto RHSCst = getIConstantVRegValWithLookThrough(RHS, MRI);
-  if (RHSCst && isLegalArithImmed(RHSCst->Value.getSExtValue()))
+  if (RHSCst && isLegalCmpImmed(RHSCst->Value))
     return false;
 
   Register LHS = MI.getOperand(2).getReg();
   auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
+  auto IsRegCMN = [&](Register Reg) {
+    return isCMN(getDefIgnoringCopies(Reg, MRI), Pred, MRI);
+  };
   auto GetRegForProfit = [&](Register Reg) {
     MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);
     return isCMN(Def, Pred, MRI) ? Def->getOperand(2).getReg() : Reg;
@@ -949,13 +977,15 @@ bool trySwapICmpOperands(MachineInstr &MI, MachineRegisterInfo &MRI) {
 
   // Don't have a constant on the RHS. If we swap the LHS and RHS of the
   // compare, would we be able to fold more instructions?
+  bool LHSIsCMN = IsRegCMN(LHS);
+  bool RHSIsCMN = IsRegCMN(RHS);
   Register TheLHS = GetRegForProfit(LHS);
   Register TheRHS = GetRegForProfit(RHS);
 
   // If the LHS is more likely to give us a folding opportunity, then swap the
   // LHS and RHS.
-  return (getCmpOperandFoldingProfit(TheLHS, MRI) >
-          getCmpOperandFoldingProfit(TheRHS, MRI));
+  return (getCmpOperandFoldingProfit(TheLHS, MRI) + (LHSIsCMN ? 1 : 0) >
+          getCmpOperandFoldingProfit(TheRHS, MRI) + (RHSIsCMN ? 1 : 0));
 }
 
 void applySwapICmpOperands(MachineInstr &MI, GISelChangeObserver &Observer) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
index 3b991c3d910d5..a86691b30f44d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir
@@ -649,8 +649,8 @@ body:             |
     ; LOWER-NEXT: {{  $}}
     ; LOWER-NEXT: %reg0:_(s32) = COPY $w0
     ; LOWER-NEXT: %reg1:_(s32) = COPY $w1
-    ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
-    ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg0(s32), [[C]]
+    ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -1
+    ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst
     ; LOWER-NEXT: %select:_(s32) = G_SELECT %cmp(s32), %reg0, %reg1
     ; LOWER-NEXT: $w0 = COPY %select(s32)
     ; LOWER-NEXT: RET_ReallyLR implicit $w0
@@ -660,8 +660,8 @@ body:             |
     ; SELECT-NEXT: {{  $}}
     ; SELECT-NEXT: %reg0:gpr32common = COPY $w0
     ; SELECT-NEXT: %reg1:gpr32 = COPY $w1
-    ; SELECT-NEXT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg0, 0, 0, implicit-def $nzcv
-    ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 4, implicit $nzcv
+    ; SELECT-NEXT: [[ADDSWri:%[0-9]+]]:gpr32 = ADDSWri %reg0, 1, 0, implicit-def $nzcv
+    ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 13, implicit $nzcv
     ; SELECT-NEXT: $w0 = COPY %select
     ; SELECT-NEXT: RET_ReallyLR implicit $w0
     %reg0:_(s32) = COPY $w0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-swap-compare-operands.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-swap-compare-operands.mir
index 315ca9360dca6..b7987c2b7cc3f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-swap-compare-operands.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-swap-compare-operands.mir
@@ -561,7 +561,7 @@ body:             |
     ; LOWER-NEXT: %sub_rhs:_(i64) = COPY $x0
     ; LOWER-NEXT: %zero:_(i64) = G_CONSTANT i64 0
     ; LOWER-NEXT: %cmp_lhs:_(i64) = G_SUB %zero, %sub_rhs
-    ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ne), %cmp_lhs(i64), %cmp_rhs
+    ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ne), %cmp_rhs(i64), %cmp_lhs
     ; LOWER-NEXT: $w0 = COPY %cmp(i32)
     ; LOWER-NEXT: RET_ReallyLR implicit $w0
     ;
@@ -570,7 +570,7 @@ body:             |
     ; SELECT-NEXT: {{  $}}
     ; SELECT-NEXT: %cmp_rhs:gpr64 = COPY $x1
     ; SELECT-NEXT: %sub_rhs:gpr64 = COPY $x0
-    ; SELECT-NEXT: [[ADDSXrr:%[0-9]+]]:gpr64 = ADDSXrr %sub_rhs, %cmp_rhs, implicit-def $nzcv
+    ; SELECT-NEXT: [[ADDSXrr:%[0-9]+]]:gpr64 = ADDSXrr %cmp_rhs, %sub_rhs, implicit-def $nzcv
     ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 0, implicit $nzcv
     ; SELECT-NEXT: $w0 = COPY %cmp
     ; SELECT-NEXT: RET_ReallyLR implicit $w0
diff --git a/llvm/test/CodeGen/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll
index f677f2f77fc61..2c7ac20ce68c6 100644
--- a/llvm/test/CodeGen/AArch64/arm64-csel.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll
@@ -110,24 +110,15 @@ l.else:
 
 ; If CPSR is used multiple times and V flag is used, we don't remove cmp.
 define i32 @foo7(i32 %a, i32 %b) nounwind {
-; CHECK-SD-LABEL: foo7:
-; CHECK-SD:       // %bb.0: // %entry
-; CHECK-SD-NEXT:    subs w8, w0, w1
-; CHECK-SD-NEXT:    cneg w9, w8, mi
-; CHECK-SD-NEXT:    cmn w8, #1
-; CHECK-SD-NEXT:    csel w8, w9, w0, lt
-; CHECK-SD-NEXT:    csel w0, w8, w9, gt
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: foo7:
-; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    subs w8, w0, w1
-; CHECK-GI-NEXT:    cneg w9, w8, mi
-; CHECK-GI-NEXT:    cmn w8, #1
-; CHECK-GI-NEXT:    csel w10, w9, w0, lt
-; CHECK-GI-NEXT:    cmp w8, #0
-; CHECK-GI-NEXT:    csel w0, w10, w9, pl
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: foo7:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    subs w8, w0, w1
+; CHECK-NEXT:    cneg w9, w8, mi
+; CHECK-NEXT:    cmn w8, #1
+; CHECK-NEXT:    csel w10, w9, w0, lt
+; CHECK-NEXT:    cmp w8, #0
+; CHECK-NEXT:    csel w0, w10, w9, pl
+; CHECK-NEXT:    ret
 entry:
   %sub = sub nsw i32 %a, %b
   %cmp = icmp sgt i32 %sub, -1
diff --git a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
index b3ce9d2369104..8757f48409827 100644
--- a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
+++ b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
@@ -5,17 +5,11 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "arm64"
 
 define i1 @test_EQ_IllEbT(i64 %a, i64 %b) {
-; CHECK-SD-LABEL: test_EQ_IllEbT:
-; CHECK-SD:       // %bb.0: // %entry
-; CHECK-SD-NEXT:    cmn x0, x1
-; CHECK-SD-NEXT:    cset w0, eq
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: test_EQ_IllEbT:
-; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    cmn x1, x0
-; CHECK-GI-NEXT:    cset w0, eq
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: test_EQ_IllEbT:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    cmn x0, x1
+; CHECK-NEXT:    cset w0, eq
+; CHECK-NEXT:    ret
 entry:
   %add = sub i64 0, %b
   %cmp = icmp eq i64 %add, %a
@@ -44,11 +38,19 @@ entry:
 }
 
 define i1 @test_EQ_IlsEbT(i64 %a, i16 %b) {
-; CHECK-LABEL: test_EQ_IlsEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn x0, w1, sxth
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IlsEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn x0, w1, sxth
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IlsEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-GI-NEXT:    sxth x8, w1
+; CHECK-GI-NEXT:    cmn x8, x0
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = sext i16 %b to i64
   %add = sub i64 0, %a
@@ -57,11 +59,19 @@ entry:
 }
 
 define i1 @test_EQ_IlcEbT(i64 %a, i8 %b) {
-; CHECK-LABEL: test_EQ_IlcEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn x0, w1, uxtb
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IlcEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn x0, w1, uxtb
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IlcEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    // kill: def $w1 killed $w1 def $x1
+; CHECK-GI-NEXT:    and x8, x1, #0xff
+; CHECK-GI-NEXT:    cmn x8, x0
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = zext i8 %b to i64
   %add = sub i64 0, %a
@@ -91,17 +101,11 @@ entry:
 }
 
 define i1 @test_EQ_IiiEbT(i32 %a, i32 %b) {
-; CHECK-SD-LABEL: test_EQ_IiiEbT:
-; CHECK-SD:       // %bb.0: // %entry
-; CHECK-SD-NEXT:    cmn w0, w1
-; CHECK-SD-NEXT:    cset w0, eq
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: test_EQ_IiiEbT:
-; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    cmn w1, w0
-; CHECK-GI-NEXT:    cset w0, eq
-; CHECK-GI-NEXT:    ret
+; CHECK-LABEL: test_EQ_IiiEbT:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    cmn w0, w1
+; CHECK-NEXT:    cset w0, eq
+; CHECK-NEXT:    ret
 entry:
   %add = sub i32 0, %b
   %cmp = icmp eq i32 %add, %a
@@ -109,11 +113,18 @@ entry:
 }
 
 define i1 @test_EQ_IisEbT(i32 %a, i16 %b) {
-; CHECK-LABEL: test_EQ_IisEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn w0, w1, sxth
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IisEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn w0, w1, sxth
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IisEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    sxth w8, w1
+; CHECK-GI-NEXT:    cmn w8, w0
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = sext i16 %b to i32
   %add = sub i32 0, %a
@@ -122,11 +133,18 @@ entry:
 }
 
 define i1 @test_EQ_IicEbT(i32 %a, i8 %b) {
-; CHECK-LABEL: test_EQ_IicEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn w0, w1, uxtb
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IicEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn w0, w1, uxtb
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IicEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    and w8, w1, #0xff
+; CHECK-GI-NEXT:    cmn w8, w0
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = zext i8 %b to i32
   %add = sub i32 0, %a
@@ -135,11 +153,19 @@ entry:
 }
 
 define i1 @test_EQ_IslEbT(i16 %a, i64 %b) {
-; CHECK-LABEL: test_EQ_IslEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn x1, w0, sxth
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IslEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn x1, w0, sxth
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IslEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    // kill: def $w0 killed $w0 def $x0
+; CHECK-GI-NEXT:    sxth x8, w0
+; CHECK-GI-NEXT:    cmn x8, x1
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = sext i16 %a to i64
   %add = sub i64 0, %b
@@ -148,11 +174,18 @@ entry:
 }
 
 define i1 @test_EQ_IsiEbT(i16 %a, i32 %b) {
-; CHECK-LABEL: test_EQ_IsiEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn w1, w0, sxth
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IsiEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn w1, w0, sxth
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IsiEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    sxth w8, w0
+; CHECK-GI-NEXT:    cmn w8, w1
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = sext i16 %a to i32
   %add = sub i32 0, %b
@@ -191,11 +224,19 @@ entry:
 }
 
 define i1 @test_EQ_IclEbT(i8 %a, i64 %b) {
-; CHECK-LABEL: test_EQ_IclEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn x1, w0, uxtb
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IclEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn x1, w0, uxtb
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IclEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    // kill: def $w0 killed $w0 def $x0
+; CHECK-GI-NEXT:    and x8, x0, #0xff
+; CHECK-GI-NEXT:    cmn x8, x1
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = zext i8 %a to i64
   %add = sub i64 0, %b
@@ -204,11 +245,18 @@ entry:
 }
 
 define i1 @test_EQ_IciEbT(i8 %a, i32 %b) {
-; CHECK-LABEL: test_EQ_IciEbT:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    cmn w1, w0, uxtb
-; CHECK-NEXT:    cset w0, eq
-; CHECK-NEXT:    ret
+; CHECK-SD-LABEL: test_EQ_IciEbT:
+; CHECK-SD:       // %bb.0: // %entry
+; CHECK-SD-NEXT:    cmn w1, w0, uxtb
+; CHECK-SD-NEXT:    cset w0, eq
+; CHECK-SD-NEXT:    ret
+;
+; CHECK-GI-LABEL: test_EQ_IciEbT:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    and w8, w0, #0xff
+; CHECK-GI-NEXT:    cmn w8, w1
+; CHECK-GI-NEXT:    cset w0, eq
+; CHECK-GI-NEXT:    ret
 entry:
   %conv = zext i8 %a to i32
   %add = sub i32 0, %b
@@ -247,17 +295,11 @@ entry:
 }
 
 define i1 @test_NE_IllEbT(i64 %a, i64 %b) {
-; CHECK-SD-LABEL: test_NE_IllEbT:
-; CHECK-SD:       // %bb.0: // %entry
-; CHECK-SD-NEXT:    cmn x0, x1
-; CHECK-SD-NEXT:    cset w0, ne
-; CHECK-SD-NEXT:    ret
-;
-; CHECK-GI-LABEL: test_NE_IllEbT:
-; CHECK-GI:       // %bb.0: // %entry
-; CHECK-GI-NEXT:    cmn x1, x0
-; CHECK-GI-NEXT:    cset w0, ne
-; CHECK-GI-NEXT:    re...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/195941


More information about the llvm-commits mailing list