Skip to content

Commit 42ab473

Browse files
authored
[RISCV] Xqci with Short Forward Branches (#161407)
This change implements support for the combination of Xqci and the Short Forward Branch optimisation. In particular, we want to prioritise `Branch+ALU` (short forward branches) over the equivalent `ALU+CMov`, when the compared values are both registers, and the selected values come from registers (as this is what `PseudoCCMOVGPR` supports). However, when expanding `PseudoCCMOVGPR` (i.e., `Branch+MV`), we instead want to expand it to a conditional move (for code size reasons), so I have added `RISCVExpandPseudo::expandCCOpToCMov` to try to do so. This mostly works, except if `PseudoCCMOVGPR` is comparing against zero and gets commuted - as can be seen in one example in `foo` in `select-cc.ll`. This change: - updates the attributes used for the XQCI RUN lines for the select tests. - modifies the CodeGen patterns and predicates to prioritise selecting the SFB Pseudo. - adds CodeGen patterns for MVLTI/MVLTUI/MVGEI/MVGEUI with imm=zero, to prioritise over the equivalent `Select_GPR_Using_CC_GPR` patterns for rhs=X0. - adds a hook to attempt to turn the predicated-mov Pseudo back into a Conditional Move from Xqcicm (which matches the pseudo in terms of tied register operands).
1 parent 240b73e commit 42ab473

File tree

11 files changed

+514
-245
lines changed

11 files changed

+514
-245
lines changed

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class RISCVExpandPseudo : public MachineFunctionPass {
4646
MachineBasicBlock::iterator &NextMBBI);
4747
bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
4848
MachineBasicBlock::iterator &NextMBBI);
49+
bool expandCCOpToCMov(MachineBasicBlock &MBB,
50+
MachineBasicBlock::iterator MBBI);
4951
bool expandVMSET_VMCLR(MachineBasicBlock &MBB,
5052
MachineBasicBlock::iterator MBBI, unsigned Opcode);
5153
bool expandMV_FPR16INX(MachineBasicBlock &MBB,
@@ -178,6 +180,9 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
178180
bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
179181
MachineBasicBlock::iterator MBBI,
180182
MachineBasicBlock::iterator &NextMBBI) {
183+
// First try expanding to a Conditional Move rather than a branch+mv
184+
if (expandCCOpToCMov(MBB, MBBI))
185+
return true;
181186

182187
MachineFunction *MF = MBB.getParent();
183188
MachineInstr &MI = *MBBI;
@@ -277,6 +282,86 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
277282
return true;
278283
}
279284

