[llvm] 0c93879 - [AArch64] merge scaled and unscaled zero narrow stores.
Zain Jaffal via llvm-commits
llvm-commits at lists.llvm.org
Fri May 26 07:07:44 PDT 2023
Author: Zain Jaffal
Date: 2023-05-26T15:07:24+01:00
New Revision: 0c93879d9621057c02712f700e79d4afa4a9bf8f
URL: https://github.com/llvm/llvm-project/commit/0c93879d9621057c02712f700e79d4afa4a9bf8f
DIFF: https://github.com/llvm/llvm-project/commit/0c93879d9621057c02712f700e79d4afa4a9bf8f.diff
LOG: [AArch64] merge scaled and unscaled zero narrow stores.
This patch fixes a crash when a sclaed and unscaled zero stores are merged.
Differential Revision: https://reviews.llvm.org/D150963
Added:
llvm/test/CodeGen/AArch64/str-narrow-zero-merge.mir
Modified:
llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index 4c13c095ff69f..41af5522d967d 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -734,8 +734,11 @@ AArch64LoadStoreOpt::mergeNarrowZeroStores(MachineBasicBlock::iterator I,
NextI = next_nodbg(NextI, E);
unsigned Opc = I->getOpcode();
+ unsigned MergeMIOpc = MergeMI->getOpcode();
bool IsScaled = !TII->hasUnscaledLdStOffset(Opc);
- int OffsetStride = IsScaled ? 1 : TII->getMemScale(*I);
+ bool IsMergedMIScaled = !TII->hasUnscaledLdStOffset(MergeMIOpc);
+ int OffsetStride = IsScaled ? TII->getMemScale(*I) : 1;
+ int MergeMIOffsetStride = IsMergedMIScaled ? TII->getMemScale(*MergeMI) : 1;
bool MergeForward = Flags.getMergeForward();
// Insert our new paired instruction after whichever of the paired
@@ -748,18 +751,27 @@ AArch64LoadStoreOpt::mergeNarrowZeroStores(MachineBasicBlock::iterator I,
: AArch64InstrInfo::getLdStBaseOp(*I);
// Which register is Rt and which is Rt2 depends on the offset order.
- MachineInstr *RtMI;
- if (AArch64InstrInfo::getLdStOffsetOp(*I).getImm() ==
- AArch64InstrInfo::getLdStOffsetOp(*MergeMI).getImm() + OffsetStride)
- RtMI = &*MergeMI;
+ int64_t IOffsetInBytes =
+ AArch64InstrInfo::getLdStOffsetOp(*I).getImm() * OffsetStride;
+ int64_t MIOffsetInBytes =
+ AArch64InstrInfo::getLdStOffsetOp(*MergeMI).getImm() *
+ MergeMIOffsetStride;
+ // Select final offset based on the offset order.
+ int64_t OffsetImm;
+ if (IOffsetInBytes > MIOffsetInBytes)
+ OffsetImm = MIOffsetInBytes;
else
- RtMI = &*I;
+ OffsetImm = IOffsetInBytes;
- int OffsetImm = AArch64InstrInfo::getLdStOffsetOp(*RtMI).getImm();
- // Change the scaled offset from small to large type.
- if (IsScaled) {
- assert(((OffsetImm & 1) == 0) && "Unexpected offset to merge");
- OffsetImm /= 2;
+ int NewOpcode = getMatchingWideOpcode(Opc);
+ bool FinalIsScaled = !TII->hasUnscaledLdStOffset(NewOpcode);
+
+ // Adjust final offset if the result opcode is a scaled store.
+ if (FinalIsScaled) {
+ int NewOffsetStride = FinalIsScaled ? TII->getMemScale(NewOpcode) : 1;
+ assert(((OffsetImm % NewOffsetStride) == 0) &&
+ "Offset should be a multiple of the store memory scale");
+ OffsetImm = OffsetImm / NewOffsetStride;
}
// Construct the new instruction.
diff --git a/llvm/test/CodeGen/AArch64/str-narrow-zero-merge.mir b/llvm/test/CodeGen/AArch64/str-narrow-zero-merge.mir
new file mode 100644
index 0000000000000..e995c402c50a8
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/str-narrow-zero-merge.mir
@@ -0,0 +1,172 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
+# RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs -run-pass=aarch64-ldst-opt %s -o - | FileCheck %s
+
+
+---
+name: merge_unscaled_str_with_unscaled_str_8
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_unscaled_str_8
+ ; CHECK: STURHHi $wzr, $x0, 4 :: (store (s8))
+ ; CHECK-NEXT: RET undef $lr
+ STURBBi $wzr, $x0, 4 :: (store (s8))
+ STURBBi $wzr, $x0, 5 :: (store (s8))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_scaled_str_8
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_scaled_str_8
+ ; CHECK: STRHHui $wzr, $x0, 2 :: (store (s8))
+ ; CHECK-NEXT: RET undef $lr
+ STRBBui $wzr, $x0, 4 :: (store (s8))
+ STRBBui $wzr, $x0, 5 :: (store (s8))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_unscaled_8
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_unscaled_8
+ ; CHECK: STRBBui $wzr, $x0, 4 :: (store (s8))
+ ; CHECK-NEXT: STURBBi $wzr, $x0, 5 :: (store (s8))
+ ; CHECK-NEXT: RET undef $lr
+ STRBBui $wzr, $x0, 4 :: (store (s8))
+ STURBBi $wzr, $x0, 5 :: (store (s8))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_scaled_8
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_scaled_8
+ ; CHECK: STURBBi $wzr, $x0, 4 :: (store (s8))
+ ; CHECK-NEXT: STRBBui $wzr, $x0, 5 :: (store (s8))
+ ; CHECK-NEXT: RET undef $lr
+ STURBBi $wzr, $x0, 4 :: (store (s8))
+ STRBBui $wzr, $x0, 5 :: (store (s8))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_unscaled_str_16
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_unscaled_str_16
+ ; CHECK: STURWi $wzr, $x0, 4 :: (store (s16))
+ ; CHECK-NEXT: RET undef $lr
+ STURHHi $wzr, $x0, 4 :: (store (s16))
+ STURHHi $wzr, $x0, 6 :: (store (s16))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_scaled_str_16
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_scaled_str_16
+ ; CHECK: STRWui $wzr, $x0, 2 :: (store (s16))
+ ; CHECK-NEXT: RET undef $lr
+ STRHHui $wzr, $x0, 4 :: (store (s16))
+ STRHHui $wzr, $x0, 5 :: (store (s16))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_unscaled_16
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_unscaled_16
+ ; CHECK: STRHHui $wzr, $x0, 2 :: (store (s16))
+ ; CHECK-NEXT: STURHHi $wzr, $x0, 6 :: (store (s16))
+ ; CHECK-NEXT: RET undef $lr
+ STRHHui $wzr, $x0, 2 :: (store (s16))
+ STURHHi $wzr, $x0, 6 :: (store (s16))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_scaled_16
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_scaled_16
+ ; CHECK: STURHHi $wzr, $x0, 4 :: (store (s16))
+ ; CHECK-NEXT: STRHHui $wzr, $x0, 3 :: (store (s16))
+ ; CHECK-NEXT: RET undef $lr
+ STURHHi $wzr, $x0, 4 :: (store (s16))
+ STRHHui $wzr, $x0, 3 :: (store (s16))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_unscaled_32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_unscaled_32
+ ; CHECK: STURXi $xzr, $x0, 4 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STURWi $wzr, $x0, 4 :: (store (s32))
+ STURWi $wzr, $x0, 8 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_scaled_32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_scaled_32
+ ; CHECK: STRXui $xzr, $x0, 1 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STRWui $wzr, $x0, 2 :: (store (s32))
+ STRWui $wzr, $x0, 3 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_unscaled_32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_unscaled_32
+ ; CHECK: STRXui $xzr, $x0, 1 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STRWui $wzr, $x0, 2 :: (store (s32))
+ STURWi $wzr, $x0, 12 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_scaled_32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_scaled_32
+ ; CHECK: STURXi $xzr, $x0, 8 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STURWi $wzr, $x0, 8 :: (store (s32))
+ STRWui $wzr, $x0, 3 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_unscaled_32_lower_address_second
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_unscaled_32_lower_address_second
+ ; CHECK: STRXui $xzr, $x0, 1 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STRWui $wzr, $x0, 3 :: (store (s32))
+ STURWi $wzr, $x0, 8 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_unscaled_str_with_scaled_32_lower_address_second
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_unscaled_str_with_scaled_32_lower_address_second
+ ; CHECK: STURXi $xzr, $x0, 4 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STURWi $wzr, $x0, 8 :: (store (s32))
+ STRWui $wzr, $x0, 1 :: (store (s32))
+ RET undef $lr
+...
+---
+name: merge_scaled_str_with_unscaled_32_negative_address
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: merge_scaled_str_with_unscaled_32_negative_address
+ ; CHECK: STPWi $wzr, $wzr, $x0, -1 :: (store (s32))
+ ; CHECK-NEXT: RET undef $lr
+ STRWui $wzr, $x0, 0 :: (store (s32))
+ STURWi $wzr, $x0, -4 :: (store (s32))
+ RET undef $lr
More information about the llvm-commits
mailing list