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 @@ -38,9 +38,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 @@ -155,3 +155,11 @@ ; CHECK-NEXT: jirl $zero, $ra, 0 ret i64 2251801961170944 } + +define i64 @imm0() { +; CHECK-LABEL: imm0: +; CHECK: # %bb.0: +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: jirl $zero, $ra, 0 + ret i64 0 +} diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/and.ll @@ -84,12 +84,12 @@ define i1 @and_i1_4(i1 %b) { ; LA32-LABEL: and_i1_4: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i1_4: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i1 4, %b @@ -145,7 +145,7 @@ ; LA32-LABEL: and_i64_4: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 4 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_4: @@ -219,7 +219,7 @@ ; LA32-LABEL: and_i64_31: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 31 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_31: @@ -293,7 +293,7 @@ ; LA32-LABEL: and_i64_65: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 65 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_65: @@ -365,7 +365,7 @@ ; LA32-LABEL: and_i64_255: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 255 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_255: @@ -380,12 +380,12 @@ define i1 @and_i1_256(i1 %b) { ; LA32-LABEL: and_i1_256: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i1_256: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i1 256, %b @@ -395,12 +395,12 @@ define i8 @and_i8_256(i8 %b) { ; LA32-LABEL: and_i8_256: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i8_256: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i8 256, %b @@ -441,7 +441,7 @@ ; LA32-LABEL: and_i64_256: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 256 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_256: @@ -456,12 +456,12 @@ define i1 @and_i1_2048(i1 %b) { ; LA32-LABEL: and_i1_2048: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i1_2048: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i1 2048, %b @@ -471,12 +471,12 @@ define i8 @and_i8_2048(i8 %b) { ; LA32-LABEL: and_i8_2048: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i8_2048: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i8 2048, %b @@ -517,7 +517,7 @@ ; LA32-LABEL: and_i64_2048: ; LA32: # %bb.0: # %entry ; LA32-NEXT: andi $a0, $a0, 2048 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_2048: @@ -532,12 +532,12 @@ define i1 @and_i1_4096(i1 %b) { ; LA32-LABEL: and_i1_4096: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i1_4096: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i1 4096, %b @@ -547,12 +547,12 @@ define i8 @and_i8_4096(i8 %b) { ; LA32-LABEL: and_i8_4096: ; LA32: # %bb.0: # %entry -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i8_4096: ; LA64: # %bb.0: # %entry -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 entry: %r = and i8 4096, %b @@ -598,7 +598,7 @@ ; LA32: # %bb.0: # %entry ; LA32-NEXT: lu12i.w $a1, 1 ; LA32-NEXT: and $a0, $a0, $a1 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: and_i64_4096: diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-dbl.ll @@ -7,12 +7,12 @@ define i1 @fcmp_false(double %a, double %b) { ; LA32-LABEL: fcmp_false: ; LA32: # %bb.0: -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: fcmp_false: ; LA64: # %bb.0: -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 %cmp = fcmp false double %a, %b ret i1 %cmp diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/fcmp-flt.ll @@ -7,12 +7,12 @@ define i1 @fcmp_false(float %a, float %b) { ; LA32-LABEL: fcmp_false: ; LA32: # %bb.0: -; LA32-NEXT: ori $a0, $zero, 0 +; LA32-NEXT: move $a0, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: fcmp_false: ; LA64: # %bb.0: -; LA64-NEXT: ori $a0, $zero, 0 +; LA64-NEXT: move $a0, $zero ; LA64-NEXT: jirl $zero, $ra, 0 %cmp = fcmp false float %a, %b ret i1 %cmp diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sext-zext-trunc.ll @@ -7,15 +7,13 @@ ; LA32-LABEL: sext_i1_to_i8: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 1 -; LA32-NEXT: ori $a1, $zero, 0 -; LA32-NEXT: sub.w $a0, $a1, $a0 +; LA32-NEXT: sub.w $a0, $zero, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: sext_i1_to_i8: ; LA64: # %bb.0: ; LA64-NEXT: andi $a0, $a0, 1 -; LA64-NEXT: ori $a1, $zero, 0 -; LA64-NEXT: sub.d $a0, $a1, $a0 +; LA64-NEXT: sub.d $a0, $zero, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = sext i1 %a to i8 ret i8 %1 @@ -25,15 +23,13 @@ ; LA32-LABEL: sext_i1_to_i16: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 1 -; LA32-NEXT: ori $a1, $zero, 0 -; LA32-NEXT: sub.w $a0, $a1, $a0 +; LA32-NEXT: sub.w $a0, $zero, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: sext_i1_to_i16: ; LA64: # %bb.0: ; LA64-NEXT: andi $a0, $a0, 1 -; LA64-NEXT: ori $a1, $zero, 0 -; LA64-NEXT: sub.d $a0, $a1, $a0 +; LA64-NEXT: sub.d $a0, $zero, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = sext i1 %a to i16 ret i16 %1 @@ -43,15 +39,13 @@ ; LA32-LABEL: sext_i1_to_i32: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 1 -; LA32-NEXT: ori $a1, $zero, 0 -; LA32-NEXT: sub.w $a0, $a1, $a0 +; LA32-NEXT: sub.w $a0, $zero, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: sext_i1_to_i32: ; LA64: # %bb.0: ; LA64-NEXT: andi $a0, $a0, 1 -; LA64-NEXT: ori $a1, $zero, 0 -; LA64-NEXT: sub.d $a0, $a1, $a0 +; LA64-NEXT: sub.d $a0, $zero, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = sext i1 %a to i32 ret i32 %1 @@ -61,16 +55,14 @@ ; LA32-LABEL: sext_i1_to_i64: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 1 -; LA32-NEXT: ori $a1, $zero, 0 -; LA32-NEXT: sub.w $a0, $a1, $a0 +; LA32-NEXT: sub.w $a0, $zero, $a0 ; LA32-NEXT: move $a1, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: sext_i1_to_i64: ; LA64: # %bb.0: ; LA64-NEXT: andi $a0, $a0, 1 -; LA64-NEXT: ori $a1, $zero, 0 -; LA64-NEXT: sub.d $a0, $a1, $a0 +; LA64-NEXT: sub.d $a0, $zero, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = sext i1 %a to i64 ret i64 %1 @@ -208,7 +200,7 @@ ; LA32-LABEL: zext_i1_to_i64: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 1 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: zext_i1_to_i64: @@ -251,7 +243,7 @@ ; LA32-LABEL: zext_i8_to_i64: ; LA32: # %bb.0: ; LA32-NEXT: andi $a0, $a0, 255 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: zext_i8_to_i64: @@ -286,7 +278,7 @@ ; LA32-NEXT: lu12i.w $a1, 15 ; LA32-NEXT: ori $a1, $a1, 4095 ; LA32-NEXT: and $a0, $a0, $a1 -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: zext_i16_to_i64: @@ -302,7 +294,7 @@ define i64 @zext_i32_to_i64(i32 %a) { ; LA32-LABEL: zext_i32_to_i64: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 0 +; LA32-NEXT: move $a1, $zero ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: zext_i32_to_i64: