Skip to content

Commit bcc5b48

Browse files
Reapply "[AArch64] Merge LDRSWpre-LD[U]RSW pair into LDPSWpre"
This reverts commit 0def4e6, applies a quick fix that disallows merging two pre-indexed loads, and adds MIR regression tests. Differential Revision: https://reviews.llvm.org/D152407
1 parent b8b4ee6 commit bcc5b48

File tree

3 files changed

+81
-10
lines changed

3 files changed

+81
-10
lines changed

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2270,6 +2270,7 @@ bool AArch64InstrInfo::hasUnscaledLdStOffset(unsigned Opc) {
22702270
case AArch64::LDRWpre:
22712271
case AArch64::LDURXi:
22722272
case AArch64::LDRXpre:
2273+
case AArch64::LDRSWpre:
22732274
case AArch64::LDURSWi:
22742275
case AArch64::LDURHHi:
22752276
case AArch64::LDURBBi:
@@ -2479,6 +2480,7 @@ bool AArch64InstrInfo::isPairableLdStInst(const MachineInstr &MI) {
24792480
case AArch64::LDURXi:
24802481
case AArch64::LDRXpre:
24812482
case AArch64::LDURSWi:
2483+
case AArch64::LDRSWpre:
24822484
return true;
24832485
}
24842486
}
@@ -2599,7 +2601,8 @@ bool AArch64InstrInfo::isCandidateToMergeOrPair(const MachineInstr &MI) const {
25992601
// Can't merge/pair if the instruction modifies the base register.
26002602
// e.g., ldr x0, [x0]
26012603
// This case will never occur with an FI base.
2602-
// However, if the instruction is an LDR/STR<S,D,Q,W,X>pre, it can be merged.
2604+
// However, if the instruction is an LDR<S,D,Q,W,X,SW>pre or
2605+
// STR<S,D,Q,W,X>pre, it can be merged.
26032606
// For example:
26042607
// ldr q0, [x11, #32]!
26052608
// ldr q1, [x11, #16]
@@ -3176,6 +3179,7 @@ int AArch64InstrInfo::getMemScale(unsigned Opc) {
31763179
case AArch64::LDRSpre:
31773180
case AArch64::LDRSWui:
31783181
case AArch64::LDURSWi:
3182+
case AArch64::LDRSWpre:
31793183
case AArch64::LDRWpre:
31803184
case AArch64::LDRWui:
31813185
case AArch64::LDURWi:
@@ -3231,6 +3235,7 @@ bool AArch64InstrInfo::isPreLd(const MachineInstr &MI) {
32313235
return false;
32323236
case AArch64::LDRWpre:
32333237
case AArch64::LDRXpre:
3238+
case AArch64::LDRSWpre:
32343239
case AArch64::LDRSpre:
32353240
case AArch64::LDRDpre:
32363241
case AArch64::LDRQpre:

llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ static unsigned getMatchingNonSExtOpcode(unsigned Opc,
293293
return AArch64::LDRWui;
294294
case AArch64::LDURSWi:
295295
return AArch64::LDURWi;
296+
case AArch64::LDRSWpre:
297+
return AArch64::LDRWpre;
296298
}
297299
}
298300

@@ -372,6 +374,8 @@ static unsigned getMatchingPairOpcode(unsigned Opc) {
372374
case AArch64::LDRSWui:
373375
case AArch64::LDURSWi:
374376
return AArch64::LDPSWi;
377+
case AArch64::LDRSWpre:
378+
return AArch64::LDPSWpre;
375379
}
376380
}
377381

@@ -585,6 +589,8 @@ static bool isPreLdStPairCandidate(MachineInstr &FirstMI, MachineInstr &MI) {
585589
return (OpcB == AArch64::LDRWui) || (OpcB == AArch64::LDURWi);
586590
case AArch64::LDRXpre:
587591
return (OpcB == AArch64::LDRXui) || (OpcB == AArch64::LDURXi);
592+
case AArch64::LDRSWpre:
593+
return (OpcB == AArch64::LDRSWui) || (OpcB == AArch64::LDURSWi);
588594
}
589595
}
590596

