llvm.org GIT mirror llvm / 2597299
[GlobalISel][AArch64] Select CBZ. CBZ/CBNZ represent a substantial portion of all conditional branches. Look through G_ICMP to select them. We can't use tablegen yet because the existing patterns match an AArch64ISD node. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298856 91177308-0d34-0410-b5e6-96231b3b80d8 Ahmed Bougacha 3 years ago
3 changed file(s) with 161 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
447447 }
448448 }
449449
450 bool AArch64InstructionSelector::selectCompareBranch(
451 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
452
453 const unsigned CondReg = I.getOperand(0).getReg();
454 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
455 MachineInstr *CCMI = MRI.getVRegDef(CondReg);
456 if (CCMI->getOpcode() != TargetOpcode::G_ICMP)
457 return false;
458
459 unsigned LHS = CCMI->getOperand(2).getReg();
460 unsigned RHS = CCMI->getOperand(3).getReg();
461 if (!getConstantVRegVal(RHS, MRI))
462 std::swap(RHS, LHS);
463
464 const auto RHSImm = getConstantVRegVal(RHS, MRI);
465 if (!RHSImm || *RHSImm != 0)
466 return false;
467
468 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI);
469 if (RB.getID() != AArch64::GPRRegBankID)
470 return false;
471
472 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate();
473 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ)
474 return false;
475
476 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits();
477 unsigned CBOpc = 0;
478 if (CmpWidth <= 32)
479 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW);
480 else if (CmpWidth == 64)
481 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX);
482 else
483 return false;
484
485 auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc))
486 .addUse(LHS)
487 .addMBB(DestMBB);
488
489 constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
490 I.eraseFromParent();
491 return true;
492 }
493
450494 bool AArch64InstructionSelector::selectVaStartAAPCS(
451495 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const {
452496 return false;
554598
555599 const unsigned CondReg = I.getOperand(0).getReg();
556600 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
601
602 if (selectCompareBranch(I, MF, MRI))
603 return true;
557604
558605 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW))
559606 .addUse(CondReg)
3939 bool select(MachineInstr &I) const override;
4040
4141 private:
42 /// tblgen-erated 'select' implementation, used as the initial selector for
43 /// the patterns that don't require complex C++.
44 bool selectImpl(MachineInstr &I) const;
45
4246 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF,
4347 MachineRegisterInfo &MRI) const;
4448 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF,
4549 MachineRegisterInfo &MRI) const;
4650
47 /// tblgen-erated 'select' implementation, used as the initial selector for
48 /// the patterns that don't require complex C++.
49 bool selectImpl(MachineInstr &I) const;
51 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF,
52 MachineRegisterInfo &MRI) const;
5053
5154 bool selectArithImmed(MachineOperand &Root, MachineOperand &Result1,
5255 MachineOperand &Result2) const;
0 # RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s
1
2 --- |
3 define void @cbz_s32() { ret void }
4 define void @cbz_s64() { ret void }
5 define void @cbnz_s32() { ret void }
6 define void @cbnz_s64() { ret void }
7 ...
8
9 ---
10 # CHECK-LABEL: name: cbz_s32
11 name: cbz_s32
12 legalized: true
13 regBankSelected: true
14
15 # CHECK: body:
16 # CHECK: bb.0:
17 # CHECK: %0 = COPY %w0
18 # CHECK: CBZW %0, %bb.1
19 # CHECK: B %bb.0
20 body: |
21 bb.0:
22 liveins: %w0
23 successors: %bb.0, %bb.1
24
25 %0:gpr(s32) = COPY %w0
26 %1:gpr(s32) = G_CONSTANT i32 0
27 %2:gpr(s1) = G_ICMP intpred(eq), %0, %1
28 G_BRCOND %2(s1), %bb.1
29 G_BR %bb.0
30
31 bb.1:
32 ...
33
34 ---
35 # CHECK-LABEL: name: cbz_s64
36 name: cbz_s64
37 legalized: true
38 regBankSelected: true
39
40 # CHECK: body:
41 # CHECK: bb.0:
42 # CHECK: %0 = COPY %x0
43 # CHECK: CBZX %0, %bb.1
44 # CHECK: B %bb.0
45 body: |
46 bb.0:
47 liveins: %x0
48 successors: %bb.0, %bb.1
49
50 %0:gpr(s64) = COPY %x0
51 %1:gpr(s64) = G_CONSTANT i64 0
52 %2:gpr(s1) = G_ICMP intpred(eq), %0, %1
53 G_BRCOND %2(s1), %bb.1
54 G_BR %bb.0
55
56 bb.1:
57 ...
58
59 ---
60 # CHECK-LABEL: name: cbnz_s32
61 name: cbnz_s32
62 legalized: true
63 regBankSelected: true
64
65 # CHECK: body:
66 # CHECK: bb.0:
67 # CHECK: %0 = COPY %w0
68 # CHECK: CBNZW %0, %bb.1
69 # CHECK: B %bb.0
70 body: |
71 bb.0:
72 liveins: %w0
73 successors: %bb.0, %bb.1
74
75 %0:gpr(s32) = COPY %w0
76 %1:gpr(s32) = G_CONSTANT i32 0
77 %2:gpr(s1) = G_ICMP intpred(ne), %0, %1
78 G_BRCOND %2(s1), %bb.1
79 G_BR %bb.0
80
81 bb.1:
82 ...
83
84 ---
85 # CHECK-LABEL: name: cbnz_s64
86 name: cbnz_s64
87 legalized: true
88 regBankSelected: true
89
90 # CHECK: body:
91 # CHECK: bb.0:
92 # CHECK: %0 = COPY %x0
93 # CHECK: CBNZX %0, %bb.1
94 # CHECK: B %bb.0
95 body: |
96 bb.0:
97 liveins: %x0
98 successors: %bb.0, %bb.1
99
100 %0:gpr(s64) = COPY %x0
101 %1:gpr(s64) = G_CONSTANT i64 0
102 %2:gpr(s1) = G_ICMP intpred(ne), %0, %1
103 G_BRCOND %2(s1), %bb.1
104 G_BR %bb.0
105
106 bb.1:
107 ...