285+
bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
286+
MachineBasicBlock::iterator MBBI) {
287+
MachineInstr &MI = *MBBI;
288+
DebugLoc DL = MI.getDebugLoc();
289+
290+
if (MI.getOpcode() != RISCV::PseudoCCMOVGPR &&
291+
MI.getOpcode() != RISCV::PseudoCCMOVGPRNoX0)
292+
return false;
293+
294+
if (!STI->hasVendorXqcicm())
295+
return false;
296+
297+
// FIXME: Would be wonderful to support LHS=X0, but not very easy.
298+
if (MI.getOperand(1).getReg() == RISCV::X0 ||
299+
MI.getOperand(4).getReg() == RISCV::X0 ||
300+
MI.getOperand(5).getReg() == RISCV::X0)
301+
return false;
302+
303+
auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
304+
305+
unsigned CMovOpcode, CMovIOpcode;
306+
switch (CC) {
307+
default:
308+
llvm_unreachable("Unhandled CC");
309+
case RISCVCC::COND_EQ:
310+
CMovOpcode = RISCV::QC_MVEQ;
311+
CMovIOpcode = RISCV::QC_MVEQI;
312+
break;
313+
case RISCVCC::COND_NE:
314+
CMovOpcode = RISCV::QC_MVNE;
315+
CMovIOpcode = RISCV::QC_MVNEI;
316+
break;
317+
case RISCVCC::COND_LT:
318+
CMovOpcode = RISCV::QC_MVLT;
319+
CMovIOpcode = RISCV::QC_MVLTI;
320+
break;
321+
case RISCVCC::COND_GE:
322+
CMovOpcode = RISCV::QC_MVGE;
323+
CMovIOpcode = RISCV::QC_MVGEI;
324+
break;
325+
case RISCVCC::COND_LTU:
326+
CMovOpcode = RISCV::QC_MVLTU;
327+
CMovIOpcode = RISCV::QC_MVLTUI;
328+
break;
329+
case RISCVCC::COND_GEU:
330+
CMovOpcode = RISCV::QC_MVGEU;
331+
CMovIOpcode = RISCV::QC_MVGEUI;
332+
break;
333+
}
334+
335+
if (MI.getOperand(2).getReg() == RISCV::X0) {
336+
// $dst = PseudoCCMOVGPR $lhs, X0, $cc, $falsev (=$dst), $truev
337+
// $dst = PseudoCCMOVGPRNoX0 $lhs, X0, $cc, $falsev (=$dst), $truev
338+
// =>
339+
// $dst = QC_MVccI $falsev (=$dst), $lhs, 0, $truev
340+
BuildMI(MBB, MBBI, DL, TII->get(CMovIOpcode))
341+
.addDef(MI.getOperand(0).getReg())
342+
.addReg(MI.getOperand(4).getReg())
343+
.addReg(MI.getOperand(1).getReg())
344+
.addImm(0)
345+
.addReg(MI.getOperand(5).getReg());
346+
347+
MI.eraseFromParent();
348+
return true;
349+
}
350+
351+
// $dst = PseudoCCMOVGPR $lhs, $rhs, $cc, $falsev (=$dst), $truev
352+
// $dst = PseudoCCMOVGPRNoX0 $lhs, $rhs, $cc, $falsev (=$dst), $truev
353+
// =>
354+
// $dst = QC_MVcc $falsev (=$dst), $lhs, $rhs, $truev
355+
BuildMI(MBB, MBBI, DL, TII->get(CMovOpcode))
356+
.addDef(MI.getOperand(0).getReg())
357+
.addReg(MI.getOperand(4).getReg())
358+
.addReg(MI.getOperand(1).getReg())
359+
.addReg(MI.getOperand(2).getReg())
360+
.addReg(MI.getOperand(5).getReg());
361+
MI.eraseFromParent();
362+
return true;
363+
}
364+
280365
bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB,
281366
MachineBasicBlock::iterator MBBI,
282367
unsigned Opcode) {

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,10 @@ class QCIMVCCIPat<CondCode Cond, QCIMVCCI Inst, DAGOperand InTyImm>
13501350
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
13511351
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, GPRNoX0:$rs3)>;
13521352

1353+
class QCIMVCCIZeroPat<CondCode Cond, QCIMVCCI Inst>
1354+
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
1355+
(Inst GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
1356+
13531357
class QCISELECTCCIPat<CondCode Cond, QCISELECTCCI Inst>
13541358
: Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),
13551359
(Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, GPRNoX0:$rs3)>;
@@ -1538,27 +1542,32 @@ def: Pat<(i32 (ctlz (not (i32 GPR:$rs1)))), (QC_CLO GPR:$rs1)>;
15381542
let Predicates = [HasVendorXqciint, IsRV32] in
15391543
def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
15401544

1541-
let Predicates = [HasVendorXqcicm, IsRV32] in {
1542-
// (SELECT X, Y, Z) is canonicalised to `(riscv_selectcc x, 0, NE, y, z)`.
1543-
// This exists to prioritise over the `Select_GPR_Using_CC_GPR` pattern.
1544-
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETNE, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
1545-
(QC_MVNEI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
1546-
def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETEQ, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
1547-
(QC_MVEQI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
1548-
1545+
let Predicates = [HasVendorXqcicm, NoShortForwardBranchOpt, IsRV32] in {
15491546
def : QCIMVCCPat<SETEQ, QC_MVEQ>;
15501547
def : QCIMVCCPat<SETNE, QC_MVNE>;
15511548
def : QCIMVCCPat<SETLT, QC_MVLT>;
15521549
def : QCIMVCCPat<SETULT, QC_MVLTU>;
15531550
def : QCIMVCCPat<SETGE, QC_MVGE>;
15541551
def : QCIMVCCPat<SETUGE, QC_MVGEU>;
15551552

1556-
def : QCIMVCCIPat<SETEQ, QC_MVEQI, simm5>;
1557-
def : QCIMVCCIPat<SETNE, QC_MVNEI, simm5>;
1558-
def : QCIMVCCIPat<SETLT, QC_MVLTI, simm5>;
1559-
def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5>;
1560-
def : QCIMVCCIPat<SETGE, QC_MVGEI, simm5>;
1561-
def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5>;
1553+
// These exist to prioritise over the `Select_GPR_Using_CC_GPR` pattern for X0.
1554+
def : QCIMVCCIZeroPat<SETEQ, QC_MVEQI>;
1555+
def : QCIMVCCIZeroPat<SETNE, QC_MVNEI>;
1556+
def : QCIMVCCIZeroPat<SETLT, QC_MVLTI>;
1557+
def : QCIMVCCIZeroPat<SETULT, QC_MVLTUI>;
1558+
def : QCIMVCCIZeroPat<SETGE, QC_MVGEI>;
1559+
def : QCIMVCCIZeroPat<SETUGE, QC_MVGEUI>;
1560+
}
1561+
1562+
let Predicates = [HasVendorXqcicm, IsRV32] in {
1563+
// These all use *imm5nonzero because we want to use PseudoCCMOVGPR with X0 when SFB is enabled.
1564+
// When SFB is not enabled, the `QCIMVCCIZeroPat`s above will be used if RHS=0.
1565+
def : QCIMVCCIPat<SETEQ, QC_MVEQI, simm5nonzero>;
1566+
def : QCIMVCCIPat<SETNE, QC_MVNEI, simm5nonzero>;
1567+
def : QCIMVCCIPat<SETLT, QC_MVLTI, simm5nonzero>;
1568+
def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5nonzero>;
1569+
def : QCIMVCCIPat<SETGE, QC_MVGEI, simm5nonzero>;
1570+
def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5nonzero>;
15621571
}
15631572

15641573
let Predicates = [HasVendorXqcicli, IsRV32] in {

llvm/test/CodeGen/RISCV/cmov-branch-opt.ll

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
; RUN: | FileCheck -check-prefixes=SHORT_FORWARD,SFB-NOZICOND,SFB-NOZICOND-C %s
1212
; RUN: llc -mtriple=riscv64 -mattr=+short-forward-branch-opt,+zicond -verify-machineinstrs < %s \
1313
; RUN: | FileCheck -check-prefixes=SHORT_FORWARD,SFB-ZICOND %s
14+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
15+
; RUN: | FileCheck %s --check-prefixes=RV32IXQCI
1416

1517
; The conditional move optimization in sifive-p450 requires that only a
1618
; single c.mv instruction appears in the branch shadow.
@@ -42,6 +44,14 @@ define signext i32 @test1(i32 signext %x, i32 signext %y, i32 signext %z) {
4244
; SHORT_FORWARD-NEXT: xor a0, a0, a1
4345
; SHORT_FORWARD-NEXT: .LBB0_2:
4446
; SHORT_FORWARD-NEXT: ret
47+
;
48+
; RV32IXQCI-LABEL: test1:
49+
; RV32IXQCI: # %bb.0:
50+
; RV32IXQCI-NEXT: bnez a2, .LBB0_2
51+
; RV32IXQCI-NEXT: # %bb.1:
52+
; RV32IXQCI-NEXT: xor a0, a0, a1
53+
; RV32IXQCI-NEXT: .LBB0_2:
54+
; RV32IXQCI-NEXT: ret
4555
%c = icmp eq i32 %z, 0
4656
%a = xor i32 %x, %y
4757
%b = select i1 %c, i32 %a, i32 %x
@@ -73,6 +83,14 @@ define signext i32 @test2(i32 signext %x, i32 signext %y, i32 signext %z) {
7383
; SHORT_FORWARD-NEXT: xor a0, a0, a1
7484
; SHORT_FORWARD-NEXT: .LBB1_2:
7585
; SHORT_FORWARD-NEXT: ret
86+
;
87+
; RV32IXQCI-LABEL: test2:
88+
; RV32IXQCI: # %bb.0:
89+
; RV32IXQCI-NEXT: beqz a2, .LBB1_2
90+
; RV32IXQCI-NEXT: # %bb.1:
91+
; RV32IXQCI-NEXT: xor a0, a0, a1
92+
; RV32IXQCI-NEXT: .LBB1_2:
93+
; RV32IXQCI-NEXT: ret
7694
%c = icmp eq i32 %z, 0
7795
%a = xor i32 %x, %y
7896
%b = select i1 %c, i32 %x, i32 %a
@@ -120,6 +138,19 @@ define signext i32 @test3(i32 signext %v, i32 signext %w, i32 signext %x, i32 si
120138
; SHORT_FORWARD-NEXT: .LBB2_4:
121139
; SHORT_FORWARD-NEXT: addw a0, a0, a2
122140
; SHORT_FORWARD-NEXT: ret
141+
;
142+
; RV32IXQCI-LABEL: test3:
143+
; RV32IXQCI: # %bb.0:
144+
; RV32IXQCI-NEXT: beqz a4, .LBB2_2
145+
; RV32IXQCI-NEXT: # %bb.1:
146+
; RV32IXQCI-NEXT: xor a0, a0, a1
147+
; RV32IXQCI-NEXT: .LBB2_2:
148+
; RV32IXQCI-NEXT: beqz a4, .LBB2_4
149+
; RV32IXQCI-NEXT: # %bb.3:
150+
; RV32IXQCI-NEXT: xor a2, a2, a3
151+
; RV32IXQCI-NEXT: .LBB2_4:
152+
; RV32IXQCI-NEXT: add a0, a0, a2
153+
; RV32IXQCI-NEXT: ret
123154
%c = icmp eq i32 %z, 0
124155
%a = xor i32 %v, %w
125156
%b = select i1 %c, i32 %v, i32 %a
@@ -167,6 +198,12 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
167198
; SFB-ZICOND-NEXT: li a0, 3
168199
; SFB-ZICOND-NEXT: czero.nez a0, a0, a2
169200
; SFB-ZICOND-NEXT: ret
201+
;
202+
; RV32IXQCI-LABEL: test4:
203+
; RV32IXQCI: # %bb.0:
204+
; RV32IXQCI-NEXT: li a0, 0
205+
; RV32IXQCI-NEXT: qc.lieqi a0, a2, 0, 3
206+
; RV32IXQCI-NEXT: ret
170207
%c = icmp eq i32 %z, 0
171208
%a = select i1 %c, i32 3, i32 0
172209
ret i32 %a
@@ -199,6 +236,15 @@ define i16 @select_xor_1(i16 %A, i8 %cond) {
199236
; SHORT_FORWARD-NEXT: xori a0, a0, 43
200237
; SHORT_FORWARD-NEXT: .LBB4_2: # %entry
201238
; SHORT_FORWARD-NEXT: ret
239+
;
240+
; RV32IXQCI-LABEL: select_xor_1:
241+
; RV32IXQCI: # %bb.0: # %entry
242+
; RV32IXQCI-NEXT: andi a1, a1, 1
243+
; RV32IXQCI-NEXT: beqz a1, .LBB4_2
244+
; RV32IXQCI-NEXT: # %bb.1: # %entry
245+
; RV32IXQCI-NEXT: xori a0, a0, 43
246+
; RV32IXQCI-NEXT: .LBB4_2: # %entry
247+
; RV32IXQCI-NEXT: ret
202248
entry:
203249
%and = and i8 %cond, 1
204250
%cmp10 = icmp eq i8 %and, 0
@@ -236,6 +282,15 @@ define i16 @select_xor_1b(i16 %A, i8 %cond) {
236282
; SHORT_FORWARD-NEXT: xori a0, a0, 43
237283
; SHORT_FORWARD-NEXT: .LBB5_2: # %entry
238284
; SHORT_FORWARD-NEXT: ret
285+
;
286+
; RV32IXQCI-LABEL: select_xor_1b:
287+
; RV32IXQCI: # %bb.0: # %entry
288+
; RV32IXQCI-NEXT: andi a1, a1, 1
289+
; RV32IXQCI-NEXT: beqz a1, .LBB5_2
290+
; RV32IXQCI-NEXT: # %bb.1: # %entry
291+
; RV32IXQCI-NEXT: xori a0, a0, 43
292+
; RV32IXQCI-NEXT: .LBB5_2: # %entry
293+
; RV32IXQCI-NEXT: ret
239294
entry:
240295
%and = and i8 %cond, 1
241296
%cmp10 = icmp ne i8 %and, 1
@@ -289,6 +344,15 @@ define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
289344
; SFB-ZICOND-NEXT: xor a0, a1, a0
290345
; SFB-ZICOND-NEXT: .LBB6_2: # %entry
291346
; SFB-ZICOND-NEXT: ret
347+
;
348+
; RV32IXQCI-LABEL: select_xor_2:
349+
; RV32IXQCI: # %bb.0: # %entry
350+
; RV32IXQCI-NEXT: andi a2, a2, 1
351+
; RV32IXQCI-NEXT: beqz a2, .LBB6_2
352+
; RV32IXQCI-NEXT: # %bb.1: # %entry
353+
; RV32IXQCI-NEXT: xor a0, a0, a1
354+
; RV32IXQCI-NEXT: .LBB6_2: # %entry
355+
; RV32IXQCI-NEXT: ret
292356
entry:
293357
%and = and i8 %cond, 1
294358
%cmp10 = icmp eq i8 %and, 0
@@ -344,6 +408,15 @@ define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
344408
; SFB-ZICOND-NEXT: xor a0, a1, a0
345409
; SFB-ZICOND-NEXT: .LBB7_2: # %entry
346410
; SFB-ZICOND-NEXT: ret
411+
;
412+
; RV32IXQCI-LABEL: select_xor_2b:
413+
; RV32IXQCI: # %bb.0: # %entry
414+
; RV32IXQCI-NEXT: andi a2, a2, 1
415+
; RV32IXQCI-NEXT: beqz a2, .LBB7_2
416+
; RV32IXQCI-NEXT: # %bb.1: # %entry
417+
; RV32IXQCI-NEXT: xor a0, a0, a1
418+
; RV32IXQCI-NEXT: .LBB7_2: # %entry
419+
; RV32IXQCI-NEXT: ret
347420
entry:
348421
%and = and i8 %cond, 1
349422
%cmp10 = icmp ne i8 %and, 1
@@ -397,6 +470,15 @@ define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
397470
; SFB-ZICOND-NEXT: or a0, a1, a0
398471
; SFB-ZICOND-NEXT: .LBB8_2: # %entry
399472
; SFB-ZICOND-NEXT: ret
473+
;
474+
; RV32IXQCI-LABEL: select_or:
475+
; RV32IXQCI: # %bb.0: # %entry
476+
; RV32IXQCI-NEXT: andi a2, a2, 1
477+
; RV32IXQCI-NEXT: beqz a2, .LBB8_2
478+
; RV32IXQCI-NEXT: # %bb.1: # %entry
479+
; RV32IXQCI-NEXT: or a0, a0, a1
480+
; RV32IXQCI-NEXT: .LBB8_2: # %entry
481+
; RV32IXQCI-NEXT: ret
400482
entry:
401483
%and = and i8 %cond, 1
402484
%cmp10 = icmp eq i8 %and, 0
@@ -452,6 +534,15 @@ define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
452534
; SFB-ZICOND-NEXT: or a0, a1, a0
453535
; SFB-ZICOND-NEXT: .LBB9_2: # %entry
454536
; SFB-ZICOND-NEXT: ret
537+
;
538+
; RV32IXQCI-LABEL: select_or_b:
539+
; RV32IXQCI: # %bb.0: # %entry
540+
; RV32IXQCI-NEXT: andi a2, a2, 1
541+
; RV32IXQCI-NEXT: beqz a2, .LBB9_2
542+
; RV32IXQCI-NEXT: # %bb.1: # %entry
543+
; RV32IXQCI-NEXT: or a0, a0, a1
544+
; RV32IXQCI-NEXT: .LBB9_2: # %entry
545+
; RV32IXQCI-NEXT: ret
455546
entry:
456547
%and = and i8 %cond, 1
457548
%cmp10 = icmp ne i8 %and, 1
@@ -505,6 +596,15 @@ define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
505596
; SFB-ZICOND-NEXT: or a0, a1, a0
506597
; SFB-ZICOND-NEXT: .LBB10_2: # %entry
507598
; SFB-ZICOND-NEXT: ret
599+
;
600+
; RV32IXQCI-LABEL: select_or_1:
601+
; RV32IXQCI: # %bb.0: # %entry
602+
; RV32IXQCI-NEXT: andi a2, a2, 1
603+
; RV32IXQCI-NEXT: beqz a2, .LBB10_2
604+
; RV32IXQCI-NEXT: # %bb.1: # %entry
605+
; RV32IXQCI-NEXT: or a0, a0, a1
606+
; RV32IXQCI-NEXT: .LBB10_2: # %entry
607+
; RV32IXQCI-NEXT: ret
508608
entry:
509609
%and = and i32 %cond, 1
510610
%cmp10 = icmp eq i32 %and, 0
@@ -560,6 +660,15 @@ define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
560660
; SFB-ZICOND-NEXT: or a0, a1, a0
561661
; SFB-ZICOND-NEXT: .LBB11_2: # %entry
562662
; SFB-ZICOND-NEXT: ret
663+
;
664+
; RV32IXQCI-LABEL: select_or_1b:
665+
; RV32IXQCI: # %bb.0: # %entry
666+
; RV32IXQCI-NEXT: andi a2, a2, 1
667+
; RV32IXQCI-NEXT: beqz a2, .LBB11_2
668+
; RV32IXQCI-NEXT: # %bb.1: # %entry
669+
; RV32IXQCI-NEXT: or a0, a0, a1
670+
; RV32IXQCI-NEXT: .LBB11_2: # %entry
671+
; RV32IXQCI-NEXT: ret
563672
entry:
564673
%and = and i32 %cond, 1
565674
%cmp10 = icmp ne i32 %and, 1

llvm/test/CodeGen/RISCV/select-bare.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
; RUN: | FileCheck %s -check-prefix=RV32I
44
; RUN: llc -mtriple=riscv64 -mattr=+xmipscmov -verify-machineinstrs < %s \
55
; RUN: | FileCheck -check-prefix=RV64I-CCMOV %s
6-
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
6+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
77
; RUN: | FileCheck %s --check-prefixes=RV32IXQCI
88

99
define i32 @bare_select(i1 %a, i32 %b, i32 %c) nounwind {

0 commit comments

Comments
 (0)