diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -202,6 +202,7 @@ unsigned AS, Instruction *I = nullptr) const override; + bool isLegalICmpImmediate(int64_t Imm) const override; bool isLegalAddImmediate(int64_t Imm) const override; bool hasAndNotCompare(SDValue Y) const override; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -3243,6 +3243,10 @@ return true; } +bool LoongArchTargetLowering::isLegalICmpImmediate(int64_t Imm) const { + return isInt<12>(Imm); +} + bool LoongArchTargetLowering::isLegalAddImmediate(int64_t Imm) const { return isInt<12>(Imm); } diff --git a/llvm/test/CodeGen/LoongArch/legalicmpimm.ll b/llvm/test/CodeGen/LoongArch/legalicmpimm.ll --- a/llvm/test/CodeGen/LoongArch/legalicmpimm.ll +++ b/llvm/test/CodeGen/LoongArch/legalicmpimm.ll @@ -5,20 +5,15 @@ define i32 @icmpimm(i32 %x) { ; LA32-LABEL: icmpimm: ; LA32: # %bb.0: -; LA32-NEXT: lu12i.w $a1, -1 -; LA32-NEXT: and $a0, $a0, $a1 -; LA32-NEXT: lu12i.w $a1, 1 -; LA32-NEXT: xor $a0, $a0, $a1 +; LA32-NEXT: srli.w $a0, $a0, 12 +; LA32-NEXT: addi.w $a0, $a0, -1 ; LA32-NEXT: sltui $a0, $a0, 1 ; LA32-NEXT: ret ; ; LA64-LABEL: icmpimm: ; LA64: # %bb.0: -; LA64-NEXT: lu12i.w $a1, -1 -; LA64-NEXT: lu32i.d $a1, 0 -; LA64-NEXT: and $a0, $a0, $a1 -; LA64-NEXT: lu12i.w $a1, 1 -; LA64-NEXT: xor $a0, $a0, $a1 +; LA64-NEXT: bstrpick.d $a0, $a0, 31, 12 +; LA64-NEXT: addi.d $a0, $a0, -1 ; LA64-NEXT: sltui $a0, $a0, 1 ; LA64-NEXT: ret %1 = and i32 %x, -4096