diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp @@ -37,9 +37,14 @@ break; case ISD::Constant: { int64_t Imm = cast(Node)->getSExtValue(); + if (Imm == 0 && Node->getSimpleValueType(0) == GRLenVT) { + SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, + LoongArch::R0, GRLenVT); + ReplaceNode(Node, New.getNode()); + return; + } SDNode *Result = nullptr; SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT); - // The instructions in the sequence are handled here. for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, GRLenVT); diff --git a/llvm/test/CodeGen/LoongArch/imm.ll b/llvm/test/CodeGen/LoongArch/imm.ll --- a/llvm/test/CodeGen/LoongArch/imm.ll +++ b/llvm/test/CodeGen/LoongArch/imm.ll @@ -1,5 +1,13 @@ ; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +define i64 @imm0() { +; CHECK-LABEL: imm0: +; CHECK: # %bb.0: +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: jirl $zero, $ra, 0 + ret i64 0 +} + define i64 @imm7ff0000000000000() { ; CHECK-LABEL: imm7ff0000000000000: ; CHECK: # %bb.0: