Skip to content

Commit 80fe772

Browse files
committed
Revert "Teach the AArch64 backend to materialize immediates using a pair of ORR-immediate"
This reverts commit 8d433a0 due to test failures on CodeGen/AArch64/GlobalISel/store-merging.ll
1 parent 3fad47a commit 80fe772

File tree

3 files changed

+38
-192
lines changed

3 files changed

+38
-192
lines changed

llvm/lib/Target/AArch64/AArch64ExpandImm.cpp

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -239,141 +239,6 @@ static bool trySequenceOfOnes(uint64_t UImm,
239239
return true;
240240
}
241241

242-
static uint64_t GetRunOfOnesStartingAt(uint64_t V, uint64_t StartPosition) {
243-
uint64_t NumOnes = llvm::countTrailingOnes(V >> StartPosition);
244-
245-
uint64_t UnshiftedOnes;
246-
if (NumOnes == 64) {
247-
UnshiftedOnes = ~0ULL;
248-
} else {
249-
UnshiftedOnes = (1ULL << NumOnes) - 1;
250-
}
251-
return UnshiftedOnes << StartPosition;
252-
}
253-
254-
static uint64_t rotl(uint64_t n, uint64_t d) {
255-
if (d == 0)
256-
return n;
257-
return (n << d) | (n >> (64 - d));
258-
}
259-
260-
static uint64_t rotr(uint64_t n, uint64_t d) {
261-
if (d == 0)
262-
return n;
263-
return (n >> d) | (n << (64 - d));
264-
}
265-
266-
static uint64_t MaximallyReplicateSubImmediate(uint64_t V, uint64_t Subset) {
267-
uint64_t Result = Subset;
268-
269-
// 64, 32, 16, 8, 4, 2
270-
for (uint64_t i = 0; i < 6; ++i) {
271-
uint64_t Rotation = 1 << (6 - i);
272-
uint64_t Closure = Result | rotl(Result, Rotation);
273-
if (Closure != (Closure & V)) {
274-
break;
275-
}
276-
Result = Closure;
277-
}
278-
279-
return Result;
280-
}
281-
282-
// Find the logical immediate that covers the most bits in RemainingBits,
283-
// allowing for additional bits to be set that were set in OriginalBits.
284-
static uint64_t maximalLogicalImmWithin(uint64_t RemainingBits,
285-
uint64_t OriginalBits) {
286-
// Find the first set bit.
287-
uint32_t Position = llvm::countTrailingZeros(RemainingBits);
288-
289-
// Get the first run of set bits.
290-
uint64_t FirstRun = GetRunOfOnesStartingAt(OriginalBits, Position);
291-
292-
// Replicate the run as many times as possible, as long as the bits are set in
293-
// RemainingBits.
294-
uint64_t MaximalImm = MaximallyReplicateSubImmediate(OriginalBits, FirstRun);
295-
296-
return MaximalImm;
297-
}
298-
299-
static std::optional<std::pair<uint64_t, uint64_t>>
300-
decomposeIntoOrrOfLogicalImmediates(uint64_t UImm) {
301-
if (UImm == 0 || ~UImm == 0)
302-
return std::nullopt;
303-
304-
// Make sure we don't have a run of ones split around the rotation boundary.
305-
uint32_t InitialTrailingOnes = llvm::countTrailingOnes(UImm);
306-
uint64_t RotatedBits = rotr(UImm, InitialTrailingOnes);
307-
308-
// Find the largest logical immediate that fits within the full immediate.
309-
uint64_t MaximalImm1 = maximalLogicalImmWithin(RotatedBits, RotatedBits);
310-
311-
// Remove all bits that are set by this mask.
312-
uint64_t RemainingBits = RotatedBits & ~MaximalImm1;
313-
314-
// Find the largest logical immediate covering the remaining bits, allowing
315-
// for additional bits to be set that were also set in the original immediate.
316-
uint64_t MaximalImm2 = maximalLogicalImmWithin(RemainingBits, RotatedBits);
317-
318-
// If any bits still haven't been covered, then give up.
319-
if (RemainingBits & ~MaximalImm2)
320-
return std::nullopt;
321-
322-
// Make sure to un-rotate the immediates.
323-
return std::make_pair(rotl(MaximalImm1, InitialTrailingOnes),
324-
rotl(MaximalImm2, InitialTrailingOnes));
325-
}
326-
327-
// Attempt to expand an immediate as the ORR of a pair of logical immediates.
328-
static bool tryOrrOfLogicalImmediates(uint64_t UImm,
329-
SmallVectorImpl<ImmInsnModel> &Insn) {
330-
auto MaybeDecomposition = decomposeIntoOrrOfLogicalImmediates(UImm);
331-
if (MaybeDecomposition == std::nullopt)
332-
return false;
333-
uint64_t Imm1 = MaybeDecomposition->first;
334-
uint64_t Imm2 = MaybeDecomposition->second;
335-
336-
uint64_t Encoding1, Encoding2;
337-
bool Imm1Success = AArch64_AM::processLogicalImmediate(Imm1, 64, Encoding1);
338-
bool Imm2Success = AArch64_AM::processLogicalImmediate(Imm2, 64, Encoding2);
339-
340-
if (Imm1Success && Imm2Success) {
341-
// Create the ORR-immediate instructions.
342-
Insn.push_back({AArch64::ORRXri, 0, Encoding1});
343-
Insn.push_back({AArch64::ORRXri, 1, Encoding2});
344-
return true;
345-
}
346-
347-
return false;
348-
}
349-
350-
// Attempt to expand an immediate as the AND of a pair of logical immediates.
351-
// This is done by applying DeMorgan's law, under which logical immediates
352-
// are closed.
353-
static bool tryAndOfLogicalImmediates(uint64_t UImm,
354-
SmallVectorImpl<ImmInsnModel> &Insn) {
355-
// Apply DeMorgan's law to turn this into an ORR problem.
356-
auto MaybeDecomposition = decomposeIntoOrrOfLogicalImmediates(~UImm);
357-
if (MaybeDecomposition == std::nullopt)
358-
return false;
359-
uint64_t Imm1 = MaybeDecomposition->first;
360-
uint64_t Imm2 = MaybeDecomposition->second;
361-
362-
uint64_t Encoding1, Encoding2;
363-
bool Imm1Success = AArch64_AM::processLogicalImmediate(~Imm1, 64, Encoding1);
364-
bool Imm2Success = AArch64_AM::processLogicalImmediate(~Imm2, 64, Encoding2);
365-
366-
if (Imm1Success && Imm2Success) {
367-
// Materialize Imm1, the LHS of the AND
368-
Insn.push_back({AArch64::ORRXri, 0, Encoding1});
369-
// AND Imm1 with Imm2
370-
Insn.push_back({AArch64::ANDXri, 1, Encoding2});
371-
return true;
372-
}
373-
374-
return false;
375-
}
376-
377242
/// \brief Expand a MOVi32imm or MOVi64imm pseudo instruction to a
378243
/// MOVZ or MOVN of width BitSize followed by up to 3 MOVK instructions.
379244
static inline void expandMOVImmSimple(uint64_t Imm, unsigned BitSize,
@@ -507,14 +372,6 @@ void AArch64_IMM::expandMOVImm(uint64_t Imm, unsigned BitSize,
507372
}
508373
}
509374

