diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -10041,12 +10041,11 @@ // And has a few special cases for zext. if (Opcode == ISD::AND) { - // Preserve (and X, 0xffff) when zext.h is supported. - if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) { - APInt NewMask = APInt(Mask.getBitWidth(), 0xffff); - if (IsLegalMask(NewMask)) - return UseMask(NewMask); - } + // Preserve (and X, 0xffff), if zext.h exists use zext.h, + // otherwise use SLLI + SRLI. + APInt NewMask = APInt(Mask.getBitWidth(), 0xffff); + if (IsLegalMask(NewMask)) + return UseMask(NewMask); // Try to preserve (and X, 0xffffffff), the (zext_inreg X, i32) pattern. if (VT == MVT::i64) { diff --git a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll --- a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll +++ b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll @@ -140,3 +140,16 @@ %6 = add i32 %4, %2 ret i32 %6 } + +define i32 @and_or(i32 signext %x) { +; CHECK-LABEL: and_or: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori a0, a0, 255 +; CHECK-NEXT: slli a0, a0, 48 +; CHECK-NEXT: srli a0, a0, 48 +; CHECK-NEXT: ret +entry: + %and = and i32 %x, 65280 + %or = or i32 %and, 255 + ret i32 %or +}