Skip to content

Commit 00eff96

Browse files
committed
[RISCV] Add missing patterns for rotr with immediate for Zbb/Zbp extensions.
DAGCombine doesn't canonicalize rotl/rotr with immediate so we need patterns for both. Remove the custom matcher for rotl to RORI and just use a SDNodeXForm to convert the immediate instead. Doing this gives priority to the rev32/rev16 versions of grevi over rori since an explicit immediate is more precise than any immediate. I also added rotr patterns for rev32/rev16. And removed the (or (shl), (shr)) patterns that should be combined to rotl by DAG combine. There is at least one other grev pattern that probably needs a another rotr pattern, but we need more test coverage first. Differential Revision: https://reviews.llvm.org/D90575
1 parent cb798f0 commit 00eff96

File tree

7 files changed

+39
-79
lines changed

7 files changed

+39
-79
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -284,44 +284,6 @@ bool RISCVDAGToDAGISel::SelectSROI(SDValue N, SDValue &RS1, SDValue &Shamt) {
284284
return false;
285285
}
286286

287-
// Check that it is a RORI (Rotate Right Immediate). We first check that
288-
// it is the right node tree:
289-
//
290-
// (ROTL RS1, VC)
291-
//
292-
// The compiler translates immediate rotations to the right given by the call
293-
// to the rotateright32/rotateright64 intrinsics as rotations to the left.
294-
// Since the rotation to the left can be easily emulated as a rotation to the
295-
// right by negating the constant, there is no encoding for ROLI.
296-
// We then select the immediate left rotations as RORI by the complementary
297-
// constant:
298-
//
299-
// Shamt == XLen - VC
300-
301-
bool RISCVDAGToDAGISel::SelectRORI(SDValue N, SDValue &RS1, SDValue &Shamt) {
302-
MVT XLenVT = Subtarget->getXLenVT();
303-
if (N.getOpcode() == ISD::ROTL) {
304-
if (isa<ConstantSDNode>(N.getOperand(1))) {
305-
if (XLenVT == MVT::i64) {
306-
uint64_t VC = N.getConstantOperandVal(1);
307-
Shamt = CurDAG->getTargetConstant((64 - VC), SDLoc(N),
308-
N.getOperand(1).getValueType());
309-
RS1 = N.getOperand(0);
310-
return true;
311-
}
312-
if (XLenVT == MVT::i32) {
313-
uint32_t VC = N.getConstantOperandVal(1);
314-
Shamt = CurDAG->getTargetConstant((32 - VC), SDLoc(N),
315-
N.getOperand(1).getValueType());
316-
RS1 = N.getOperand(0);
317-
return true;
318-
}
319-
}
320-
}
321-
return false;
322-
}
323-
324-
325287
// Check that it is a SLLIUW (Shift Logical Left Immediate Unsigned i32
326288
// on RV64).
327289
// SLLIUW is the same as SLLI except for the fact that it clears the bits

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
4747

4848
bool SelectSLOI(SDValue N, SDValue &RS1, SDValue &Shamt);
4949
bool SelectSROI(SDValue N, SDValue &RS1, SDValue &Shamt);
50-
bool SelectRORI(SDValue N, SDValue &RS1, SDValue &Shamt);
5150
bool SelectSLLIUW(SDValue N, SDValue &RS1, SDValue &Shamt);
5251
bool SelectSLOIW(SDValue N, SDValue &RS1, SDValue &Shamt);
5352
bool SelectSROIW(SDValue N, SDValue &RS1, SDValue &Shamt);

llvm/lib/Target/RISCV/RISCVInstrInfoB.td

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ def ImmSub32 : SDNodeXForm<imm, [{
4646
N->getValueType(0));
4747
}]>;
4848

