diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -444,10 +444,14 @@ 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 --- a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll @@ -318,26 +318,17 @@ ; ; 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