Skip to content

Commit

Permalink
Reapply "[AArch64] Merge LDRSWpre-LD[U]RSW pair into LDPSWpre"
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chaosdefinition committed Sep 23, 2023
1 parent b8b4ee6 commit bcc5b48
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 10 deletions.
7 changes: 6 additions & 1 deletion llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Expand Up @@ -2270,6 +2270,7 @@ bool AArch64InstrInfo::hasUnscaledLdStOffset(unsigned Opc) {
case AArch64::LDRWpre:
case AArch64::LDURXi:
case AArch64::LDRXpre:
case AArch64::LDRSWpre:
case AArch64::LDURSWi:
case AArch64::LDURHHi:
case AArch64::LDURBBi:
Expand Down Expand Up @@ -2479,6 +2480,7 @@ bool AArch64InstrInfo::isPairableLdStInst(const MachineInstr &MI) {
case AArch64::LDURXi:
case AArch64::LDRXpre:
case AArch64::LDURSWi:
case AArch64::LDRSWpre:
return true;
}
}
Expand Down Expand Up @@ -2599,7 +2601,8 @@ bool AArch64InstrInfo::isCandidateToMergeOrPair(const MachineInstr &MI) const {
// Can't merge/pair if the instruction modifies the base register.
// e.g., ldr x0, [x0]
// This case will never occur with an FI base.
// However, if the instruction is an LDR/STR<S,D,Q,W,X>pre, it can be merged.
// However, if the instruction is an LDR<S,D,Q,W,X,SW>pre or
// STR<S,D,Q,W,X>pre, it can be merged.
// For example:
// ldr q0, [x11, #32]!
// ldr q1, [x11, #16]
Expand Down Expand Up @@ -3176,6 +3179,7 @@ int AArch64InstrInfo::getMemScale(unsigned Opc) {
case AArch64::LDRSpre:
case AArch64::LDRSWui:
case AArch64::LDURSWi:
case AArch64::LDRSWpre:
case AArch64::LDRWpre:
case AArch64::LDRWui:
case AArch64::LDURWi:
Expand Down Expand Up @@ -3231,6 +3235,7 @@ bool AArch64InstrInfo::isPreLd(const MachineInstr &MI) {
return false;
case AArch64::LDRWpre:
case AArch64::LDRXpre:
case AArch64::LDRSWpre:
case AArch64::LDRSpre:
case AArch64::LDRDpre:
case AArch64::LDRQpre:
Expand Down
12 changes: 11 additions & 1 deletion llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
Expand Up @@ -293,6 +293,8 @@ static unsigned getMatchingNonSExtOpcode(unsigned Opc,
return AArch64::LDRWui;
case AArch64::LDURSWi:
return AArch64::LDURWi;
case AArch64::LDRSWpre:
return AArch64::LDRWpre;
}
}

Expand Down Expand Up @@ -372,6 +374,8 @@ static unsigned getMatchingPairOpcode(unsigned Opc) {
case AArch64::LDRSWui:
case AArch64::LDURSWi:
return AArch64::LDPSWi;
case AArch64::LDRSWpre:
return AArch64::LDPSWpre;
}
}

Expand Down Expand Up @@ -585,6 +589,8 @@ static bool isPreLdStPairCandidate(MachineInstr &FirstMI, MachineInstr &MI) {
return (OpcB == AArch64::LDRWui) || (OpcB == AArch64::LDURWi);
case AArch64::LDRXpre:
return (OpcB == AArch64::LDRXui) || (OpcB == AArch64::LDURXi);
case AArch64::LDRSWpre:
return (OpcB == AArch64::LDRSWui) || (OpcB == AArch64::LDURSWi);
}
}

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

// Two pre ld/st of different opcodes cannot be merged either
if (AArch64InstrInfo::isPreLdSt(FirstMI) && AArch64InstrInfo::isPreLdSt(MI))
return false;

// Try to match a sign-extended load/store with a zero-extended load/store.
bool IsValidLdStrOpc, PairIsValidLdStrOpc;
unsigned NonSExtOpc = getMatchingNonSExtOpcode(OpcA, &IsValidLdStrOpc);
Expand All @@ -1340,7 +1350,7 @@ static bool areCandidatesToMergeOrPair(MachineInstr &FirstMI, MachineInstr &MI,
return false;

// The STR<S,D,Q,W,X>pre - STR<S,D,Q,W,X>ui and
// LDR<S,D,Q,W,X>pre-LDR<S,D,Q,W,X>ui
// LDR<S,D,Q,W,X,SW>pre-LDR<S,D,Q,W,X,SW>ui
// are candidate pairs that can be merged.
if (isPreLdStPairCandidate(FirstMI, MI))
return true;
Expand Down
72 changes: 64 additions & 8 deletions llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir
Expand Up @@ -588,7 +588,7 @@ body: |


---
name: 21-ldrswpre-ldrswui-no-merge
name: 21-ldrswpre-ldrswui-merge
tracksRegLiveness: true
liveins:
- { reg: '$x0' }
Expand All @@ -599,10 +599,9 @@ machineFunctionInfo:
body: |
bb.0:
liveins: $x0, $x1, $x2
; CHECK-LABEL: name: 21-ldrswpre-ldrswui-no-merge
; CHECK-LABEL: name: 21-ldrswpre-ldrswui-merge
; CHECK: liveins: $x0, $x1, $x2
; CHECK: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1 :: (load (s32))
; CHECK: renamable $x2 = LDRSWui renamable $x1, 1 :: (load (s32))
; CHECK: early-clobber $x1, renamable $x0, renamable $x2 = LDPSWpre renamable $x1, 10 :: (load (s32))
; CHECK: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64))
; CHECK: RET undef $lr
early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32))
Expand All @@ -614,7 +613,7 @@ body: |