@@ -1318,6 +1324,10 @@ static bool areCandidatesToMergeOrPair(MachineInstr &FirstMI, MachineInstr &MI,
13181324
if (OpcA == OpcB)
13191325
return !AArch64InstrInfo::isPreLdSt(FirstMI);
13201326

1327+
// Two pre ld/st of different opcodes cannot be merged either
1328+
if (AArch64InstrInfo::isPreLdSt(FirstMI) && AArch64InstrInfo::isPreLdSt(MI))
1329+
return false;
1330+
13211331
// Try to match a sign-extended load/store with a zero-extended load/store.
13221332
bool IsValidLdStrOpc, PairIsValidLdStrOpc;
13231333
unsigned NonSExtOpc = getMatchingNonSExtOpcode(OpcA, &IsValidLdStrOpc);
@@ -1340,7 +1350,7 @@ static bool areCandidatesToMergeOrPair(MachineInstr &FirstMI, MachineInstr &MI,
13401350
return false;
13411351

13421352
// The STR<S,D,Q,W,X>pre - STR<S,D,Q,W,X>ui and
1343-
// LDR<S,D,Q,W,X>pre-LDR<S,D,Q,W,X>ui
1353+
// LDR<S,D,Q,W,X,SW>pre-LDR<S,D,Q,W,X,SW>ui
13441354
// are candidate pairs that can be merged.
13451355
if (isPreLdStPairCandidate(FirstMI, MI))
13461356
return true;

llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ body: |
588588

589589

590590
---
591-
name: 21-ldrswpre-ldrswui-no-merge
591+
name: 21-ldrswpre-ldrswui-merge
592592
tracksRegLiveness: true
593593
liveins:
594594
- { reg: '$x0' }
@@ -599,10 +599,9 @@ machineFunctionInfo:
599599
body: |
600600
bb.0:
601601
liveins: $x0, $x1, $x2
602-
; CHECK-LABEL: name: 21-ldrswpre-ldrswui-no-merge
602+
; CHECK-LABEL: name: 21-ldrswpre-ldrswui-merge
603603
; CHECK: liveins: $x0, $x1, $x2
604-
; CHECK: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1 :: (load (s32))
605-
; CHECK: renamable $x2 = LDRSWui renamable $x1, 1 :: (load (s32))
604+
; CHECK: early-clobber $x1, renamable $x0, renamable $x2 = LDPSWpre renamable $x1, 10 :: (load (s32))
606605
; CHECK: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64))
607606
; CHECK: RET undef $lr
608607
early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32))
@@ -614,7 +613,7 @@ body: |
614613

615614

