@@ -296,6 +296,92 @@ RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const {
296
296
[=](MachineInstrBuilder &MIB) { MIB.addImm (0 ); }}};
297
297
}
298
298
299
+ // / Returns the RISCVCC::CondCode that corresponds to the CmpInst::Predicate CC.
300
+ // / CC Must be an ICMP Predicate.
301
+ static RISCVCC::CondCode getRISCVCCFromICmp (CmpInst::Predicate CC) {
302
+ switch (CC) {
303
+ default :
304
+ llvm_unreachable (" Expected ICMP CmpInst::Predicate." );
305
+ case CmpInst::Predicate::ICMP_EQ:
306
+ return RISCVCC::COND_EQ;
307
+ case CmpInst::Predicate::ICMP_NE:
308
+ return RISCVCC::COND_NE;
309
+ case CmpInst::Predicate::ICMP_ULT:
310
+ return RISCVCC::COND_LTU;
311
+ case CmpInst::Predicate::ICMP_SLT:
312
+ return RISCVCC::COND_LT;
313
+ case CmpInst::Predicate::ICMP_UGE:
314
+ return RISCVCC::COND_GEU;
315
+ case CmpInst::Predicate::ICMP_SGE:
316
+ return RISCVCC::COND_GE;
317
+ }
318
+ }
319
+
320
+ static void getOperandsForBranch (Register CondReg, MachineRegisterInfo &MRI,
321
+ RISCVCC::CondCode &CC, Register &LHS,
322
+ Register &RHS) {
323
+ // Try to fold an ICmp. If that fails, use a NE compare with X0.
324
+ CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
325
+ if (!mi_match (CondReg, MRI, m_GICmp (m_Pred (Pred), m_Reg (LHS), m_Reg (RHS)))) {
326
+ LHS = CondReg;
327
+ RHS = RISCV::X0;
328
+ CC = RISCVCC::COND_NE;
329
+ return ;
330
+ }
331
+
332
+ // We found an ICmp, do some canonicalizations.
333
+
334
+ // Adjust comparisons to use comparison with 0 if possible.
335
+ if (auto Constant = getIConstantVRegSExtVal (RHS, MRI)) {
336
+ switch (Pred) {
337
+ case CmpInst::Predicate::ICMP_SGT:
338
+ // Convert X > -1 to X >= 0
339
+ if (*Constant == -1 ) {
340
+ CC = RISCVCC::COND_GE;
341
+ RHS = RISCV::X0;
342
+ return ;
343
+ }
344
+ break ;
345
+ case CmpInst::Predicate::ICMP_SLT:
346
+ // Convert X < 1 to 0 >= X
347
+ if (*Constant == 1 ) {
348
+ CC = RISCVCC::COND_GE;
349
+ RHS = LHS;
350
+ LHS = RISCV::X0;
351
+ return ;
352
+ }
353
+ break ;
354
+ default :
355
+ break ;
356
+ }
357
+ }
358
+
359
+ switch (Pred) {
360
+ default :
361
+ llvm_unreachable (" Expected ICMP CmpInst::Predicate." );
362
+ case CmpInst::Predicate::ICMP_EQ:
363
+ case CmpInst::Predicate::ICMP_NE:
364
+ case CmpInst::Predicate::ICMP_ULT:
365
+ case CmpInst::Predicate::ICMP_SLT:
366
+ case CmpInst::Predicate::ICMP_UGE:
367
+ case CmpInst::Predicate::ICMP_SGE:
368
+ // These CCs are supported directly by RISC-V branches.
369
+ break ;
370
+ case CmpInst::Predicate::ICMP_SGT:
371
+ case CmpInst::Predicate::ICMP_SLE:
372
+ case CmpInst::Predicate::ICMP_UGT:
373
+ case CmpInst::Predicate::ICMP_ULE:
374
+ // These CCs are not supported directly by RISC-V branches, but changing the
375
+ // direction of the CC and swapping LHS and RHS are.
376
+ Pred = CmpInst::getSwappedPredicate (Pred);
377
+ std::swap (LHS, RHS);
378
+ break ;
379
+ }
380
+
381
+ CC = getRISCVCCFromICmp (Pred);
382
+ return ;
383
+ }
384
+
299
385
bool RISCVInstructionSelector::select (MachineInstr &MI) {
300
386
MachineBasicBlock &MBB = *MI.getParent ();
301
387
MachineFunction &MF = *MBB.getParent ();
@@ -398,10 +484,12 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
398
484
case TargetOpcode::G_GLOBAL_VALUE:
399
485
return selectGlobalValue (MI, MIB, MRI);
400
486
case TargetOpcode::G_BRCOND: {
401
- // TODO: Fold with G_ICMP.
402
- auto Bcc =
403
- MIB.buildInstr (RISCV::BNE, {}, {MI.getOperand (0 ), Register (RISCV::X0)})
404
- .addMBB (MI.getOperand (1 ).getMBB ());
487
+ Register LHS, RHS;
488
+ RISCVCC::CondCode CC;
489
+ getOperandsForBranch (MI.getOperand (0 ).getReg (), MRI, CC, LHS, RHS);
490
+
491
+ auto Bcc = MIB.buildInstr (RISCVCC::getBrCond (CC), {}, {LHS, RHS})
492
+ .addMBB (MI.getOperand (1 ).getMBB ());
405
493
MI.eraseFromParent ();
406
494
return constrainSelectedInstRegOperands (*Bcc, TII, TRI, RBI);
407
495
}
@@ -719,101 +807,14 @@ bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
719
807
return true ;
720
808
}
721
809
722
- // / Returns the RISCVCC::CondCode that corresponds to the CmpInst::Predicate CC.
723
- // / CC Must be an ICMP Predicate.
724
- static RISCVCC::CondCode getRISCVCCFromICMP (CmpInst::Predicate CC) {
725
- switch (CC) {
726
- default :
727
- llvm_unreachable (" Expected ICMP CmpInst::Predicate." );
728
- case CmpInst::Predicate::ICMP_EQ:
729
- return RISCVCC::COND_EQ;
730
- case CmpInst::Predicate::ICMP_NE:
731
- return RISCVCC::COND_NE;
732
- case CmpInst::Predicate::ICMP_ULT:
733
- return RISCVCC::COND_LTU;
734
- case CmpInst::Predicate::ICMP_SLT:
735
- return RISCVCC::COND_LT;
736
- case CmpInst::Predicate::ICMP_UGE:
737
- return RISCVCC::COND_GEU;
738
- case CmpInst::Predicate::ICMP_SGE:
739
- return RISCVCC::COND_GE;
740
- }
741
- }
742
-
743
- static void getOperandsForBranch (Register CondReg, MachineIRBuilder &MIB,
744
- MachineRegisterInfo &MRI,
745
- RISCVCC::CondCode &CC, Register &LHS,
746
- Register &RHS) {
747
- // Try to fold an ICmp. If that fails, use a NE compare with X0.
748
- CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
749
- if (!mi_match (CondReg, MRI, m_GICmp (m_Pred (Pred), m_Reg (LHS), m_Reg (RHS)))) {
750
- LHS = CondReg;
751
- RHS = RISCV::X0;
752
- CC = RISCVCC::COND_NE;
753
- return ;
754
- }
755
-
756
- // We found an ICmp, do some canonicalizations.
757
-
758
- // Adjust comparisons to use comparison with 0 if possible.
759
- if (auto Constant = getIConstantVRegSExtVal (RHS, MRI)) {
760
- switch (Pred) {
761
- case CmpInst::Predicate::ICMP_SGT:
762
- // Convert X > -1 to X >= 0
763
- if (*Constant == -1 ) {
764
- CC = RISCVCC::COND_GE;
765
- RHS = RISCV::X0;
766
- return ;
767
- }
768
- break ;
769
- case CmpInst::Predicate::ICMP_SLT:
770
- // Convert X < 1 to 0 >= X
771
- if (*Constant == 1 ) {
772
- CC = RISCVCC::COND_GE;
773
- RHS = LHS;
774
- LHS = RISCV::X0;
775
- return ;
776
- }
777
- break ;
778
- default :
779
- break ;
780
- }
781
- }
782
-
783
- switch (Pred) {
784
- default :
785
- llvm_unreachable (" Expected ICMP CmpInst::Predicate." );
786
- case CmpInst::Predicate::ICMP_EQ:
787
- case CmpInst::Predicate::ICMP_NE:
788
- case CmpInst::Predicate::ICMP_ULT:
789
- case CmpInst::Predicate::ICMP_SLT:
790
- case CmpInst::Predicate::ICMP_UGE:
791
- case CmpInst::Predicate::ICMP_SGE:
792
- // These CCs are supported directly by RISC-V branches.
793
- break ;
794
- case CmpInst::Predicate::ICMP_SGT:
795
- case CmpInst::Predicate::ICMP_SLE:
796
- case CmpInst::Predicate::ICMP_UGT:
797
- case CmpInst::Predicate::ICMP_ULE:
798
- // These CCs are not supported directly by RISC-V branches, but changing the
799
- // direction of the CC and swapping LHS and RHS are.
800
- Pred = CmpInst::getSwappedPredicate (Pred);
801
- std::swap (LHS, RHS);
802
- break ;
803
- }
804
-
805
- CC = getRISCVCCFromICMP (Pred);
806
- return ;
807
- }
808
-
809
810
bool RISCVInstructionSelector::selectSelect (MachineInstr &MI,
810
811
MachineIRBuilder &MIB,
811
812
MachineRegisterInfo &MRI) const {
812
813
auto &SelectMI = cast<GSelect>(MI);
813
814
814
815
Register LHS, RHS;
815
816
RISCVCC::CondCode CC;
816
- getOperandsForBranch (SelectMI.getCondReg (), MIB, MRI, CC, LHS, RHS);
817
+ getOperandsForBranch (SelectMI.getCondReg (), MRI, CC, LHS, RHS);
817
818
818
819
MachineInstr *Result = MIB.buildInstr (RISCV::Select_GPR_Using_CC_GPR)
819
820
.addDef (SelectMI.getReg (0 ))
0 commit comments