---
name: 22-ldrswpre-ldurswi-no-merge
name: 22-ldrswpre-ldurswi-merge
tracksRegLiveness: true
liveins:
- { reg: '$x0' }
Expand All @@ -625,10 +624,9 @@ machineFunctionInfo:
body: |
bb.0:
liveins: $x0, $x1, $x2
; CHECK-LABEL: name: 22-ldrswpre-ldurswi-no-merge
; CHECK-LABEL: name: 22-ldrswpre-ldurswi-merge
; CHECK: liveins: $x0, $x1, $x2
; CHECK: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1 :: (load (s32))
; CHECK: renamable $x2 = LDURSWi renamable $x1, 4 :: (load (s32))
; CHECK: early-clobber $x1, renamable $x0, renamable $x2 = LDPSWpre renamable $x1, 10 :: (load (s32))
; CHECK: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64))
; CHECK: RET undef $lr
early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32))
Expand Down Expand Up @@ -775,3 +773,61 @@ body: |
STRXui killed renamable $x2, renamable $x1, 1 :: (store (s64))
RET undef $lr
...


---
name: 28-ldrswpre-ldrwpre-no-merge
tracksRegLiveness: true
liveins:
- { reg: '$x11' }
- { reg: '$x13' }
machineFunctionInfo:
hasRedZone: false
body: |
bb.0:
liveins: $x11, $x13
; CHECK-LABEL: name: 28-ldrswpre-ldrwpre-no-merge
; CHECK: liveins: $x11, $x13
; CHECK: early-clobber renamable $x11, dead renamable $x10 = LDRSWpre renamable $x11, 8, implicit $w11 :: (load (s32), align 8)
; CHECK: $x14 = EORXrs renamable $x11, renamable $x13, 0
; CHECK: early-clobber renamable $x11, dead renamable $w12 = LDRWpre renamable $x11, 4, implicit $w11 :: (load (s32))
; CHECK: $x13 = EORXrs renamable $x11, renamable $x13, 0
; CHECK: STPXi renamable $x13, renamable $x14, renamable $x11, 0 :: (store (s64))
; CHECK: RET undef $lr
early-clobber renamable $x11, renamable $x10 = LDRSWpre killed renamable $x11, 8 :: (load (s32), align 8)
$x14 = EORXrs renamable $x11, renamable $x13, 0
early-clobber renamable $x11, renamable $w12 = LDRWpre killed renamable $x11, 4 :: (load (s32))
$x13 = EORXrs renamable $x11, killed renamable $x13, 0
STRXui killed renamable $x13, renamable $x11, 0 :: (store (s64))
STRXui killed renamable $x14, renamable $x11, 1 :: (store (s64))
RET undef $lr
...


---
name: 29-ldrwpre-ldrswpre-no-merge
tracksRegLiveness: true
liveins:
- { reg: '$x11' }
- { reg: '$x13' }
machineFunctionInfo:
hasRedZone: false
body: |
bb.0:
liveins: $x11, $x13
; CHECK-LABEL: name: 29-ldrwpre-ldrswpre-no-merge
; CHECK: liveins: $x11, $x13
; CHECK: early-clobber renamable $x11, dead renamable $w12 = LDRWpre renamable $x11, 8, implicit $w11 :: (load (s32))
; CHECK: $x14 = EORXrs renamable $x11, renamable $x13, 0
; CHECK: early-clobber renamable $x11, dead renamable $x10 = LDRSWpre renamable $x11, 4, implicit $w11 :: (load (s32), align 8)
; CHECK: $x13 = EORXrs renamable $x11, renamable $x13, 0
; CHECK: STPXi renamable $x13, renamable $x14, renamable $x11, 0 :: (store (s64))
; CHECK: RET undef $lr
early-clobber renamable $x11, renamable $w12 = LDRWpre killed renamable $x11, 8 :: (load (s32))
$x14 = EORXrs renamable $x11, renamable $x13, 0
early-clobber renamable $x11, renamable $x10 = LDRSWpre killed renamable $x11, 4 :: (load (s32), align 8)
$x13 = EORXrs renamable $x11, killed renamable $x13, 0
STRXui killed renamable $x13, renamable $x11, 0 :: (store (s64))
STRXui killed renamable $x14, renamable $x11, 1 :: (store (s64))
RET undef $lr
...

0 comments on commit bcc5b48

Please sign in to comment.