616615
---
617-
name: 22-ldrswpre-ldurswi-no-merge
616+
name: 22-ldrswpre-ldurswi-merge
618617
tracksRegLiveness: true
619618
liveins:
620619
- { reg: '$x0' }
@@ -625,10 +624,9 @@ machineFunctionInfo:
625624
body: |
626625
bb.0:
627626
liveins: $x0, $x1, $x2
628-
; CHECK-LABEL: name: 22-ldrswpre-ldurswi-no-merge
627+
; CHECK-LABEL: name: 22-ldrswpre-ldurswi-merge
629628
; CHECK: liveins: $x0, $x1, $x2
630-
; CHECK: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1 :: (load (s32))
631-
; CHECK: renamable $x2 = LDURSWi renamable $x1, 4 :: (load (s32))
629+
; CHECK: early-clobber $x1, renamable $x0, renamable $x2 = LDPSWpre renamable $x1, 10 :: (load (s32))
632630
; CHECK: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64))
633631
; CHECK: RET undef $lr
634632
early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32))
@@ -775,3 +773,61 @@ body: |
775773
STRXui killed renamable $x2, renamable $x1, 1 :: (store (s64))
776774
RET undef $lr
777775
...
776+
777+
778+
---
779+
name: 28-ldrswpre-ldrwpre-no-merge
780+
tracksRegLiveness: true
781+
liveins:
782+
- { reg: '$x11' }
783+
- { reg: '$x13' }
784+
machineFunctionInfo:
785+
hasRedZone: false
786+
body: |
787+
bb.0:
788+
liveins: $x11, $x13
789+
; CHECK-LABEL: name: 28-ldrswpre-ldrwpre-no-merge
790+
; CHECK: liveins: $x11, $x13
791+
; CHECK: early-clobber renamable $x11, dead renamable $x10 = LDRSWpre renamable $x11, 8, implicit $w11 :: (load (s32), align 8)
792+
; CHECK: $x14 = EORXrs renamable $x11, renamable $x13, 0
793+
; CHECK: early-clobber renamable $x11, dead renamable $w12 = LDRWpre renamable $x11, 4, implicit $w11 :: (load (s32))
794+
; CHECK: $x13 = EORXrs renamable $x11, renamable $x13, 0
795+
; CHECK: STPXi renamable $x13, renamable $x14, renamable $x11, 0 :: (store (s64))
796+
; CHECK: RET undef $lr
797+
early-clobber renamable $x11, renamable $x10 = LDRSWpre killed renamable $x11, 8 :: (load (s32), align 8)
798+
$x14 = EORXrs renamable $x11, renamable $x13, 0
799+
early-clobber renamable $x11, renamable $w12 = LDRWpre killed renamable $x11, 4 :: (load (s32))
800+
$x13 = EORXrs renamable $x11, killed renamable $x13, 0
801+
STRXui killed renamable $x13, renamable $x11, 0 :: (store (s64))
802+
STRXui killed renamable $x14, renamable $x11, 1 :: (store (s64))
803+
RET undef $lr
804+
...
805+
806+
807+
---
808+
name: 29-ldrwpre-ldrswpre-no-merge
809+
tracksRegLiveness: true
810+
liveins:
811+
- { reg: '$x11' }
812+
- { reg: '$x13' }
813+
machineFunctionInfo:
814+
hasRedZone: false
815+
body: |
816+
bb.0:
817+
liveins: $x11, $x13
818+
; CHECK-LABEL: name: 29-ldrwpre-ldrswpre-no-merge
819+
; CHECK: liveins: $x11, $x13
820+
; CHECK: early-clobber renamable $x11, dead renamable $w12 = LDRWpre renamable $x11, 8, implicit $w11 :: (load (s32))
821+
; CHECK: $x14 = EORXrs renamable $x11, renamable $x13, 0
822+
; CHECK: early-clobber renamable $x11, dead renamable $x10 = LDRSWpre renamable $x11, 4, implicit $w11 :: (load (s32), align 8)
823+
; CHECK: $x13 = EORXrs renamable $x11, renamable $x13, 0
824+
; CHECK: STPXi renamable $x13, renamable $x14, renamable $x11, 0 :: (store (s64))
825+
; CHECK: RET undef $lr
826+
early-clobber renamable $x11, renamable $w12 = LDRWpre killed renamable $x11, 8 :: (load (s32))
827+
$x14 = EORXrs renamable $x11, renamable $x13, 0
828+
early-clobber renamable $x11, renamable $x10 = LDRSWpre killed renamable $x11, 4 :: (load (s32), align 8)
829+
$x13 = EORXrs renamable $x11, killed renamable $x13, 0
830+
STRXui killed renamable $x13, renamable $x11, 0 :: (store (s64))
831+
STRXui killed renamable $x14, renamable $x11, 1 :: (store (s64))
832+
RET undef $lr
833+
...

0 commit comments

Comments
 (0)