49+
50+
// Convert rotl immediate to a rotr immediate.
51+
def ImmROTL2R : SDNodeXForm<imm, [{
52+
uint64_t XLen = Subtarget->getXLen();
53+
return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),
54+
N->getValueType(0));
55+
}]>;
56+
4957
//===----------------------------------------------------------------------===//
5058
// Instruction class templates
5159
//===----------------------------------------------------------------------===//
@@ -644,7 +652,6 @@ def : CompressPat<(PACK GPRC:$rs1, GPRC:$rs1, X0),
644652
//===----------------------------------------------------------------------===//
645653
def SLOIPat : ComplexPattern<XLenVT, 2, "SelectSLOI", [or]>;
646654
def SROIPat : ComplexPattern<XLenVT, 2, "SelectSROI", [or]>;
647-
def RORIPat : ComplexPattern<XLenVT, 2, "SelectRORI", [rotl]>;
648655
def SLLIUWPat : ComplexPattern<i64, 2, "SelectSLLIUW", [and]>;
649656
def SLOIWPat : ComplexPattern<i64, 2, "SelectSLOIW", [sext_inreg]>;
650657
def SROIWPat : ComplexPattern<i64, 2, "SelectSROIW", [or]>;
@@ -709,10 +716,12 @@ def : Pat<(SROIPat GPR:$rs1, uimmlog2xlen:$shamt),
709716

710717
// There's no encoding for roli in the current version of the 'B' extension
711718
// (v0.92) as it can be implemented with rori by negating the immediate.
712-
// For this reason we pattern-match only against rori[w].
713-
let Predicates = [HasStdExtZbbOrZbp] in
714-
def : Pat<(RORIPat GPR:$rs1, uimmlog2xlen:$shamt),
719+
let Predicates = [HasStdExtZbbOrZbp] in {
720+
def : Pat<(rotr GPR:$rs1, uimmlog2xlen:$shamt),
715721
(RORI GPR:$rs1, uimmlog2xlen:$shamt)>;
722+
def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
723+
(RORI GPR:$rs1, (ImmROTL2R uimmlog2xlen:$shamt))>;
724+
}
716725

717726
// We don't pattern-match sbclri[w], sbseti[w], sbinvi[w] because they are
718727
// pattern-matched by simple andi, ori, and xori.
@@ -778,9 +787,9 @@ def : Pat<(or (and (shl GPR:$rs1, (i32 8)), (i32 0xFF00FF00)),
778787
(and (srl GPR:$rs1, (i32 8)), (i32 0x00FF00FF))),
779788
(GREVI GPR:$rs1, (i32 8))>;
780789
def : Pat<(rotr (bswap GPR:$rs1), (i32 16)), (GREVI GPR:$rs1, (i32 8))>;
781-
def : Pat<(or (shl GPR:$rs1, (i32 16)), (srl GPR:$rs1, (i32 16))),
782-
(GREVI GPR:$rs1, (i32 16))>;
790+
// FIXME: Is grev better than rori?
783791
def : Pat<(rotl GPR:$rs1, (i32 16)), (GREVI GPR:$rs1, (i32 16))>;
792+
def : Pat<(rotr GPR:$rs1, (i32 16)), (GREVI GPR:$rs1, (i32 16))>;
784793
def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i32 24))>;
785794
def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i32 31))>;
786795
} // Predicates = [HasStdExtZbp, IsRV32]
@@ -801,9 +810,9 @@ def : Pat<(or (and (shl GPR:$rs1, (i64 8)), (i64 0xFF00FF00FF00FF00)),
801810
def : Pat<(or (and (shl GPR:$rs1, (i64 16)), (i64 0xFFFF0000FFFF0000)),
802811
(and (srl GPR:$rs1, (i64 16)), (i64 0x0000FFFF0000FFFF))),
803812
(GREVI GPR:$rs1, (i64 16))>;
804-
def : Pat<(or (shl GPR:$rs1, (i64 32)), (srl GPR:$rs1, (i64 32))),
805-
(GREVI GPR:$rs1, (i64 32))>;
813+
// FIXME: Is grev better than rori?
806814
def : Pat<(rotl GPR:$rs1, (i64 32)), (GREVI GPR:$rs1, (i64 32))>;
815+
def : Pat<(rotr GPR:$rs1, (i64 32)), (GREVI GPR:$rs1, (i64 32))>;
807816
def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i64 56))>;
808817
def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i64 63))>;
809818
} // Predicates = [HasStdExtZbp, IsRV64]

