[llvm] [RISCV][GISel] Select G_SELECT (G_ICMP, A, B) (PR #68247)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 23 07:06:40 PDT 2023


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/68247

>From e81ab66f04e4af2ed90cebb58f506f4f7d8ed7f9 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 3 Oct 2023 15:29:47 -0700
Subject: [PATCH 1/8] [RISCV][GISel] Select G_SELECT (G_ICMP, A, B)

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 128 ++++++++++++++++--
 .../instruction-select/select-rv32.mir        | 122 +++++++++++++++++
 .../instruction-select/select-rv64.mir        | 122 +++++++++++++++++
 3 files changed, 359 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index ab2125a3615f385..f5323f6938162aa 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -83,6 +83,11 @@ class RISCVInstructionSelector : public InstructionSelector {
   void renderImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
                  int OpIdx) const;
 
+  /// Returns a G_ICMP that is equivalent to MI, whose condition code matches
+  /// one of the comparisons supported directly by branches in the RISC-V ISA.
+  MachineInstr *createICMPForBranch(MachineInstr *MI, MachineIRBuilder &MIB,
+                                 MachineRegisterInfo &MRI) const;
+
   const RISCVSubtarget &STI;
   const RISCVInstrInfo &TII;
   const RISCVRegisterInfo &TRI;
@@ -498,23 +503,120 @@ bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
   return true;
 }
 
