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 @@ -450,7 +450,8 @@ SDValue Srl = Or.getOperand(1); if (Srl.getOperand(0).getOpcode() == ISD::AND) { SDValue And = Srl.getOperand(0); - if (isa(Srl.getOperand(1)) && + if (And.getOperand(0) == Shl.getOperand(0) && + isa(Srl.getOperand(1)) && isa(Shl.getOperand(1)) && isa(And.getOperand(1))) { uint32_t VC1 = Srl.getConstantOperandVal(1); 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 @@ -346,7 +346,6 @@ ; This test is similar to the type legalized versio of the fshl/fshr tests, but ; instead of having the same input to both shifts it has different inputs. Make ; sure we don't match it has a roriw. -; FIXME: We're currently missing a check that the inputs are the same. define signext i32 @not_rori_i32(i32 signext %x, i32 signext %y) nounwind { ; RV64I-LABEL: not_rori_i32: ; RV64I: # %bb.0: @@ -358,17 +357,26 @@ ; ; RV64IB-LABEL: not_rori_i32: ; RV64IB: # %bb.0: -; RV64IB-NEXT: roriw a0, a0, 1 +; RV64IB-NEXT: slli a0, a0, 31 +; RV64IB-NEXT: srliw a1, a1, 1 +; RV64IB-NEXT: or a0, a0, a1 +; RV64IB-NEXT: sext.w a0, a0 ; RV64IB-NEXT: ret ; ; RV64IBB-LABEL: not_rori_i32: ; RV64IBB: # %bb.0: -; RV64IBB-NEXT: roriw a0, a0, 1 +; RV64IBB-NEXT: slli a0, a0, 31 +; RV64IBB-NEXT: srliw a1, a1, 1 +; RV64IBB-NEXT: or a0, a0, a1 +; RV64IBB-NEXT: sext.w a0, a0 ; RV64IBB-NEXT: ret ; ; RV64IBP-LABEL: not_rori_i32: ; RV64IBP: # %bb.0: -; RV64IBP-NEXT: roriw a0, a0, 1 +; RV64IBP-NEXT: slli a0, a0, 31 +; RV64IBP-NEXT: srliw a1, a1, 1 +; RV64IBP-NEXT: or a0, a0, a1 +; RV64IBP-NEXT: sext.w a0, a0 ; RV64IBP-NEXT: ret %a = shl i32 %x, 31 %b = lshr i32 %y, 1