[llvm] 78767b7 - [RISCV] Add RISCVISD::ROLW/RORW use those for custom legalizing i32 rotl/rotr on RV64IZbb.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 20 10:26:45 PST 2020
Author: Craig Topper
Date: 2020-11-20T10:25:47-08:00
New Revision: 78767b7f8e8a31d0941a572ecab0918f6fcc8024
URL: https://github.com/llvm/llvm-project/commit/78767b7f8e8a31d0941a572ecab0918f6fcc8024
DIFF: https://github.com/llvm/llvm-project/commit/78767b7f8e8a31d0941a572ecab0918f6fcc8024.diff
LOG: [RISCV] Add RISCVISD::ROLW/RORW use those for custom legalizing i32 rotl/rotr on RV64IZbb.
This should result in better utilization of RORIW since we
don't need to look for a SIGN_EXTEND_INREG that may not exist.
Also remove rotl/rotr isel matching to GREVI and just prefer RORI.
This is to keep consistency so we don't have to match ROLW/RORW
to GREVIW as well. I imagine RORI/RORIW performance will be the
same or better than GREVI.
Differential Revision: https://reviews.llvm.org/D91449
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.h
llvm/lib/Target/RISCV/RISCVInstrInfoB.td
llvm/test/CodeGen/RISCV/rv32Zbp.ll
llvm/test/CodeGen/RISCV/rv64Zbbp.ll
llvm/test/CodeGen/RISCV/rv64Zbp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 765775c03587..0f455a58f35c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -376,62 +376,6 @@ bool RISCVDAGToDAGISel::SelectSROIW(SDValue N, SDValue &RS1, SDValue &Shamt) {
return true;
}
-// Check that it is a RORIW (i32 Right Rotate Immediate on RV64).
-// We first check that it is the right node tree:
-//
-// (SIGN_EXTEND_INREG (OR (SHL RS1, VC2),
-// (SRL (AND RS1, VC3), VC1)))
-//
-// Then we check that the constant operands respect these constraints:
-//
-// VC2 == 32 - VC1
-// VC3 | maskTrailingOnes<uint64_t>(VC1) == 0xffffffff
-//
-// being VC1 the Shamt we need, VC2 the complementary of Shamt over 32
-// and VC3 being 0xffffffff after accounting for SimplifyDemandedBits removing
-// some bits due to the right shift.
-
-bool RISCVDAGToDAGISel::SelectRORIW(SDValue N, SDValue &RS1, SDValue &Shamt) {
- if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
- Subtarget->getXLenVT() == MVT::i64 &&
- cast<VTSDNode>(N.getOperand(1))->getVT() == MVT::i32) {
- if (N.getOperand(0).getOpcode() == ISD::OR) {
- SDValue Or = N.getOperand(0);
- SDValue Shl = Or.getOperand(0);
- SDValue Srl = Or.getOperand(1);
-
- // OR is commutable so canonicalize SHL to LHS.
- if (Srl.getOpcode() == ISD::SHL)
- std::swap(Shl, Srl);
-
- if (Shl.getOpcode() == ISD::SHL && Srl.getOpcode() == ISD::SRL) {
- if (Srl.getOperand(0).getOpcode() == ISD::AND) {
- SDValue And = Srl.getOperand(0);
- if (And.getOperand(0) == Shl.getOperand(0) &&
- isa<ConstantSDNode>(Srl.getOperand(1)) &&
- isa<ConstantSDNode>(Shl.getOperand(1)) &&
- isa<ConstantSDNode>(And.getOperand(1))) {
- uint64_t VC1 = Srl.getConstantOperandVal(1);
- uint64_t VC2 = Shl.getConstantOperandVal(1);
- uint64_t VC3 = And.getConstantOperandVal(1);
- // The mask needs to be 0xffffffff, but SimplifyDemandedBits may
- // have removed lower bits that aren't necessary due to the right
- // shift.
- if (VC2 == (32 - VC1) &&
- (VC3 | maskTrailingOnes<uint64_t>(VC1)) == 0xffffffff) {
- RS1 = Shl.getOperand(0);
- Shamt = CurDAG->getTargetConstant(VC1, SDLoc(N),
- Srl.getOperand(1).getValueType());
- return true;
- }
- }
- }
- }
- }
- }
- return false;
-}
-
// Merge an ADDI into the offset of a load/store instruction where possible.
// (load (addi base, off1), off2) -> (load base, off1+off2)
// (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 10096c39cdbe..4e382ee58500 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -50,7 +50,6 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
bool SelectSLLIUW(SDValue N, SDValue &RS1, SDValue &Shamt);
bool SelectSLOIW(SDValue N, SDValue &RS1, SDValue &Shamt);
bool SelectSROIW(SDValue N, SDValue &RS1, SDValue &Shamt);
- bool SelectRORIW(SDValue N, SDValue &RS1, SDValue &Shamt);
// Include the pieces autogenerated from the target description.
#include "RISCVGenDAGISel.inc"
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b0f62f3d45f3..3def64766066 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -151,7 +151,12 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SRL_PARTS, XLenVT, Custom);
setOperationAction(ISD::SRA_PARTS, XLenVT, Custom);
- if (!(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp())) {
+ if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
+ if (Subtarget.is64Bit()) {
+ setOperationAction(ISD::ROTL, MVT::i32, Custom);
+ setOperationAction(ISD::ROTR, MVT::i32, Custom);
+ }
+ } else {
setOperationAction(ISD::ROTL, XLenVT, Expand);
setOperationAction(ISD::ROTR, XLenVT, Expand);
}
@@ -908,6 +913,10 @@ static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
return RISCVISD::DIVUW;
case ISD::UREM:
return RISCVISD::REMUW;
+ case ISD::ROTL:
+ return RISCVISD::ROLW;
+ case ISD::ROTR:
+ return RISCVISD::RORW;
case RISCVISD::GREVI:
return RISCVISD::GREVIW;
case RISCVISD::GORCI:
@@ -1013,6 +1022,12 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
return;
Results.push_back(customLegalizeToWOp(N, DAG));
break;
+ case ISD::ROTL:
+ case ISD::ROTR:
+ assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
+ "Unexpected custom legalisation");
+ Results.push_back(customLegalizeToWOp(N, DAG));
+ break;
case ISD::SDIV:
case ISD::UDIV:
case ISD::UREM:
@@ -1267,7 +1282,9 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
}
case RISCVISD::SLLW:
case RISCVISD::SRAW:
- case RISCVISD::SRLW: {
+ case RISCVISD::SRLW:
+ case RISCVISD::ROLW:
+ case RISCVISD::RORW: {
// Only the lower 32 bits of LHS and lower 5 bits of RHS are read.
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
@@ -1392,6 +1409,8 @@ unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode(
case RISCVISD::DIVW:
case RISCVISD::DIVUW:
case RISCVISD::REMUW:
+ case RISCVISD::ROLW:
+ case RISCVISD::RORW:
case RISCVISD::GREVIW:
case RISCVISD::GORCIW:
// TODO: As the result is sign-extended, this is conservatively correct. A
@@ -2829,6 +2848,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(DIVW)
NODE_NAME_CASE(DIVUW)
NODE_NAME_CASE(REMUW)
+ NODE_NAME_CASE(ROLW)
+ NODE_NAME_CASE(RORW)
NODE_NAME_CASE(FMV_W_X_RV64)
NODE_NAME_CASE(FMV_X_ANYEXTW_RV64)
NODE_NAME_CASE(READ_CYCLE_WIDE)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index e62d3ff857ff..46c91ed78479 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -42,6 +42,10 @@ enum NodeType : unsigned {
DIVW,
DIVUW,
REMUW,
+ // RV64IB rotates, directly matching the semantics of the named RISC-V
+ // instructions.
+ ROLW,
+ RORW,
// FPR32<->GPR transfer operations for RV64. Needed as an i32<->f32 bitcast
// is not legal on RV64. FMV_W_X_RV64 matches the semantics of the FMV.W.X.
// FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
index abd0adb25bf4..87dae110a931 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -17,6 +17,9 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
+def riscv_rolw : SDNode<"RISCVISD::ROLW", SDTIntShiftOp>;
+def riscv_rorw : SDNode<"RISCVISD::RORW", SDTIntShiftOp>;
+
def UImmLog2XLenHalfAsmOperand : AsmOperandClass {
let Name = "UImmLog2XLenHalf";
let RenderMethod = "addImmOperands";
@@ -655,7 +658,6 @@ def SROIPat : ComplexPattern<XLenVT, 2, "SelectSROI", [or]>;
def SLLIUWPat : ComplexPattern<i64, 2, "SelectSLLIUW", [and]>;
def SLOIWPat : ComplexPattern<i64, 2, "SelectSLOIW", [sext_inreg]>;
def SROIWPat : ComplexPattern<i64, 2, "SelectSROIW", [or]>;
-def RORIWPat : ComplexPattern<i64, 2, "SelectRORIW", [sext_inreg]>;
let Predicates = [HasStdExtZbbOrZbp] in {
def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
@@ -724,17 +726,11 @@ def : Pat<(riscv_gorci GPR:$rs1, timm:$shamt), (GORCI GPR:$rs1, timm:$shamt)>;
let Predicates = [HasStdExtZbp, IsRV32] in {
def : Pat<(rotr (bswap GPR:$rs1), (i32 16)), (GREVI GPR:$rs1, (i32 8))>;
-// FIXME: Is grev better than rori?
-def : Pat<(rotl GPR:$rs1, (i32 16)), (GREVI GPR:$rs1, (i32 16))>;
-def : Pat<(rotr GPR:$rs1, (i32 16)), (GREVI GPR:$rs1, (i32 16))>;
def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i32 24))>;
def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i32 31))>;
} // Predicates = [HasStdExtZbp, IsRV32]
let Predicates = [HasStdExtZbp, IsRV64] in {
-// FIXME: Is grev better than rori?
-def : Pat<(rotl GPR:$rs1, (i64 32)), (GREVI GPR:$rs1, (i64 32))>;
-def : Pat<(rotr GPR:$rs1, (i64 32)), (GREVI GPR:$rs1, (i64 32))>;
def : Pat<(bswap GPR:$rs1), (GREVI GPR:$rs1, (i64 56))>;
def : Pat<(bitreverse GPR:$rs1), (GREVI GPR:$rs1, (i64 63))>;
} // Predicates = [HasStdExtZbp, IsRV64]
@@ -890,12 +886,14 @@ def : Pat<(not (riscv_srlw (not GPR:$rs1), GPR:$rs2)),
} // Predicates = [HasStdExtZbb, IsRV64]
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
-def : Pat<(or (riscv_sllw GPR:$rs1, GPR:$rs2),
- (riscv_srlw GPR:$rs1, (ineg GPR:$rs2))),
+def : Pat<(riscv_rolw GPR:$rs1, GPR:$rs2),
(ROLW GPR:$rs1, GPR:$rs2)>;
-def : Pat<(or (riscv_sllw GPR:$rs1, (ineg GPR:$rs2)),
- (riscv_srlw GPR:$rs1, GPR:$rs2)),
+def : Pat<(riscv_rorw GPR:$rs1, GPR:$rs2),
(RORW GPR:$rs1, GPR:$rs2)>;
+def : Pat<(riscv_rorw GPR:$rs1, uimm5:$rs2),
+ (RORIW GPR:$rs1, uimm5:$rs2)>;
+def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
+ (RORIW GPR:$rs1, (ImmROTL2RW uimm5:$rs2))>;
} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
let Predicates = [HasStdExtZbs, IsRV64] in {
@@ -916,10 +914,6 @@ def : Pat<(SROIWPat GPR:$rs1, uimmlog2xlen:$shamt),
(SROIW GPR:$rs1, uimmlog2xlen:$shamt)>;
} // Predicates = [HasStdExtZbb, IsRV64]
-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
-def : Pat<(RORIWPat GPR:$rs1, uimmlog2xlen:$shamt),
- (RORIW GPR:$rs1, uimmlog2xlen:$shamt)>;
-
let Predicates = [HasStdExtZbp, IsRV64] in {
def : Pat<(riscv_greviw GPR:$rs1, timm:$shamt), (GREVIW GPR:$rs1, timm:$shamt)>;
def : Pat<(riscv_gorciw GPR:$rs1, timm:$shamt), (GORCIW GPR:$rs1, timm:$shamt)>;
diff --git a/llvm/test/CodeGen/RISCV/rv32Zbp.ll b/llvm/test/CodeGen/RISCV/rv32Zbp.ll
index 22aee569ff28..69a5df3689ec 100644
--- a/llvm/test/CodeGen/RISCV/rv32Zbp.ll
+++ b/llvm/test/CodeGen/RISCV/rv32Zbp.ll
@@ -1126,12 +1126,12 @@ define i32 @grev16_i32(i32 %a) nounwind {
;
; RV32IB-LABEL: grev16_i32:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: rev16 a0, a0
+; RV32IB-NEXT: rori a0, a0, 16
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: grev16_i32:
; RV32IBP: # %bb.0:
-; RV32IBP-NEXT: rev16 a0, a0
+; RV32IBP-NEXT: rori a0, a0, 16
; RV32IBP-NEXT: ret
%shl = shl i32 %a, 16
%shr = lshr i32 %a, 16
@@ -1152,12 +1152,12 @@ define signext i32 @grev16_i32_fshl(i32 signext %a) nounwind {
;
; RV32IB-LABEL: grev16_i32_fshl:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: rev16 a0, a0
+; RV32IB-NEXT: rori a0, a0, 16
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: grev16_i32_fshl:
; RV32IBP: # %bb.0:
-; RV32IBP-NEXT: rev16 a0, a0
+; RV32IBP-NEXT: rori a0, a0, 16
; RV32IBP-NEXT: ret
%or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 16)
ret i32 %or
@@ -1173,12 +1173,12 @@ define signext i32 @grev16_i32_fshr(i32 signext %a) nounwind {
;
; RV32IB-LABEL: grev16_i32_fshr:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: rev16 a0, a0
+; RV32IB-NEXT: rori a0, a0, 16
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: grev16_i32_fshr:
; RV32IBP: # %bb.0:
-; RV32IBP-NEXT: rev16 a0, a0
+; RV32IBP-NEXT: rori a0, a0, 16
; RV32IBP-NEXT: ret
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 16)
ret i32 %or
@@ -1197,14 +1197,14 @@ define i64 @grev16_i64(i64 %a) nounwind {
;
; RV32IB-LABEL: grev16_i64:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: rev16 a0, a0
-; RV32IB-NEXT: rev16 a1, a1
+; RV32IB-NEXT: rori a0, a0, 16
+; RV32IB-NEXT: rori a1, a1, 16
; RV32IB-NEXT: ret
;
; RV32IBP-LABEL: grev16_i64:
; RV32IBP: # %bb.0:
-; RV32IBP-NEXT: rev16 a0, a0
-; RV32IBP-NEXT: rev16 a1, a1
+; RV32IBP-NEXT: rori a0, a0, 16
+; RV32IBP-NEXT: rori a1, a1, 16
; RV32IBP-NEXT: ret
%and = shl i64 %a, 16
%shl = and i64 %and, -281470681808896
diff --git a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll
index 771967d22e19..f6787b833132 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll
@@ -374,7 +374,6 @@ define signext i32 @rori_i32_fshl(i32 signext %a) nounwind {
}
; Similar to rori_i32_fshl, but doesn't sign extend the result.
-; FIXME: We should be using RORIW, but we need a sext_inreg.
define void @rori_i32_fshl_nosext(i32 signext %a, i32* %x) nounwind {
; RV64I-LABEL: rori_i32_fshl_nosext:
; RV64I: # %bb.0:
@@ -386,25 +385,19 @@ define void @rori_i32_fshl_nosext(i32 signext %a, i32* %x) nounwind {
;
; RV64IB-LABEL: rori_i32_fshl_nosext:
; RV64IB: # %bb.0:
-; RV64IB-NEXT: srliw a2, a0, 1
-; RV64IB-NEXT: slli a0, a0, 31
-; RV64IB-NEXT: or a0, a0, a2
+; RV64IB-NEXT: roriw a0, a0, 1
; RV64IB-NEXT: sw a0, 0(a1)
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: rori_i32_fshl_nosext:
; RV64IBB: # %bb.0:
-; RV64IBB-NEXT: srliw a2, a0, 1
-; RV64IBB-NEXT: slli a0, a0, 31
-; RV64IBB-NEXT: or a0, a0, a2
+; RV64IBB-NEXT: roriw a0, a0, 1
; RV64IBB-NEXT: sw a0, 0(a1)
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: rori_i32_fshl_nosext:
; RV64IBP: # %bb.0:
-; RV64IBP-NEXT: srliw a2, a0, 1
-; RV64IBP-NEXT: slli a0, a0, 31
-; RV64IBP-NEXT: or a0, a0, a2
+; RV64IBP-NEXT: roriw a0, a0, 1
; RV64IBP-NEXT: sw a0, 0(a1)
; RV64IBP-NEXT: ret
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
@@ -440,7 +433,6 @@ define signext i32 @rori_i32_fshr(i32 signext %a) nounwind {
}
; Similar to rori_i32_fshr, but doesn't sign extend the result.
-; FIXME: We should be using RORIW, but we need a sext_inreg.
define void @rori_i32_fshr_nosext(i32 signext %a, i32* %x) nounwind {
; RV64I-LABEL: rori_i32_fshr_nosext:
; RV64I: # %bb.0:
@@ -452,25 +444,19 @@ define void @rori_i32_fshr_nosext(i32 signext %a, i32* %x) nounwind {
;
; RV64IB-LABEL: rori_i32_fshr_nosext:
; RV64IB: # %bb.0:
-; RV64IB-NEXT: slli a2, a0, 1
-; RV64IB-NEXT: srliw a0, a0, 31
-; RV64IB-NEXT: or a0, a0, a2
+; RV64IB-NEXT: roriw a0, a0, 31
; RV64IB-NEXT: sw a0, 0(a1)
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: rori_i32_fshr_nosext:
; RV64IBB: # %bb.0:
-; RV64IBB-NEXT: slli a2, a0, 1
-; RV64IBB-NEXT: srliw a0, a0, 31
-; RV64IBB-NEXT: or a0, a0, a2
+; RV64IBB-NEXT: roriw a0, a0, 31
; RV64IBB-NEXT: sw a0, 0(a1)
; RV64IBB-NEXT: ret
;
; RV64IBP-LABEL: rori_i32_fshr_nosext:
; RV64IBP: # %bb.0:
-; RV64IBP-NEXT: slli a2, a0, 1
-; RV64IBP-NEXT: srliw a0, a0, 31
-; RV64IBP-NEXT: or a0, a0, a2
+; RV64IBP-NEXT: roriw a0, a0, 31
; RV64IBP-NEXT: sw a0, 0(a1)
; RV64IBP-NEXT: ret
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
diff --git a/llvm/test/CodeGen/RISCV/rv64Zbp.ll b/llvm/test/CodeGen/RISCV/rv64Zbp.ll
index 3a57967f5183..174822608468 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbp.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbp.ll
@@ -1377,12 +1377,12 @@ define i64 @grev32(i64 %a) nounwind {
;
; RV64IB-LABEL: grev32:
; RV64IB: # %bb.0:
-; RV64IB-NEXT: rev32 a0, a0
+; RV64IB-NEXT: rori a0, a0, 32
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: grev32:
; RV64IBP: # %bb.0:
-; RV64IBP-NEXT: rev32 a0, a0
+; RV64IBP-NEXT: rori a0, a0, 32
; RV64IBP-NEXT: ret
%shl = shl i64 %a, 32
%shr = lshr i64 %a, 32
@@ -1403,12 +1403,12 @@ define i64 @grev32_fshl(i64 %a) nounwind {
;
; RV64IB-LABEL: grev32_fshl:
; RV64IB: # %bb.0:
-; RV64IB-NEXT: rev32 a0, a0
+; RV64IB-NEXT: rori a0, a0, 32
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: grev32_fshl:
; RV64IBP: # %bb.0:
-; RV64IBP-NEXT: rev32 a0, a0
+; RV64IBP-NEXT: rori a0, a0, 32
; RV64IBP-NEXT: ret
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 32)
ret i64 %or
@@ -1424,12 +1424,12 @@ define i64 @grev32_fshr(i64 %a) nounwind {
;
; RV64IB-LABEL: grev32_fshr:
; RV64IB: # %bb.0:
-; RV64IB-NEXT: rev32 a0, a0
+; RV64IB-NEXT: rori a0, a0, 32
; RV64IB-NEXT: ret
;
; RV64IBP-LABEL: grev32_fshr:
; RV64IBP: # %bb.0:
-; RV64IBP-NEXT: rev32 a0, a0
+; RV64IBP-NEXT: rori a0, a0, 32
; RV64IBP-NEXT: ret
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 32)
ret i64 %or
More information about the llvm-commits
mailing list