@@ -259,7 +259,7 @@ static bool trySequenceOfOnes(uint64_t UImm,
259259// =0xffff56780000a987.
260260// In any of these cases, the expansion with EOR/EON saves an instruction
261261// compared to the default expansion based on MOV and MOVKs.
262- static bool tryCopyWithNegation (uint64_t Imm,
262+ static bool tryCopyWithNegation (uint64_t Imm, bool AllowThreeSequence,
263263 SmallVectorImpl<ImmInsnModel> &Insn) {
264264 // We need the negation of the upper half of Imm to match the lower half.
265265 // Degenerate cases where Imm is a run of ones should be handled separately.
@@ -278,6 +278,8 @@ static bool tryCopyWithNegation(uint64_t Imm,
278278
279279 unsigned Imm0 = Imm & Mask;
280280 unsigned Imm16 = (Imm >> 16 ) & Mask;
281+ if (Imm0 != Mask && Imm16 != Mask && !AllowThreeSequence)
282+ return false ;
281283 if (Imm0 != Mask) {
282284 Insn.push_back ({AArch64::MOVNXi, Imm0 ^ Mask, 0 });
283285 if (Imm16 != Mask)
@@ -665,15 +667,14 @@ void AArch64_IMM::expandMOVImm(uint64_t Imm, unsigned BitSize,
665667 if (tryEorOfLogicalImmediates (UImm, Insn))
666668 return ;
667669
670+ // Attempt to use a sequence of MOVN+EOR/EON (shifted register).
671+ if (tryCopyWithNegation (Imm, /* AllowThreeSequence=*/ false , Insn))
672+ return ;
673+
668674 // FIXME: Add more two-instruction sequences.
669675
670676 // Three instruction sequences.
671-
672- // Attempt to use a sequence of MOVN+MOVK+EOR/EON (shifted register).
673- // The MOVK can be avoided if Imm contains a zero / one chunk.
674- if (tryCopyWithNegation (Imm, Insn))
675- return ;
676-
677+ //
677678 // Prefer MOVZ/MOVN followed by two MOVK; it's more readable, and possibly
678679 // the fastest sequence with fast literal generation. (If neither MOVK is
679680 // part of a fast literal generation pair, it could be slower than the
@@ -697,6 +698,10 @@ void AArch64_IMM::expandMOVImm(uint64_t Imm, unsigned BitSize,
697698 if (BitSize == 64 && trySequenceOfOnes (UImm, Insn))
698699 return ;
699700
701+ // Attempt to use a sequence of MOVN+MOVK+EOR (shifted register).
702+ if (tryCopyWithNegation (Imm, /* AllowThreeSequence=*/ true , Insn))
703+ return ;
704+
700705 // We found no possible two or three instruction sequence; use the general
701706 // four-instruction sequence.
702707 expandMOVImmSimple (Imm, BitSize, OneChunks, ZeroChunks, Insn);
0 commit comments