diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 2a4abf50b1067..ca21c005ad4d3 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -444,10 +444,14 @@ bool RISCVDAGToDAGISel::SelectRORIW(SDValue N, SDValue &RS1, SDValue &Shamt) { cast(N.getOperand(1))->getVT() == MVT::i32) { if (N.getOperand(0).getOpcode() == ISD::OR) { SDValue Or = N.getOperand(0); - if (Or.getOperand(0).getOpcode() == ISD::SHL && - Or.getOperand(1).getOpcode() == ISD::SRL) { - SDValue Shl = Or.getOperand(0); - SDValue Srl = Or.getOperand(1); + 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) && diff --git a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll index cd028c04b3863..f145c69dc58ed 100644 --- a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll @@ -318,26 +318,17 @@ define signext i32 @rori_i32_fshr(i32 signext %a) nounwind { ; ; RV64IB-LABEL: rori_i32_fshr: ; RV64IB: # %bb.0: -; RV64IB-NEXT: slli a1, a0, 1 -; RV64IB-NEXT: srliw a0, a0, 31 -; RV64IB-NEXT: or a0, a0, a1 -; RV64IB-NEXT: sext.w a0, a0 +; RV64IB-NEXT: roriw a0, a0, 31 ; RV64IB-NEXT: ret ; ; RV64IBB-LABEL: rori_i32_fshr: ; RV64IBB: # %bb.0: -; RV64IBB-NEXT: slli a1, a0, 1 -; RV64IBB-NEXT: srliw a0, a0, 31 -; RV64IBB-NEXT: or a0, a0, a1 -; RV64IBB-NEXT: sext.w a0, a0 +; RV64IBB-NEXT: roriw a0, a0, 31 ; RV64IBB-NEXT: ret ; ; RV64IBP-LABEL: rori_i32_fshr: ; RV64IBP: # %bb.0: -; RV64IBP-NEXT: slli a1, a0, 1 -; RV64IBP-NEXT: srliw a0, a0, 31 -; RV64IBP-NEXT: or a0, a0, a1 -; RV64IBP-NEXT: sext.w a0, a0 +; RV64IBP-NEXT: roriw a0, a0, 31 ; RV64IBP-NEXT: ret %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31) ret i32 %1