Skip to content

Commit 4cf08f6

Browse files
committed
[RISCV][CodeGen] Add CodeGen support of Zibi experimental extension
1 parent aea8133 commit 4cf08f6

File tree

7 files changed

+231
-11
lines changed

7 files changed

+231
-11
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
789789
RISCVCC::CondCode CC;
790790
getOperandsForBranch(MI.getOperand(0).getReg(), CC, LHS, RHS, *MRI);
791791

792-
auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(CC), {}, {LHS, RHS})
792+
auto Bcc = MIB.buildInstr(RISCVCC::getBrCond(*Subtarget, CC), {}, {LHS, RHS})
793793
.addMBB(MI.getOperand(1).getMBB());
794794
MI.eraseFromParent();
795795
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
196196
CC = RISCVCC::getOppositeBranchCondition(CC);
197197

198198
// Insert branch instruction.
199-
BuildMI(MBB, MBBI, DL, TII->get(RISCVCC::getBrCond(CC)))
199+
BuildMI(MBB, MBBI, DL, TII->get(RISCVCC::getBrCond(*STI, CC)))
200200
.addReg(MI.getOperand(1).getReg())
201201
.addReg(MI.getOperand(2).getReg())
202202
.addMBB(MergeBB);

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21388,7 +21388,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
2138821388
Register FLHS = First.getOperand(1).getReg();
2138921389
Register FRHS = First.getOperand(2).getReg();
2139021390
// Insert appropriate branch.
21391-
BuildMI(FirstMBB, DL, TII.get(RISCVCC::getBrCond(FirstCC, First.getOpcode())))
21391+
BuildMI(FirstMBB, DL, TII.get(RISCVCC::getBrCond(Subtarget, FirstCC, First.getOpcode())))
2139221392
.addReg(FLHS)
2139321393
.addReg(FRHS)
2139421394
.addMBB(SinkMBB);
@@ -21401,7 +21401,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
2140121401
auto SecondCC = static_cast<RISCVCC::CondCode>(Second.getOperand(3).getImm());
2140221402
// Insert appropriate branch.
2140321403
BuildMI(ThisMBB, DL,
21404-
TII.get(RISCVCC::getBrCond(SecondCC, Second.getOpcode())))
21404+
TII.get(RISCVCC::getBrCond(Subtarget, SecondCC, Second.getOpcode())))
2140521405
.addReg(SLHS)
2140621406
.addReg(SRHS)
2140721407
.addMBB(SinkMBB);
@@ -21536,12 +21536,12 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
2153621536

2153721537
// Insert appropriate branch.
2153821538
if (MI.getOperand(2).isImm())
21539-
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
21539+
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode(), true)))
2154021540
.addReg(LHS)
2154121541
.addImm(MI.getOperand(2).getImm())
2154221542
.addMBB(TailMBB);
2154321543
else
21544-
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
21544+
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode())))
2154521545
.addReg(LHS)
2154621546
.addReg(RHS)
2154721547
.addMBB(TailMBB);

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -961,11 +961,13 @@ RISCVCC::CondCode RISCVInstrInfo::getCondFromBranchOpc(unsigned Opc) {
961961
default:
962962
return RISCVCC::COND_INVALID;
963963
case RISCV::BEQ:
964+
case RISCV::BEQI:
964965
case RISCV::CV_BEQIMM:
965966
case RISCV::QC_BEQI:
966967
case RISCV::QC_E_BEQI:
967968
return RISCVCC::COND_EQ;
968969
case RISCV::BNE:
970+
case RISCV::BNEI:
969971
case RISCV::QC_BNEI:
970972
case RISCV::QC_E_BNEI:
971973
case RISCV::CV_BNEIMM:
@@ -1023,16 +1025,16 @@ static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
10231025
Cond.push_back(LastInst.getOperand(1));
10241026
}
10251027