+/// Returns the RISCVCC::CondCode that corresponds to the CmpInst::Predicate CC.
+/// CC Must be an ICMP Predicate.
+static RISCVCC::CondCode getRISCVCCFromICMP(CmpInst::Predicate CC) {
+  switch (CC) {
+  default:
+    llvm_unreachable("Expected ICMP CmpInst::Predicate.");
+  case CmpInst::Predicate::ICMP_EQ:
+    return RISCVCC::COND_EQ;
+  case CmpInst::Predicate::ICMP_NE:
+    return RISCVCC::COND_NE;
+  case CmpInst::Predicate::ICMP_ULT:
+    return RISCVCC::COND_LTU;
+  case CmpInst::Predicate::ICMP_SLT:
+    return RISCVCC::COND_LT;
+  case CmpInst::Predicate::ICMP_UGE:
+    return RISCVCC::COND_GEU;
+  case CmpInst::Predicate::ICMP_SGE:
+    return RISCVCC::COND_GE;
+  }
+}
+
+MachineInstr *RISCVInstructionSelector::createICMPForBranch(
+    MachineInstr *MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
+  assert(MI->getOpcode() == TargetOpcode::G_ICMP);
+  CmpInst::Predicate CC =
+      static_cast<CmpInst::Predicate>(MI->getOperand(1).getPredicate());
+  MachineOperand &LHS = MI->getOperand(2);
+  MachineOperand &RHS = MI->getOperand(3);
+
+  // Adjust comparisons to use comparison with 0 if possible.
+  MachineInstr *MaybeConstant = MRI.getVRegDef(RHS.getReg());
+  if (MaybeConstant && MaybeConstant->getOpcode() == TargetOpcode::G_CONSTANT) {
+    switch (CC) {
+    case CmpInst::Predicate::ICMP_SGT:
+      // Convert X > -1 to X >= 0
+      if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == -1) {
+        MachineInstr *Zero = MIB.buildConstant(
+            MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
+        selectConstant(*Zero, MIB, MRI);
+        return MIB.buildICmp(CmpInst::Predicate::ICMP_SGE, MI->getOperand(0),
+                             LHS, Zero->getOperand(0));
+      }
+      break;
+    case CmpInst::Predicate::ICMP_SLT:
+      // Convert X < 1 to 0 >= X
+      if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == 1) {
+        MachineInstr *Zero= MIB.buildConstant(
+            MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
+        selectConstant(*Zero, MIB, MRI);
+        return MIB.buildICmp(CmpInst::Predicate::ICMP_SGE, MI->getOperand(0),
+                             Zero->getOperand(0), LHS);
+      }
+      break;
+    default:
+      break;
+    }
+  }
+
+  switch (CC) {
+  default:
+    llvm_unreachable("Expected ICMP CmpInst::Predicate.");
+  case CmpInst::Predicate::ICMP_EQ:
+  case CmpInst::Predicate::ICMP_NE:
+  case CmpInst::Predicate::ICMP_ULT:
+  case CmpInst::Predicate::ICMP_SLT:
+  case CmpInst::Predicate::ICMP_UGE:
+  case CmpInst::Predicate::ICMP_SGE:
+    // These CCs are supported directly by RISC-V branches.
+    return MI;
+  case CmpInst::Predicate::ICMP_SGT:
+  case CmpInst::Predicate::ICMP_SLE:
+  case CmpInst::Predicate::ICMP_UGT:
+  case CmpInst::Predicate::ICMP_ULE:
+    // These CCs are not supported directly by RISC-V branches, but changing the
+    // direction of the CC and swapping LHS and RHS are.
+    return MIB.buildICmp(CmpInst::getSwappedPredicate(CC), MI->getOperand(0),
+                         RHS, LHS);
+  }
+}
+
 bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
                                             MachineIRBuilder &MIB,
                                             MachineRegisterInfo &MRI) const {
-  // TODO: Currently we check that the conditional code passed to G_SELECT is
-  // not equal to zero; however, in the future, we might want to try and check
-  // if the conditional code comes from a G_ICMP. If it does, we can directly
-  // use G_ICMP to get the first three input operands of the
-  // Select_GPR_Using_CC_GPR. This might be done here, or in the appropriate
-  // combiner.
   assert(MI.getOpcode() == TargetOpcode::G_SELECT);
-  MachineInstr *Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
-                             .addDef(MI.getOperand(0).getReg())
-                             .addReg(MI.getOperand(1).getReg())
-                             .addReg(RISCV::X0)
-                             .addImm(RISCVCC::COND_NE)
-                             .addReg(MI.getOperand(2).getReg())
-                             .addReg(MI.getOperand(3).getReg());
+  MachineInstr *Result;
+  MachineInstr *MaybeICMP = MRI.getVRegDef(MI.getOperand(1).getReg());
+  if (MaybeICMP && MaybeICMP->getOpcode() == TargetOpcode::G_ICMP) {
+    // If MI is a G_SELECT(G_ICMP(tst, A, B), C, D) then we can use (A, B, tst)
+    // as the (LHS, RHS, CC) of the Select_GPR_Using_CC_GPR.
+    MachineInstr *ICMPForBranch = createICMPForBranch(MaybeICMP, MIB, MRI);
+    CmpInst::Predicate CC = static_cast<CmpInst::Predicate>(
+        ICMPForBranch->getOperand(1).getPredicate());
+    Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
+                 .addDef(MI.getOperand(0).getReg());
+    Result->addOperand(ICMPForBranch->getOperand(2));
+    Result->addOperand(ICMPForBranch->getOperand(3));
+    Result->addOperand(
+        MachineOperand::CreateImm(getRISCVCCFromICMP(CC)));
+    Result->addOperand(MI.getOperand(2));
+    Result->addOperand(MI.getOperand(3));
+
+    // Delete ICMPForBranch since we know it has no users. Let the original
+    // G_ICMP be selected normally in case it has other users.
+    if (ICMPForBranch != MaybeICMP)
+      ICMPForBranch->eraseFromParent();
+  } else {
+    Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
+                 .addDef(MI.getOperand(0).getReg())
+                 .addReg(MI.getOperand(1).getReg())
+                 .addReg(RISCV::X0)
+                 .addImm(RISCVCC::COND_NE)
+                 .addReg(MI.getOperand(2).getReg())
+                 .addReg(MI.getOperand(3).getReg());
+  }
   MI.eraseFromParent();
   return constrainSelectedInstRegOperands(*Result, TII, TRI, RBI);
 }
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir
index 828835dac8f80ca..b9bd9b980e2e475 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv32.mir
@@ -53,3 +53,125 @@ body:            |
     PseudoRET implicit $x10
 
 ...
