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 @@ -1008,7 +1008,7 @@ setJumpIsExpensive(); setTargetDAGCombine({ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::AND, - ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT}); + ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT, ISD::SHL}); if (Subtarget.is64Bit()) setTargetDAGCombine(ISD::SRA); @@ -10306,6 +10306,18 @@ DAG.getRegister(RISCV::X0, Subtarget.getXLenVT())); return DAG.getNode(N->getOpcode(), DL, VT, N->getOperand(0), ShAmt); } + if (N->getFlags().hasNoUnsignedWrap()) { + SDLoc DL(N); + SDValue N0 = N->getOperand(0); + auto *Ld = dyn_cast(N0); + if (Ld && ISD::isEXTLoad(Ld)) { + SDValue Res = DAG.getExtLoad(ISD::ZEXTLOAD, DL, N->getValueType(0), + Ld->getChain(), Ld->getBasePtr(), + Ld->getMemoryVT(), Ld->getMemOperand()); + return DAG.getNode(N->getOpcode(), DL, N->getValueType(0), Res, + N->getOperand(1)); + } + } break; } case RISCVISD::ADD_VL: diff --git a/llvm/test/CodeGen/RISCV/aext-to-zext.ll b/llvm/test/CodeGen/RISCV/aext-to-zext.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/aext-to-zext.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64I + +; We prefer to zero extend for zextload. The default behavior in +; TargetLowering::SimplifyDemandedBits is convert zero_extend into any_extend. +define zeroext i16 @read(ptr nocapture noundef readonly %adr) { +; RV64I-LABEL: read: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: lbu a1, 1(a0) +; RV64I-NEXT: lbu a0, 0(a0) +; RV64I-NEXT: slli a1, a1, 8 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +entry: + %0 = load i8, ptr %adr, align 1 + %conv = zext i8 %0 to i16 + %arrayidx1 = getelementptr inbounds i8, ptr %adr, i64 1 + %1 = load i8, ptr %arrayidx1, align 1 + %conv2 = zext i8 %1 to i16 + %shl = shl nuw i16 %conv2, 8 + %or = or i16 %shl, %conv + ret i16 %or +}