diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12276,11 +12276,10 @@ !TLI.isTruncateFree(N0.getOperand(0).getOperand(0).getValueType(), N0.getValueType())) { SDLoc DL(N); - SDValue X = N0.getOperand(0).getOperand(0); - X = DAG.getAnyExtOrTrunc(X, DL, VT); - APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits()); - return DAG.getNode(ISD::AND, DL, VT, - X, DAG.getConstant(Mask, DL, VT)); + SDValue X = DAG.getAnyExtOrTrunc(N0.getOperand(0).getOperand(0), DL, VT); + SDValue Y = DAG.getNode(ISD::ANY_EXTEND, DL, VT, N0.getOperand(1)); + assert(isa(Y) && "Expected constant to be folded!"); + return DAG.getNode(ISD::AND, DL, VT, X, Y); } // fold (aext (load x)) -> (aext (truncate (extload x))) diff --git a/llvm/test/CodeGen/RISCV/and.ll b/llvm/test/CodeGen/RISCV/and.ll --- a/llvm/test/CodeGen/RISCV/and.ll +++ b/llvm/test/CodeGen/RISCV/and.ll @@ -70,3 +70,32 @@ ret i64 %a } +define i32 @and32_0xfffff000(i32 %x) { +; RV32I-LABEL: and32_0xfffff000: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 1048575 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: and32_0xfffff000: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 1048575 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: ret + %a = and i32 %x, -4096 + ret i32 %a +} + +define i32 @and32_0xfffffa00(i32 %x) { +; RV32I-LABEL: and32_0xfffffa00: +; RV32I: # %bb.0: +; RV32I-NEXT: andi a0, a0, -1536 +; RV32I-NEXT: ret +; +; RV64I-LABEL: and32_0xfffffa00: +; RV64I: # %bb.0: +; RV64I-NEXT: andi a0, a0, -1536 +; RV64I-NEXT: ret + %a = and i32 %x, -1536 + ret i32 %a +}