+---
+name:            select_icmp_ult
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_ult
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY2]], [[COPY3]], 4, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s32) = COPY $x10
+    %1:gprb(s32) = COPY $x11
+    %2:gprb(s32) = COPY $x12
+    %3:gprb(s32) = COPY $x13
+    %4:gprb(s32) = COPY $x14
+    %5:gprb(s32) = G_ICMP intpred(ult), %2, %3
+    %6:gprb(s32) = G_SELECT %5, %0, %1
+    $x10 = COPY %6(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_ugt
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_ugt
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY3]], [[COPY2]], 4, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s32) = COPY $x10
+    %1:gprb(s32) = COPY $x11
+    %2:gprb(s32) = COPY $x12
+    %3:gprb(s32) = COPY $x13
+    %4:gprb(s32) = COPY $x14
+    %5:gprb(s32) = G_ICMP intpred(ugt), %2, %3
+    %6:gprb(s32) = G_SELECT %5, %0, %1
+    $x10 = COPY %6(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_sgtneg1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_sgtneg1
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x0
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY2]], [[COPY3]], 3, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s32) = COPY $x10
+    %1:gprb(s32) = COPY $x11
+    %2:gprb(s32) = COPY $x12
+    %3:gprb(s32) = COPY $x13
+    %4:gprb(s32) = COPY $x14
+    %5:gprb(s32) = G_CONSTANT i32 -1
+    %6:gprb(s32) = G_ICMP intpred(sgt), %2, %5
+    %7:gprb(s32) = G_SELECT %6, %0, %1
+    $x10 = COPY %7(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_slt1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_slt1
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x0
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY3]], [[COPY2]], 3, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s32) = COPY $x10
+    %1:gprb(s32) = COPY $x11
+    %2:gprb(s32) = COPY $x12
+    %3:gprb(s32) = COPY $x13
+    %4:gprb(s32) = COPY $x14
+    %5:gprb(s32) = G_CONSTANT i32 1
+    %6:gprb(s32) = G_ICMP intpred(slt), %2, %5
+    %7:gprb(s32) = G_SELECT %6, %0, %1
+    $x10 = COPY %7(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir
index caa42f01c40cad1..6eee273d320be94 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/select-rv64.mir
@@ -53,3 +53,125 @@ body:            |
     PseudoRET implicit $x10
 
 ...
+---
+name:            select_icmp_ult
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_ult
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY2]], [[COPY3]], 4, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s64) = COPY $x10
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = COPY $x12
+    %3:gprb(s64) = COPY $x13
+    %4:gprb(s64) = COPY $x14
+    %5:gprb(s64) = G_ICMP intpred(ult), %2, %3
+    %6:gprb(s64) = G_SELECT %5, %0, %1
+    $x10 = COPY %6(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_ugt
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_ugt
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY3]], [[COPY2]], 4, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s64) = COPY $x10
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = COPY $x12
+    %3:gprb(s64) = COPY $x13
+    %4:gprb(s64) = COPY $x14
+    %5:gprb(s64) = G_ICMP intpred(ugt), %2, %3
+    %6:gprb(s64) = G_SELECT %5, %0, %1
+    $x10 = COPY %6(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_sgtneg1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_sgtneg1
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x0
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY2]], [[COPY3]], 3, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s64) = COPY $x10
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = COPY $x12
+    %3:gprb(s64) = COPY $x13
+    %4:gprb(s64) = COPY $x14
+    %5:gprb(s64) = G_CONSTANT i64 -1
+    %6:gprb(s64) = G_ICMP intpred(sgt), %2, %5
+    %7:gprb(s64) = G_SELECT %6, %0, %1
+    $x10 = COPY %7(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            select_icmp_slt1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    liveins: $x10, $x11, $x12, $x13, $x14
+
+    ; CHECK-LABEL: name: select_icmp_slt1
+    ; CHECK: liveins: $x10, $x11, $x12, $x13, $x14
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x12
+    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x0
+    ; CHECK-NEXT: [[Select_GPR_Using_CC_GPR:%[0-9]+]]:gpr = Select_GPR_Using_CC_GPR [[COPY3]], [[COPY2]], 3, [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $x10 = COPY [[Select_GPR_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gprb(s64) = COPY $x10
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = COPY $x12
+    %3:gprb(s64) = COPY $x13
+    %4:gprb(s64) = COPY $x14
+    %5:gprb(s64) = G_CONSTANT i64 1
+    %6:gprb(s64) = G_ICMP intpred(slt), %2, %5
+    %7:gprb(s64) = G_SELECT %6, %0, %1
+    $x10 = COPY %7(s64)
+    PseudoRET implicit $x10
+
+...

>From a1b9d386f75d5c41887ea066c13f2a57beea25b3 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 4 Oct 2023 13:02:54 -0700
Subject: [PATCH 2/8] fixup! [RISCV][GISel] Select G_SELECT (G_ICMP, A, B)

Don't create new G_ICMP
---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 66 +++++++++----------
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index f5323f6938162aa..dd0673d245978c0 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -83,10 +83,13 @@ class RISCVInstructionSelector : public InstructionSelector {
   void renderImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
                  int OpIdx) const;
 
-  /// Returns a G_ICMP that is equivalent to MI, whose condition code matches
-  /// one of the comparisons supported directly by branches in the RISC-V ISA.
-  MachineInstr *createICMPForBranch(MachineInstr *MI, MachineIRBuilder &MIB,
-                                 MachineRegisterInfo &MRI) const;
+  /// Sets CC, LHS, and RHS so that they form an equivelent G_ICMP (CC, LHS,
+  /// RHS) to that of MI, but whose condition code matches one of the
+  /// comparisons supported directly by branches in the RISC-V ISA.
+  void setICMPOperandsForBranch(MachineInstr &MI, MachineIRBuilder &MIB,
+                                 MachineRegisterInfo &MRI,
+                                 CmpInst::Predicate &CC, MachineOperand &LHS,
+                                 MachineOperand &RHS) const;
 
   const RISCVSubtarget &STI;
   const RISCVInstrInfo &TII;
@@ -524,13 +527,13 @@ static RISCVCC::CondCode getRISCVCCFromICMP(CmpInst::Predicate CC) {
   }
 }
 
-MachineInstr *RISCVInstructionSelector::createICMPForBranch(
-    MachineInstr *MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI) const {
-  assert(MI->getOpcode() == TargetOpcode::G_ICMP);
-  CmpInst::Predicate CC =
-      static_cast<CmpInst::Predicate>(MI->getOperand(1).getPredicate());
-  MachineOperand &LHS = MI->getOperand(2);
-  MachineOperand &RHS = MI->getOperand(3);
+void RISCVInstructionSelector::setICMPOperandsForBranch(
+    MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI,
+    CmpInst::Predicate &CC, MachineOperand &LHS, MachineOperand &RHS) const {
+  assert(MI.getOpcode() == TargetOpcode::G_ICMP);
+  CC = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
+  LHS = MI.getOperand(2);
+  RHS = MI.getOperand(3);
 
   // Adjust comparisons to use comparison with 0 if possible.
   MachineInstr *MaybeConstant = MRI.getVRegDef(RHS.getReg());
@@ -542,20 +545,21 @@ MachineInstr *RISCVInstructionSelector::createICMPForBranch(
         MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        return MIB.buildICmp(CmpInst::Predicate::ICMP_SGE, MI->getOperand(0),
-                             LHS, Zero->getOperand(0));
+        CC = CmpInst::Predicate::ICMP_SGE;
+        RHS = MachineOperand::CreateReg(Zero->getOperand(0).getReg(), false);
       }
-      break;
+      return;
     case CmpInst::Predicate::ICMP_SLT:
       // Convert X < 1 to 0 >= X
       if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == 1) {
-        MachineInstr *Zero= MIB.buildConstant(
+        MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        return MIB.buildICmp(CmpInst::Predicate::ICMP_SGE, MI->getOperand(0),
-                             Zero->getOperand(0), LHS);
+        CC =  CmpInst::Predicate::ICMP_SGE;
+        RHS = LHS;
+        LHS = MachineOperand::CreateReg(Zero->getOperand(0).getReg(), false);
       }
-      break;
+      return;
     default:
       break;
     }
@@ -571,15 +575,16 @@ MachineInstr *RISCVInstructionSelector::createICMPForBranch(
   case CmpInst::Predicate::ICMP_UGE:
   case CmpInst::Predicate::ICMP_SGE:
     // These CCs are supported directly by RISC-V branches.
-    return MI;
+    return;
   case CmpInst::Predicate::ICMP_SGT:
   case CmpInst::Predicate::ICMP_SLE:
   case CmpInst::Predicate::ICMP_UGT:
   case CmpInst::Predicate::ICMP_ULE:
     // These CCs are not supported directly by RISC-V branches, but changing the
     // direction of the CC and swapping LHS and RHS are.
-    return MIB.buildICmp(CmpInst::getSwappedPredicate(CC), MI->getOperand(0),
-                         RHS, LHS);
+    CC = CmpInst::getSwappedPredicate(CC);
+    std::swap(LHS, RHS);
+    return;
   }
 }
 
@@ -592,22 +597,17 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
   if (MaybeICMP && MaybeICMP->getOpcode() == TargetOpcode::G_ICMP) {
     // If MI is a G_SELECT(G_ICMP(tst, A, B), C, D) then we can use (A, B, tst)
     // as the (LHS, RHS, CC) of the Select_GPR_Using_CC_GPR.
-    MachineInstr *ICMPForBranch = createICMPForBranch(MaybeICMP, MIB, MRI);
-    CmpInst::Predicate CC = static_cast<CmpInst::Predicate>(
-        ICMPForBranch->getOperand(1).getPredicate());
+    CmpInst::Predicate CC;
+    MachineOperand LHS = MaybeICMP->getOperand(2);
+    MachineOperand RHS = MaybeICMP->getOperand(3);
+    setICMPOperandsForBranch(*MaybeICMP, MIB, MRI, CC, LHS, RHS);
     Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
                  .addDef(MI.getOperand(0).getReg());
-    Result->addOperand(ICMPForBranch->getOperand(2));
-    Result->addOperand(ICMPForBranch->getOperand(3));
-    Result->addOperand(
-        MachineOperand::CreateImm(getRISCVCCFromICMP(CC)));
+    Result->addOperand(LHS);
+    Result->addOperand(RHS);
+    Result->addOperand(MachineOperand::CreateImm(getRISCVCCFromICMP(CC)));
     Result->addOperand(MI.getOperand(2));
     Result->addOperand(MI.getOperand(3));
-
-    // Delete ICMPForBranch since we know it has no users. Let the original
-    // G_ICMP be selected normally in case it has other users.
-    if (ICMPForBranch != MaybeICMP)
-      ICMPForBranch->eraseFromParent();
   } else {
     Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
                  .addDef(MI.getOperand(0).getReg())

>From 1a572375c8265ef3c6d9297738bdd98e0727fbcc Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 4 Oct 2023 14:24:37 -0700
Subject: [PATCH 3/8] fixup! [RISCV][GISel] Select G_SELECT (G_ICMP, A, B)

Refactor NFC
---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 80 +++++++++----------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index dd0673d245978c0..1c27e28eb1de03f 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -83,13 +83,12 @@ class RISCVInstructionSelector : public InstructionSelector {
   void renderImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
                  int OpIdx) const;
 
-  /// Sets CC, LHS, and RHS so that they form an equivelent G_ICMP (CC, LHS,
+  /// Sets CC, LHS, and RHS so that they form an equivelent G_ICMP (ICMPCC, LHS,
   /// RHS) to that of MI, but whose condition code matches one of the
   /// comparisons supported directly by branches in the RISC-V ISA.
-  void setICMPOperandsForBranch(MachineInstr &MI, MachineIRBuilder &MIB,
-                                 MachineRegisterInfo &MRI,
-                                 CmpInst::Predicate &CC, MachineOperand &LHS,
-                                 MachineOperand &RHS) const;
+  void getICMPOperandsForBranch(MachineInstr &MI, MachineIRBuilder &MIB,
+                                MachineRegisterInfo &MRI, RISCVCC::CondCode &CC,
+                                Register &LHS, Register &RHS) const;
 
   const RISCVSubtarget &STI;
   const RISCVInstrInfo &TII;
@@ -527,26 +526,27 @@ static RISCVCC::CondCode getRISCVCCFromICMP(CmpInst::Predicate CC) {
   }
 }
 
-void RISCVInstructionSelector::setICMPOperandsForBranch(
+void RISCVInstructionSelector::getICMPOperandsForBranch(
     MachineInstr &MI, MachineIRBuilder &MIB, MachineRegisterInfo &MRI,
-    CmpInst::Predicate &CC, MachineOperand &LHS, MachineOperand &RHS) const {
+    RISCVCC::CondCode &CC, Register &LHS, Register &RHS) const {
   assert(MI.getOpcode() == TargetOpcode::G_ICMP);
-  CC = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
-  LHS = MI.getOperand(2);
-  RHS = MI.getOperand(3);
+  CmpInst::Predicate ICMPCC =
+      static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
+  LHS = MI.getOperand(2).getReg();
+  RHS = MI.getOperand(3).getReg();
 
   // Adjust comparisons to use comparison with 0 if possible.
-  MachineInstr *MaybeConstant = MRI.getVRegDef(RHS.getReg());
+  MachineInstr *MaybeConstant = MRI.getVRegDef(RHS);
   if (MaybeConstant && MaybeConstant->getOpcode() == TargetOpcode::G_CONSTANT) {
-    switch (CC) {
+    switch (ICMPCC) {
     case CmpInst::Predicate::ICMP_SGT:
       // Convert X > -1 to X >= 0
       if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == -1) {
         MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        CC = CmpInst::Predicate::ICMP_SGE;
-        RHS = MachineOperand::CreateReg(Zero->getOperand(0).getReg(), false);
+        CC = getRISCVCCFromICMP(CmpInst::Predicate::ICMP_SGE);
+        RHS = Zero->getOperand(0).getReg();
       }
       return;
     case CmpInst::Predicate::ICMP_SLT:
@@ -555,9 +555,9 @@ void RISCVInstructionSelector::setICMPOperandsForBranch(
         MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        CC =  CmpInst::Predicate::ICMP_SGE;
+        CC = getRISCVCCFromICMP(CmpInst::Predicate::ICMP_SGE);
         RHS = LHS;
-        LHS = MachineOperand::CreateReg(Zero->getOperand(0).getReg(), false);
+        LHS = Zero->getOperand(0).getReg();
       }
       return;
     default:
@@ -565,7 +565,7 @@ void RISCVInstructionSelector::setICMPOperandsForBranch(
     }
   }
 
-  switch (CC) {
+  switch (ICMPCC) {
   default:
     llvm_unreachable("Expected ICMP CmpInst::Predicate.");
   case CmpInst::Predicate::ICMP_EQ:
@@ -575,6 +575,7 @@ void RISCVInstructionSelector::setICMPOperandsForBranch(
   case CmpInst::Predicate::ICMP_UGE:
   case CmpInst::Predicate::ICMP_SGE:
     // These CCs are supported directly by RISC-V branches.
+    CC = getRISCVCCFromICMP(ICMPCC);
     return;
   case CmpInst::Predicate::ICMP_SGT:
   case CmpInst::Predicate::ICMP_SLE:
@@ -582,7 +583,7 @@ void RISCVInstructionSelector::setICMPOperandsForBranch(
   case CmpInst::Predicate::ICMP_ULE:
     // These CCs are not supported directly by RISC-V branches, but changing the
     // direction of the CC and swapping LHS and RHS are.
-    CC = CmpInst::getSwappedPredicate(CC);
+    CC = getRISCVCCFromICMP(CmpInst::getSwappedPredicate(ICMPCC));
     std::swap(LHS, RHS);
     return;
   }
@@ -592,31 +593,26 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
                                             MachineIRBuilder &MIB,
                                             MachineRegisterInfo &MRI) const {
   assert(MI.getOpcode() == TargetOpcode::G_SELECT);
-  MachineInstr *Result;
+
+  // If MI is a G_SELECT(G_ICMP(tst, A, B), C, D) then we can use (A, B, tst)
+  // as the (LHS, RHS, CC) of the Select_GPR_Using_CC_GPR.
   MachineInstr *MaybeICMP = MRI.getVRegDef(MI.getOperand(1).getReg());
-  if (MaybeICMP && MaybeICMP->getOpcode() == TargetOpcode::G_ICMP) {
-    // If MI is a G_SELECT(G_ICMP(tst, A, B), C, D) then we can use (A, B, tst)
-    // as the (LHS, RHS, CC) of the Select_GPR_Using_CC_GPR.
-    CmpInst::Predicate CC;
-    MachineOperand LHS = MaybeICMP->getOperand(2);
-    MachineOperand RHS = MaybeICMP->getOperand(3);
-    setICMPOperandsForBranch(*MaybeICMP, MIB, MRI, CC, LHS, RHS);
-    Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
-                 .addDef(MI.getOperand(0).getReg());
-    Result->addOperand(LHS);
-    Result->addOperand(RHS);
-    Result->addOperand(MachineOperand::CreateImm(getRISCVCCFromICMP(CC)));
-    Result->addOperand(MI.getOperand(2));
-    Result->addOperand(MI.getOperand(3));
-  } else {
-    Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
-                 .addDef(MI.getOperand(0).getReg())
-                 .addReg(MI.getOperand(1).getReg())
-                 .addReg(RISCV::X0)
-                 .addImm(RISCVCC::COND_NE)
-                 .addReg(MI.getOperand(2).getReg())
-                 .addReg(MI.getOperand(3).getReg());
-  }
+  bool Op1IsICMP = MaybeICMP && MaybeICMP->getOpcode() == TargetOpcode::G_ICMP;
+  RISCVCC::CondCode CC;
+  Register LHS, RHS;
+  if (Op1IsICMP)
+    getICMPOperandsForBranch(*MaybeICMP, MIB, MRI, CC, LHS, RHS);
+
+  Register Op1 = Op1IsICMP ? LHS : MI.getOperand(1).getReg();
+  Register Op2 = Op1IsICMP ? RHS : RISCV::X0;
+  unsigned Op3 = Op1IsICMP ? CC : RISCVCC::COND_NE;
+  MachineInstr *Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
+                             .addDef(MI.getOperand(0).getReg())
+                             .addReg(Op1)
+                             .addReg(Op2)
+                             .addImm(Op3)
+                             .addReg(MI.getOperand(2).getReg())
+                             .addReg(MI.getOperand(3).getReg());
   MI.eraseFromParent();
   return constrainSelectedInstRegOperands(*Result, TII, TRI, RBI);
 }

>From ecc4c5c6fa15ab8f3bc8222a12d84fc79b87902a Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 4 Oct 2023 14:47:02 -0700
Subject: [PATCH 4/8] fixup! [RISCV][GISel] Select G_SELECT (G_ICMP, A, B)

simplify cond code and fix returns
---
 .../Target/RISCV/GISel/RISCVInstructionSelector.cpp    | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 1c27e28eb1de03f..bbf9a6eb2bc86ae 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -545,21 +545,23 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
         MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        CC = getRISCVCCFromICMP(CmpInst::Predicate::ICMP_SGE);
+        CC = RISCVCC::COND_GE;
         RHS = Zero->getOperand(0).getReg();
+        return;
       }
-      return;
+      break;
     case CmpInst::Predicate::ICMP_SLT:
       // Convert X < 1 to 0 >= X
       if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == 1) {
         MachineInstr *Zero = MIB.buildConstant(
             MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
         selectConstant(*Zero, MIB, MRI);
-        CC = getRISCVCCFromICMP(CmpInst::Predicate::ICMP_SGE);
+        CC = RISCVCC::COND_GE;
         RHS = LHS;
         LHS = Zero->getOperand(0).getReg();
+        return;
       }
-      return;
+      break;
     default:
       break;
     }

>From 99a5521961d37d7b8e79da8d49c9688ca0d70939 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 4 Oct 2023 15:33:26 -0700
Subject: [PATCH 5/8] Use match to simplify checks

---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 20 +++++++++----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index bbf9a6eb2bc86ae..bb89211926f30cc 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -26,6 +26,7 @@
 #define DEBUG_TYPE "riscv-isel"
 
 using namespace llvm;
+using namespace MIPatternMatch;
 
 #define GET_GLOBALISEL_PREDICATE_BITSET
 #include "RISCVGenGlobalISel.inc"
@@ -536,14 +537,12 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
   RHS = MI.getOperand(3).getReg();
 
   // Adjust comparisons to use comparison with 0 if possible.
-  MachineInstr *MaybeConstant = MRI.getVRegDef(RHS);
-  if (MaybeConstant && MaybeConstant->getOpcode() == TargetOpcode::G_CONSTANT) {
+  if (auto Constant = matchConstant<int64_t>(RHS, MRI)) {
     switch (ICMPCC) {
     case CmpInst::Predicate::ICMP_SGT:
       // Convert X > -1 to X >= 0
-      if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == -1) {
-        MachineInstr *Zero = MIB.buildConstant(
-            MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
+      if (*Constant == -1) {
+        MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;
         RHS = Zero->getOperand(0).getReg();
@@ -552,9 +551,8 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
       break;
     case CmpInst::Predicate::ICMP_SLT:
       // Convert X < 1 to 0 >= X
-      if (MaybeConstant->getOperand(1).getCImm()->getSExtValue() == 1) {
-        MachineInstr *Zero = MIB.buildConstant(
-            MRI.getType(MaybeConstant->getOperand(0).getReg()), 0);
+      if (*Constant == 1) {
+        MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;
         RHS = LHS;
@@ -598,12 +596,12 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
 
   // If MI is a G_SELECT(G_ICMP(tst, A, B), C, D) then we can use (A, B, tst)
   // as the (LHS, RHS, CC) of the Select_GPR_Using_CC_GPR.
-  MachineInstr *MaybeICMP = MRI.getVRegDef(MI.getOperand(1).getReg());
-  bool Op1IsICMP = MaybeICMP && MaybeICMP->getOpcode() == TargetOpcode::G_ICMP;
+  Register MIOp1Reg = MI.getOperand(1).getReg();
+  bool Op1IsICMP = mi_match(MIOp1Reg, MRI, m_GICmp(m_Pred(), m_Reg(), m_Reg()));
   RISCVCC::CondCode CC;
   Register LHS, RHS;
   if (Op1IsICMP)
-    getICMPOperandsForBranch(*MaybeICMP, MIB, MRI, CC, LHS, RHS);
+    getICMPOperandsForBranch(*MRI.getVRegDef(MIOp1Reg), MIB, MRI, CC, LHS, RHS);
 
   Register Op1 = Op1IsICMP ? LHS : MI.getOperand(1).getReg();
   Register Op2 = Op1IsICMP ? RHS : RISCV::X0;

>From 0e1d1d73be83d42cc574b0b7558d04799badc76f Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Wed, 4 Oct 2023 15:42:34 -0700
Subject: [PATCH 6/8] Use mICst

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index bb89211926f30cc..e5274d6414c5b07 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -537,11 +537,12 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
   RHS = MI.getOperand(3).getReg();
 
   // Adjust comparisons to use comparison with 0 if possible.
-  if (auto Constant = matchConstant<int64_t>(RHS, MRI)) {
+  int64_t Constant;
+  if (mi_match(RHS, MRI, m_ICst(Constant))) {
     switch (ICMPCC) {
     case CmpInst::Predicate::ICMP_SGT:
       // Convert X > -1 to X >= 0
-      if (*Constant == -1) {
+      if (Constant == -1) {
         MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;
@@ -551,7 +552,7 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
       break;
     case CmpInst::Predicate::ICMP_SLT:
       // Convert X < 1 to 0 >= X
-      if (*Constant == 1) {
+      if (Constant == 1) {
         MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;

>From 9408b96fe3d75965d4d244ae64963fb6eeb9f3b7 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Thu, 5 Oct 2023 07:24:37 -0700
Subject: [PATCH 7/8] Use getIConstantVRegSExtVal

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index e5274d6414c5b07..d7aa46fbb76eeeb 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -537,12 +537,11 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
   RHS = MI.getOperand(3).getReg();
 
   // Adjust comparisons to use comparison with 0 if possible.
-  int64_t Constant;
-  if (mi_match(RHS, MRI, m_ICst(Constant))) {
+  if (auto Constant = getIConstantVRegSExtVal(RHS, MRI)) {
     switch (ICMPCC) {
     case CmpInst::Predicate::ICMP_SGT:
       // Convert X > -1 to X >= 0
-      if (Constant == -1) {
+      if (*Constant == -1) {
         MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;
@@ -552,7 +551,7 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
       break;
     case CmpInst::Predicate::ICMP_SLT:
       // Convert X < 1 to 0 >= X
-      if (Constant == 1) {
+      if (*Constant == 1) {
         MachineInstr *Zero = MIB.buildConstant(MRI.getType(RHS), 0);
         selectConstant(*Zero, MIB, MRI);
         CC = RISCVCC::COND_GE;

>From e6fbfc9246fe1c870da9cfc4f68220e00bdfa6c7 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Thu, 5 Oct 2023 09:04:54 -0700
Subject: [PATCH 8/8] Use LookThroughInstrs

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index d7aa46fbb76eeeb..a7f18c04a190790 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -537,7 +537,7 @@ void RISCVInstructionSelector::getICMPOperandsForBranch(
   RHS = MI.getOperand(3).getReg();
 
   // Adjust comparisons to use comparison with 0 if possible.
-  if (auto Constant = getIConstantVRegSExtVal(RHS, MRI)) {
+  if (auto Constant = getIConstantVRegSExtVal(RHS, MRI, true)) {
     switch (ICMPCC) {
     case CmpInst::Predicate::ICMP_SGT:
       // Convert X > -1 to X >= 0



More information about the llvm-commits mailing list