Skip to content

Commit 0c9edb2

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

File tree

7 files changed

+238
-12
lines changed

7 files changed

+238
-12
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,9 @@ 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})
793-
.addMBB(MI.getOperand(1).getMBB());
792+
auto Bcc =
793+
MIB.buildInstr(RISCVCC::getBrCond(*Subtarget, CC), {}, {LHS, RHS})
794+
.addMBB(MI.getOperand(1).getMBB());
794795
MI.eraseFromParent();
795796
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
796797
}

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: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21388,7 +21388,8 @@ 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,
21392+
TII.get(RISCVCC::getBrCond(Subtarget, FirstCC, First.getOpcode())))
2139221393
.addReg(FLHS)
2139321394
.addReg(FRHS)
2139421395
.addMBB(SinkMBB);
@@ -21401,7 +21402,7 @@ EmitLoweredCascadedSelect(MachineInstr &First, MachineInstr &Second,
2140121402
auto SecondCC = static_cast<RISCVCC::CondCode>(Second.getOperand(3).getImm());
2140221403
// Insert appropriate branch.
2140321404
BuildMI(ThisMBB, DL,
21404-
TII.get(RISCVCC::getBrCond(SecondCC, Second.getOpcode())))
21405+
TII.get(RISCVCC::getBrCond(Subtarget, SecondCC, Second.getOpcode())))
2140521406
.addReg(SLHS)
2140621407
.addReg(SRHS)
2140721408
.addMBB(SinkMBB);
@@ -21536,12 +21537,14 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
2153621537

2153721538
// Insert appropriate branch.
2153821539
if (MI.getOperand(2).isImm())
21539-
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
21540+
BuildMI(HeadMBB, DL,
21541+
TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode(), true)))
2154021542
.addReg(LHS)
2154121543
.addImm(MI.getOperand(2).getImm())
2154221544
.addMBB(TailMBB);
2154321545
else
21544-
BuildMI(HeadMBB, DL, TII.get(RISCVCC::getBrCond(CC, MI.getOpcode())))
21546+
BuildMI(HeadMBB, DL,
21547+
TII.get(RISCVCC::getBrCond(Subtarget, CC, MI.getOpcode())))
2154521548
.addReg(LHS)
2154621549
.addReg(RHS)
2154721550
.addMBB(TailMBB);

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 18 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,17 @@ 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,
1029+
unsigned SelectOpc, bool Imm) {
10271030
switch (SelectOpc) {
10281031
default:
10291032
switch (CC) {
10301033
default:
10311034
llvm_unreachable("Unexpected condition code!");
10321035
case RISCVCC::COND_EQ:
1033-
return RISCV::BEQ;
1036+
return (Imm && STI.hasStdExtZibi()) ? RISCV::BEQI : RISCV::BEQ;
10341037
case RISCVCC::COND_NE:
1035-
return RISCV::BNE;
1038+
return (Imm && STI.hasStdExtZibi()) ? RISCV::BNEI : RISCV::BNE;
10361039
case RISCVCC::COND_LT:
10371040
return RISCV::BLT;
10381041
case RISCVCC::COND_GE:
@@ -1341,9 +1344,15 @@ bool RISCVInstrInfo::reverseBranchCondition(
13411344
case RISCV::BEQ:
13421345
Cond[0].setImm(RISCV::BNE);
13431346
break;
1347+
case RISCV::BEQI:
1348+
Cond[0].setImm(RISCV::BNEI);
1349+
break;
13441350
case RISCV::BNE:
13451351
Cond[0].setImm(RISCV::BEQ);
13461352
break;
1353+
case RISCV::BNEI:
1354+
Cond[0].setImm(RISCV::BEQI);
1355+
break;
13471356
case RISCV::BLT:
13481357
Cond[0].setImm(RISCV::BGE);
13491358
break;
@@ -1506,7 +1515,7 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
15061515
return Register();
15071516
};
15081517

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

15111520
// Might be case 1.
15121521
// Don't change 0 to 1 since we can use x0.
@@ -1576,6 +1585,8 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
15761585
case RISCV::BGE:
15771586
case RISCV::BLTU:
15781587
case RISCV::BGEU:
1588+
case RISCV::BEQI:
1589+
case RISCV::BNEI:
15791590
case RISCV::CV_BEQIMM:
15801591
case RISCV::CV_BNEIMM:
15811592
case RISCV::QC_BEQI:
@@ -2775,6 +2786,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
27752786
case RISCVOp::OPERAND_UIMM2_LSB0:
27762787
Ok = isShiftedUInt<1, 1>(Imm);
27772788
break;
2789+
case RISCVOp::OPERAND_UIMM5_ZIBI:
2790+
Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1;
2791+
break;
27782792
case RISCVOp::OPERAND_UIMM5_LSB0:
27792793
Ok = isShiftedUInt<4, 1>(Imm);
27802794
break;

llvm/lib/Target/RISCV/RISCVInstrInfo.h

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

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

5051
} // end of namespace RISCVCC
5152

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)