llvm/test/CodeGen/RISCV/rv32Zbbp.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,20 +663,17 @@ define i32 @rori_i32_fshr(i32 %a) nounwind {
663663
;
664664
; RV32IB-LABEL: rori_i32_fshr:
665665
; RV32IB: # %bb.0:
666-
; RV32IB-NEXT: addi a1, zero, 31
667-
; RV32IB-NEXT: ror a0, a0, a1
666+
; RV32IB-NEXT: rori a0, a0, 31
668667
; RV32IB-NEXT: ret
669668
;
670669
; RV32IBB-LABEL: rori_i32_fshr:
671670
; RV32IBB: # %bb.0:
672-
; RV32IBB-NEXT: addi a1, zero, 31
673-
; RV32IBB-NEXT: ror a0, a0, a1
671+
; RV32IBB-NEXT: rori a0, a0, 31
674672
; RV32IBB-NEXT: ret
675673
;
676674
; RV32IBP-LABEL: rori_i32_fshr:
677675
; RV32IBP: # %bb.0:
678-
; RV32IBP-NEXT: addi a1, zero, 31
679-
; RV32IBP-NEXT: ror a0, a0, a1
676+
; RV32IBP-NEXT: rori a0, a0, 31
680677
; RV32IBP-NEXT: ret
681678
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
682679
ret i32 %1

llvm/test/CodeGen/RISCV/rv32Zbp.ll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -646,12 +646,12 @@ define i32 @grev16_i32(i32 %a) nounwind {
646646
;
647647
; RV32IB-LABEL: grev16_i32:
648648
; RV32IB: # %bb.0:
649-
; RV32IB-NEXT: rori a0, a0, 16
649+
; RV32IB-NEXT: rev16 a0, a0
650650
; RV32IB-NEXT: ret
651651
;
652652
; RV32IBP-LABEL: grev16_i32:
653653
; RV32IBP: # %bb.0:
654-
; RV32IBP-NEXT: rori a0, a0, 16
654+
; RV32IBP-NEXT: rev16 a0, a0
655655
; RV32IBP-NEXT: ret
656656
%shl = shl i32 %a, 16
657657
%shr = lshr i32 %a, 16
@@ -672,12 +672,12 @@ define signext i32 @grev16_i32_fshl(i32 signext %a) nounwind {
672672
;
673673
; RV32IB-LABEL: grev16_i32_fshl:
674674
; RV32IB: # %bb.0:
675-
; RV32IB-NEXT: rori a0, a0, 16
675+
; RV32IB-NEXT: rev16 a0, a0
676676
; RV32IB-NEXT: ret
677677
;
678678
; RV32IBP-LABEL: grev16_i32_fshl:
679679
; RV32IBP: # %bb.0:
680-
; RV32IBP-NEXT: rori a0, a0, 16
680+
; RV32IBP-NEXT: rev16 a0, a0
681681
; RV32IBP-NEXT: ret
682682
%or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 16)
683683
ret i32 %or
@@ -693,14 +693,12 @@ define signext i32 @grev16_i32_fshr(i32 signext %a) nounwind {
693693
;
694694
; RV32IB-LABEL: grev16_i32_fshr:
695695
; RV32IB: # %bb.0:
696-
; RV32IB-NEXT: addi a1, zero, 16
697-
; RV32IB-NEXT: ror a0, a0, a1
696+
; RV32IB-NEXT: rev16 a0, a0
698697
; RV32IB-NEXT: ret
699698
;
700699
; RV32IBP-LABEL: grev16_i32_fshr:
701700
; RV32IBP: # %bb.0:
702-
; RV32IBP-NEXT: addi a1, zero, 16
703-
; RV32IBP-NEXT: ror a0, a0, a1
701+
; RV32IBP-NEXT: rev16 a0, a0
704702
; RV32IBP-NEXT: ret
705703
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 16)
706704
ret i32 %or
@@ -719,14 +717,14 @@ define i64 @grev16_i64(i64 %a) nounwind {
719717
;
720718
; RV32IB-LABEL: grev16_i64:
721719
; RV32IB: # %bb.0:
722-
; RV32IB-NEXT: rori a0, a0, 16
723-
; RV32IB-NEXT: rori a1, a1, 16
720+
; RV32IB-NEXT: rev16 a0, a0
721+
; RV32IB-NEXT: rev16 a1, a1
724722
; RV32IB-NEXT: ret
725723
;
726724
; RV32IBP-LABEL: grev16_i64:
727725
; RV32IBP: # %bb.0:
728-
; RV32IBP-NEXT: rori a0, a0, 16
729-
; RV32IBP-NEXT: rori a1, a1, 16
726+
; RV32IBP-NEXT: rev16 a0, a0
727+
; RV32IBP-NEXT: rev16 a1, a1
730728
; RV32IBP-NEXT: ret
731729
%and = shl i64 %a, 16
732730
%shl = and i64 %and, -281470681808896

llvm/test/CodeGen/RISCV/rv64Zbbp.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,20 +456,17 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
456456
;
457457
; RV64IB-LABEL: rori_i64_fshr:
458458
; RV64IB: # %bb.0:
459-
; RV64IB-NEXT: addi a1, zero, 63
460-
; RV64IB-NEXT: ror a0, a0, a1
459+
; RV64IB-NEXT: rori a0, a0, 63
461460
; RV64IB-NEXT: ret
462461
;
463462
; RV64IBB-LABEL: rori_i64_fshr:
464463
; RV64IBB: # %bb.0:
465-
; RV64IBB-NEXT: addi a1, zero, 63
466-
; RV64IBB-NEXT: ror a0, a0, a1
464+
; RV64IBB-NEXT: rori a0, a0, 63
467465
; RV64IBB-NEXT: ret
468466
;
469467
; RV64IBP-LABEL: rori_i64_fshr:
470468
; RV64IBP: # %bb.0:
471-
; RV64IBP-NEXT: addi a1, zero, 63
472-
; RV64IBP-NEXT: ror a0, a0, a1
469+
; RV64IBP-NEXT: rori a0, a0, 63
473470
; RV64IBP-NEXT: ret
474471
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
475472
ret i64 %1

llvm/test/CodeGen/RISCV/rv64Zbp.ll

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -840,12 +840,12 @@ define i64 @grev32(i64 %a) nounwind {
840840
;
841841
; RV64IB-LABEL: grev32:
842842
; RV64IB: # %bb.0:
843-
; RV64IB-NEXT: rori a0, a0, 32
843+
; RV64IB-NEXT: rev32 a0, a0
844844
; RV64IB-NEXT: ret
845845
;
846846
; RV64IBP-LABEL: grev32:
847847
; RV64IBP: # %bb.0:
848-
; RV64IBP-NEXT: rori a0, a0, 32
848+
; RV64IBP-NEXT: rev32 a0, a0
849849
; RV64IBP-NEXT: ret
850850
%shl = shl i64 %a, 32
851851
%shr = lshr i64 %a, 32
@@ -866,12 +866,12 @@ define i64 @grev32_fshl(i64 %a) nounwind {
866866
;
867867
; RV64IB-LABEL: grev32_fshl:
868868
; RV64IB: # %bb.0:
869-
; RV64IB-NEXT: rori a0, a0, 32
869+
; RV64IB-NEXT: rev32 a0, a0
870870
; RV64IB-NEXT: ret
871871
;
872872
; RV64IBP-LABEL: grev32_fshl:
873873
; RV64IBP: # %bb.0:
874-
; RV64IBP-NEXT: rori a0, a0, 32
874+
; RV64IBP-NEXT: rev32 a0, a0
875875
; RV64IBP-NEXT: ret
876876
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 32)
877877
ret i64 %or
@@ -887,14 +887,12 @@ define i64 @grev32_fshr(i64 %a) nounwind {
887887
;
888888
; RV64IB-LABEL: grev32_fshr:
889889
; RV64IB: # %bb.0:
890-
; RV64IB-NEXT: addi a1, zero, 32
891-
; RV64IB-NEXT: ror a0, a0, a1
890+
; RV64IB-NEXT: rev32 a0, a0
892891
; RV64IB-NEXT: ret
893892
;
894893
; RV64IBP-LABEL: grev32_fshr:
895894
; RV64IBP: # %bb.0:
896-
; RV64IBP-NEXT: addi a1, zero, 32
897-
; RV64IBP-NEXT: ror a0, a0, a1
895+
; RV64IBP-NEXT: rev32 a0, a0
898896
; RV64IBP-NEXT: ret
899897
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 32)
900898
ret i64 %or

0 commit comments

Comments
 (0)