510-
// Attempt to use a sequence of two ORR-immediate instructions.
511-
if (tryOrrOfLogicalImmediates(Imm, Insn))
512-
return;
513-
514-
// Attempt to use a sequence of ORR-immediate followed by AND-immediate.
515-
if (tryAndOfLogicalImmediates(Imm, Insn))
516-
return;
517-
518375
// FIXME: Add more two-instruction sequences.
519376

520377
// Three instruction sequences.

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -148,40 +148,10 @@ bool AArch64ExpandPseudo::expandMOVImm(MachineBasicBlock &MBB,
148148

149149
case AArch64::ORRWri:
150150
case AArch64::ORRXri:
151-
if (I->Op1 == 0) {
152-
MIBS.push_back(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
153-
.add(MI.getOperand(0))
154-
.addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
155-
.addImm(I->Op2));
156-
} else {
157-
Register DstReg = MI.getOperand(0).getReg();
158-
bool DstIsDead = MI.getOperand(0).isDead();
159-
MIBS.push_back(
160-
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
161-
.addReg(DstReg, RegState::Define |
162-
getDeadRegState(DstIsDead && LastItem) |
163-
RenamableState)
164-
.addReg(DstReg)
165-
.addImm(I->Op2));
166-
}
167-
break;
168-
case AArch64::ANDXri:
169-
if (I->Op1 == 0) {
170-
MIBS.push_back(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
171-
.add(MI.getOperand(0))
172-
.addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
173-
.addImm(I->Op2));
174-
} else {
175-
Register DstReg = MI.getOperand(0).getReg();
176-
bool DstIsDead = MI.getOperand(0).isDead();
177-
MIBS.push_back(
178-
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
179-
.addReg(DstReg, RegState::Define |
180-
getDeadRegState(DstIsDead && LastItem) |
181-
RenamableState)
182-
.addReg(DstReg)
183-
.addImm(I->Op2));
184-
}
151+
MIBS.push_back(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
152+
.add(MI.getOperand(0))
153+
.addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
154+
.addImm(I->Op2));
185155
break;
186156
case AArch64::MOVNWi:
187157
case AArch64::MOVNXi:

llvm/test/CodeGen/AArch64/arm64-movi.ll

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,14 @@ define i64 @movz_skip1_movk() nounwind {
109109
ret i64 147695335379508
110110
}
111111

112+
; FIXME: Prefer "mov w0, #2863311530; lsl x0, x0, #4"
113+
; or "mov x0, #-6148914691236517206; and x0, x0, #45812984480"
112114
define i64 @orr_lsl_pattern() nounwind {
113115
; CHECK-LABEL: orr_lsl_pattern:
114116
; CHECK: // %bb.0:
115-
; CHECK-NEXT: mov x0, #-6148914691236517206
116-
; CHECK-NEXT: and x0, x0, #0x1fffffffe0
117+
; CHECK-NEXT: mov x0, #43680
118+
; CHECK-NEXT: movk x0, #43690, lsl #16
119+
; CHECK-NEXT: movk x0, #10, lsl #32
117120
; CHECK-NEXT: ret
118121
ret i64 45812984480
119122
}
@@ -319,11 +322,13 @@ define i64 @orr_movk15() nounwind {
319322
ret i64 549621596159
320323
}
321324

325+
; FIXME: prefer "mov x0, #2147483646; orr x0, x0, #36028659580010496"
322326
define i64 @orr_movk16() nounwind {
323327
; CHECK-LABEL: orr_movk16:
324328
; CHECK: // %bb.0:
325-
; CHECK-NEXT: mov x0, #2147483646
326-
; CHECK-NEXT: orr x0, x0, #0x7fffe0007fffe0
329+
; CHECK-NEXT: mov x0, #36028659580010496
330+
; CHECK-NEXT: movk x0, #65534
331+
; CHECK-NEXT: movk x0, #32767, lsl #16
327332
; CHECK-NEXT: ret
328333
ret i64 36028661727494142
329334
}
@@ -346,11 +351,13 @@ define i64 @orr_movk18() nounwind {
346351
ret i64 137438953409
347352
}
348353

354+
; FIXME: prefer "mov x0, #72340172838076673; and x0, x0, #2199023255296"
349355
define i64 @orr_and() nounwind {
350356
; CHECK-LABEL: orr_and:
351357
; CHECK: // %bb.0:
352-
; CHECK-NEXT: mov x0, #72340172838076673
353-
; CHECK-NEXT: and x0, x0, #0xffffffffff00
358+
; CHECK-NEXT: mov x0, #256
359+
; CHECK-NEXT: movk x0, #257, lsl #16
360+
; CHECK-NEXT: movk x0, #257, lsl #32
354361
; CHECK-NEXT: ret
355362
ret i64 1103823438080
356363
}
@@ -388,47 +395,59 @@ define i64 @movn_eor() nounwind {
388395
ret i64 3689348814437076172
389396
}
390397

398+
; FIXME: prefer "mov x0, #536866816; orr x0, x0, #0x3fff800000000000"
391399
define i64 @orr_orr_64() nounwind {
392400
; CHECK-LABEL: orr_orr_64:
393401
; CHECK: // %bb.0:
394-
; CHECK-NEXT: mov x0, #536866816
395-
; CHECK-NEXT: orr x0, x0, #0x3fff800000000000
402+
; CHECK-NEXT: mov x0, #4611545280939032576
403+
; CHECK-NEXT: movk x0, #61440
404+
; CHECK-NEXT: movk x0, #8191, lsl #16
396405
; CHECK-NEXT: ret
397406
ret i64 4611545281475899392
398407
}
399408

409+
; FIXME: prefer "mov x0, #558551907040256; orr x0, x0, #0x1000100010001000"
400410
define i64 @orr_orr_32() nounwind {
401411
; CHECK-LABEL: orr_orr_32:
402412
; CHECK: // %bb.0:
403-
; CHECK-NEXT: mov x0, #558551907040256
404-
; CHECK-NEXT: orr x0, x0, #0x1c001c001c001c00
413+
; CHECK-NEXT: mov x0, #-287953294993589248
414+
; CHECK-NEXT: movk x0, #7169, lsl #16
415+
; CHECK-NEXT: movk x0, #7169, lsl #48
405416
; CHECK-NEXT: ret
406417
ret i64 2018171185438784512
407418
}
408419

420+
; FIXME: prefer "mov x0, #281479271743489; orr x0, x0, #0x1000100010001000"
409421
define i64 @orr_orr_16() nounwind {
410422
; CHECK-LABEL: orr_orr_16:
411423
; CHECK: // %bb.0:
412-
; CHECK-NEXT: mov x0, #1152939097061330944
413-
; CHECK-NEXT: orr x0, x0, #0x1000100010001
424+
; CHECK-NEXT: mov x0, #4097
425+
; CHECK-NEXT: movk x0, #4097, lsl #16
426+
; CHECK-NEXT: movk x0, #4097, lsl #32
427+
; CHECK-NEXT: movk x0, #4097, lsl #48
414428
; CHECK-NEXT: ret
415429
ret i64 1153220576333074433
416430
}
417431

432+
; FIXME: prefer "mov x0, #144680345676153346; orr x0, x0, #0x1818181818181818"
418433
define i64 @orr_orr_8() nounwind {
419434
; CHECK-LABEL: orr_orr_8:
420435
; CHECK: // %bb.0:
421-
; CHECK-NEXT: mov x0, #144680345676153346
422-
; CHECK-NEXT: orr x0, x0, #0x1818181818181818
436+
; CHECK-NEXT: mov x0, #6682
437+
; CHECK-NEXT: movk x0, #6682, lsl #16
438+
; CHECK-NEXT: movk x0, #6682, lsl #32
439+
; CHECK-NEXT: movk x0, #6682, lsl #48
423440
; CHECK-NEXT: ret
424441
ret i64 1880844493789993498
425442
}
426443

444+
; FIXME: prefer "mov x0, #-6148914691236517206; orr x0, x0, #0x0FFFFF0000000000"
427445
define i64 @orr_64_orr_8() nounwind {
428446
; CHECK-LABEL: orr_64_orr_8:
429447
; CHECK: // %bb.0:
430448
; CHECK-NEXT: mov x0, #-6148914691236517206
431-
; CHECK-NEXT: orr x0, x0, #0xfffff0000000000
449+
; CHECK-NEXT: movk x0, #65450, lsl #32
450+
; CHECK-NEXT: movk x0, #45055, lsl #48
432451
; CHECK-NEXT: ret
433452
ret i64 -5764607889538110806
434453
}

0 commit comments

Comments
 (0)