1026-
unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC, unsigned SelectOpc) {
1028+
unsigned RISCVCC::getBrCond(const RISCVSubtarget &STI, CondCode CC, unsigned SelectOpc, bool Imm) {
10271029
switch (SelectOpc) {
10281030
default:
10291031
switch (CC) {
10301032
default:
10311033
llvm_unreachable("Unexpected condition code!");
10321034
case RISCVCC::COND_EQ:
1033-
return RISCV::BEQ;
1035+
return (Imm && STI.hasStdExtZibi()) ? RISCV::BEQI : RISCV::BEQ;
10341036
case RISCVCC::COND_NE:
1035-
return RISCV::BNE;
1037+
return (Imm && STI.hasStdExtZibi()) ? RISCV::BNEI : RISCV::BNE;
10361038
case RISCVCC::COND_LT:
10371039
return RISCV::BLT;
10381040
case RISCVCC::COND_GE:
@@ -1341,9 +1343,15 @@ bool RISCVInstrInfo::reverseBranchCondition(
13411343
case RISCV::BEQ:
13421344
Cond[0].setImm(RISCV::BNE);
13431345
break;
1346+
case RISCV::BEQI:
1347+
Cond[0].setImm(RISCV::BNEI);
1348+
break;
13441349
case RISCV::BNE:
13451350
Cond[0].setImm(RISCV::BEQ);
13461351
break;
1352+
case RISCV::BNEI:
1353+
Cond[0].setImm(RISCV::BEQI);
1354+
break;
13471355
case RISCV::BLT:
13481356
Cond[0].setImm(RISCV::BGE);
13491357
break;
@@ -1506,7 +1514,7 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
15061514
return Register();
15071515
};
15081516

1509-
unsigned NewOpc = RISCVCC::getBrCond(getOppositeBranchCondition(CC));
1517+
unsigned NewOpc = RISCVCC::getBrCond(STI, getOppositeBranchCondition(CC));
15101518

15111519
// Might be case 1.
15121520
// Don't change 0 to 1 since we can use x0.
@@ -1576,6 +1584,8 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
15761584
case RISCV::BGE:
15771585
case RISCV::BLTU:
15781586
case RISCV::BGEU:
1587+
case RISCV::BEQI:
1588+
case RISCV::BNEI:
15791589
case RISCV::CV_BEQIMM:
15801590
case RISCV::CV_BNEIMM:
15811591
case RISCV::QC_BEQI:
@@ -2775,6 +2785,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
27752785
case RISCVOp::OPERAND_UIMM2_LSB0:
27762786
Ok = isShiftedUInt<1, 1>(Imm);
27772787
break;
2788+
case RISCVOp::OPERAND_UIMM5_ZIBI:
2789+
Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
2790+
break;
27782791
case RISCVOp::OPERAND_UIMM5_LSB0:
27792792
Ok = isShiftedUInt<4, 1>(Imm);
27802793
break;

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ enum CondCode {
4545
};
4646

4747
CondCode getOppositeBranchCondition(CondCode);
48-
unsigned getBrCond(CondCode CC, unsigned SelectOpc = 0);
48+
unsigned getBrCond(const RISCVSubtarget &STI, CondCode CC, unsigned SelectOpc = 0, bool Imm = false);
4949

5050
} // end of namespace RISCVCC
5151

llvm/lib/Target/RISCV/RISCVInstrInfoZibi.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,13 @@ class Branch_imm<bits<3> funct3, string opcodestr>
3939
let Predicates = [HasStdExtZibi] in {
4040
def BEQI : Branch_imm<0b010, "beqi">;
4141
def BNEI : Branch_imm<0b011, "bnei">;
42+
} // Predicates = [HasStdExtZibi]
43+
44+
let Predicates = [HasStdExtZibi] in {
45+
multiclass BccImmPat<CondCode Cond, Branch_imm Inst> {
46+
def : Pat<(riscv_brcc(XLenVT GPR:$rs1), uimm5_zibi:$cimm, Cond, bb:$imm12),
47+
(Inst GPR:$rs1, uimm5_zibi:$cimm, bare_simm13_lsb0_bb:$imm12)>;
48+
}
49+
defm : BccImmPat<SETEQ, BEQI>;
50+
defm : BccImmPat<SETNE, BNEI>;
4251
} // Predicates = [HasStdExtZibi]

llvm/test/CodeGen/RISCV/zibi.ll

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zibi -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=ZIBI %s
4+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibi -verify-machineinstrs < %s \
5+
; RUN: | FileCheck -check-prefix=ZIBI %s
6+
7+
define void @test_bne_neg(ptr %b) nounwind {
8+
; ZIBI-LABEL: test_bne_neg:
9+
; ZIBI: # %bb.0:
10+
; ZIBI-NEXT: lw a1, 0(a0)
11+
; ZIBI-NEXT: bnei a1, -1, .LBB0_2
12+
; ZIBI-NEXT: # %bb.1: # %test2
13+
; ZIBI-NEXT: lw zero, 0(a0)
14+
; ZIBI-NEXT: .LBB0_2: # %end
15+
; ZIBI-NEXT: ret
16+
%val1 = load volatile i32, ptr %b
17+
%tst1 = icmp ne i32 %val1, -1
18+
br i1 %tst1, label %end, label %test2, !prof !0
19+
test2:
20+
%val2 = load volatile i32, ptr %b
21+
br label %end
22+
end:
23+
ret void
24+
}
25+
26+
define void @test_beq_neg(ptr %b) nounwind {
27+
; ZIBI-LABEL: test_beq_neg:
28+
; ZIBI: # %bb.0:
29+
; ZIBI-NEXT: lw a1, 0(a0)
30+
; ZIBI-NEXT: beqi a1, -1, .LBB1_2
31+
; ZIBI-NEXT: # %bb.1: # %test2
32+
; ZIBI-NEXT: lw zero, 0(a0)
33+
; ZIBI-NEXT: .LBB1_2: # %end
34+
; ZIBI-NEXT: ret
35+
%val1 = load volatile i32, ptr %b
36+
%tst1 = icmp eq i32 %val1, -1
37+
br i1 %tst1, label %end, label %test2, !prof !0
38+
test2:
39+
%val2 = load volatile i32, ptr %b
40+
br label %end
41+
end:
42+
ret void
43+
}
44+
45+
define void @test_bne_zero(ptr %b) nounwind {
46+
; ZIBI-LABEL: test_bne_zero:
47+
; ZIBI: # %bb.0:
48+
; ZIBI-NEXT: lw a1, 0(a0)
49+
; ZIBI-NEXT: bnez a1, .LBB2_2
50+
; ZIBI-NEXT: # %bb.1: # %test2
51+
; ZIBI-NEXT: lw zero, 0(a0)
52+
; ZIBI-NEXT: .LBB2_2: # %end
53+
; ZIBI-NEXT: ret
54+
%val1 = load volatile i32, ptr %b
55+
%tst1 = icmp ne i32 %val1, 0
56+
br i1 %tst1, label %end, label %test2, !prof !0
57+
test2:
58+
%val2 = load volatile i32, ptr %b
59+
br label %end
60+
end:
61+
ret void
62+
}
63+
64+
define void @test_beq_zero(ptr %b) nounwind {
65+
; ZIBI-LABEL: test_beq_zero:
66+
; ZIBI: # %bb.0:
67+
; ZIBI-NEXT: lw a1, 0(a0)
68+
; ZIBI-NEXT: beqz a1, .LBB3_2
69+
; ZIBI-NEXT: # %bb.1: # %test2
70+
; ZIBI-NEXT: lw zero, 0(a0)
71+
; ZIBI-NEXT: .LBB3_2: # %end
72+
; ZIBI-NEXT: ret
73+
%val1 = load volatile i32, ptr %b
74+
%tst1 = icmp eq i32 %val1, 0
75+
br i1 %tst1, label %end, label %test2, !prof !0
76+
test2:
77+
%val2 = load volatile i32, ptr %b
78+
br label %end
79+
end:
80+
ret void
81+
}
82+
83+
define void @test_bne_1(ptr %b) nounwind {
84+
; ZIBI-LABEL: test_bne_1:
85+
; ZIBI: # %bb.0:
86+
; ZIBI-NEXT: lw a1, 0(a0)
87+
; ZIBI-NEXT: bnei a1, 1, .LBB4_2
88+
; ZIBI-NEXT: # %bb.1: # %test2
89+
; ZIBI-NEXT: lw zero, 0(a0)
90+
; ZIBI-NEXT: .LBB4_2: # %end
91+
; ZIBI-NEXT: ret
92+
%val1 = load volatile i32, ptr %b
93+
%tst1 = icmp ne i32 %val1, 1
94+
br i1 %tst1, label %end, label %test2, !prof !0
95+
test2:
96+
%val2 = load volatile i32, ptr %b
97+
br label %end
98+
end:
99+
ret void
100+
}
101+
102+
define void @test_beq_1(ptr %b) nounwind {
103+
; ZIBI-LABEL: test_beq_1:
104+
; ZIBI: # %bb.0:
105+
; ZIBI-NEXT: lw a1, 0(a0)
106+
; ZIBI-NEXT: beqi a1, 1, .LBB5_2
107+
; ZIBI-NEXT: # %bb.1: # %test2
108+
; ZIBI-NEXT: lw zero, 0(a0)
109+
; ZIBI-NEXT: .LBB5_2: # %end
110+
; ZIBI-NEXT: ret
111+
%val1 = load volatile i32, ptr %b
112+
%tst1 = icmp eq i32 %val1, 1
113+
br i1 %tst1, label %end, label %test2, !prof !0
114+
test2:
115+
%val2 = load volatile i32, ptr %b
116+
br label %end
117+
end:
118+
ret void
119+
}
120+
121+
define void @test_bne_31(ptr %b) nounwind {
122+
; ZIBI-LABEL: test_bne_31:
123+
; ZIBI: # %bb.0:
124+
; ZIBI-NEXT: lw a1, 0(a0)
125+
; ZIBI-NEXT: bnei a1, 31, .LBB6_2
126+
; ZIBI-NEXT: # %bb.1: # %test2
127+
; ZIBI-NEXT: lw zero, 0(a0)
128+
; ZIBI-NEXT: .LBB6_2: # %end
129+
; ZIBI-NEXT: ret
130+
%val1 = load volatile i32, ptr %b
131+
%tst1 = icmp ne i32 %val1, 31
132+
br i1 %tst1, label %end, label %test2, !prof !0
133+
test2:
134+
%val2 = load volatile i32, ptr %b
135+
br label %end
136+
end:
137+
ret void
138+
}
139+
140+
define void @test_beq_31(ptr %b) nounwind {
141+
; ZIBI-LABEL: test_beq_31:
142+
; ZIBI: # %bb.0:
143+
; ZIBI-NEXT: lw a1, 0(a0)
144+
; ZIBI-NEXT: beqi a1, 1, .LBB7_2
145+
; ZIBI-NEXT: # %bb.1: # %test2
146+
; ZIBI-NEXT: lw zero, 0(a0)
147+
; ZIBI-NEXT: .LBB7_2: # %end
148+
; ZIBI-NEXT: ret
149+
%val1 = load volatile i32, ptr %b
150+
%tst1 = icmp eq i32 %val1, 1
151+
br i1 %tst1, label %end, label %test2, !prof !0
152+
test2:
153+
%val2 = load volatile i32, ptr %b
154+
br label %end
155+
end:
156+
ret void
157+
}
158+
159+
define void @test_bne_32(ptr %b) nounwind {
160+
; ZIBI-LABEL: test_bne_32:
161+
; ZIBI: # %bb.0:
162+
; ZIBI-NEXT: lw a1, 0(a0)
163+
; ZIBI-NEXT: li a2, 32
164+
; ZIBI-NEXT: bne a1, a2, .LBB8_2
165+
; ZIBI-NEXT: # %bb.1: # %test2
166+
; ZIBI-NEXT: lw zero, 0(a0)
167+
; ZIBI-NEXT: .LBB8_2: # %end
168+
; ZIBI-NEXT: ret
169+
%val1 = load volatile i32, ptr %b
170+
%tst1 = icmp ne i32 %val1, 32
171+
br i1 %tst1, label %end, label %test2, !prof !0
172+
test2:
173+
%val2 = load volatile i32, ptr %b
174+
br label %end
175+
end:
176+
ret void
177+
}
178+
179+
define void @test_beq_32(ptr %b) nounwind {
180+
; ZIBI-LABEL: test_beq_32:
181+
; ZIBI: # %bb.0:
182+
; ZIBI-NEXT: lw a1, 0(a0)
183+
; ZIBI-NEXT: li a2, 32
184+
; ZIBI-NEXT: beq a1, a2, .LBB9_2
185+
; ZIBI-NEXT: # %bb.1: # %test2
186+
; ZIBI-NEXT: lw zero, 0(a0)
187+
; ZIBI-NEXT: .LBB9_2: # %end
188+
; ZIBI-NEXT: ret
189+
%val1 = load volatile i32, ptr %b
190+
%tst1 = icmp eq i32 %val1, 32
191+
br i1 %tst1, label %end, label %test2, !prof !0
192+
test2:
193+
%val2 = load volatile i32, ptr %b
194+
br label %end
195+
end:
196+
ret void
197+
}
198+
!0 = !{!"branch_weights", i32 1, i32 99}

0 commit comments

Comments
 (0)