[PATCH] D152790: [ARM] Fix codegen of unaligned volatile load/store of i64

Maurice Heumann via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 19 02:00:23 PDT 2023


momo5502 updated this revision to Diff 532567.
momo5502 added a comment.

Thank you for investigating it. I have added a helper called `getDualLoadStoreAlignment`. Feel free to suggest a better name if you have one.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152790/new/

https://reviews.llvm.org/D152790

Files:
  llvm/lib/Target/ARM/ARMISelLowering.cpp
  llvm/lib/Target/ARM/ARMSubtarget.h
  llvm/test/CodeGen/ARM/i64_volatile_load_store.ll


Index: llvm/test/CodeGen/ARM/i64_volatile_load_store.ll
===================================================================
--- llvm/test/CodeGen/ARM/i64_volatile_load_store.ll
+++ llvm/test/CodeGen/ARM/i64_volatile_load_store.ll
@@ -5,6 +5,9 @@
 @x = common dso_local global i64 0, align 8
 @y = common dso_local global i64 0, align 8
 
+ at x_unaligned = common dso_local global i64 0, align 1
+ at y_unaligned = common dso_local global i64 0, align 1
+
 define void @test() {
 entry:
 ; CHECK-LABEL: test:
@@ -29,6 +32,34 @@
   ret void
 }
 
+define void @test_unaligned() {
+entry:
+; CHECK-LABEL: test_unaligned:
+; CHECK-ARMV5TE:      ldr [[ADDR0:r[0-9]+]]
+; CHECK-ARMV5TE-NEXT: ldr [[ADDR1:r[0-9]+]]
+; CHECK-ARMV5TE-NEXT: ldr [[R1:r[0-9]+]], [[[ADDR0]]]
+; CHECK-ARMV5TE-NEXT: ldr [[R0:r[0-9]+]], [[[ADDR0]], #4]
+; CHECK-ARMV5TE-NEXT: str [[R0]], [[[ADDR1]], #4]
+; CHECK-ARMV5TE-NEXT: str [[R1]], [[[ADDR1]]]
+; CHECK-T2:           movw [[ADDR0:r[0-9]+]], :lower16:x_unaligned
+; CHECK-T2-NEXT:      movw [[ADDR1:r[0-9]+]], :lower16:y_unaligned
+; CHECK-T2-NEXT:      movt [[ADDR0]], :upper16:x_unaligned
+; CHECK-T2-NEXT:      movt [[ADDR1]], :upper16:y_unaligned
+; CHECK-T2-NEXT:      ldr [[R1]], [[[ADDR0]]]
+; CHECK-T2-NEXT:      ldr [[R0]], [[[ADDR0]], #4]
+; CHECK-T2-NEXT:      str [[R0]], [[[ADDR1]], #4]
+; CHECK-T2-NEXT:      str [[R1]], [[[ADDR1]]]
+; CHECK-ARMV4T:       ldr [[ADDR0:r[0-9]+]]
+; CHECK-ARMV4T-NEXT:  ldr [[ADDR1:r[0-9]+]]
+; CHECK-ARMV4T-NEXT:  ldr [[R1:r[0-9]+]], [[[ADDR0]]]
+; CHECK-ARMV4T-NEXT:  ldr [[R0:r[0-9]+]], [[[ADDR0]], #4]
+; CHECK-ARMV4T-NEXT:  str [[R0]], [[[ADDR1]], #4]
+; CHECK-ARMV4T-NEXT:  str [[R1]], [[[ADDR1]]]
+  %0 = load volatile i64, ptr @x_unaligned, align 1
+  store volatile i64 %0, ptr @y_unaligned, align 1
+  ret void
+}
+
 define void @test_offset() {
 entry:
 ; CHECK-LABEL: test_offset:
Index: llvm/lib/Target/ARM/ARMSubtarget.h
===================================================================
--- llvm/lib/Target/ARM/ARMSubtarget.h
+++ llvm/lib/Target/ARM/ARMSubtarget.h
@@ -494,6 +494,11 @@
   /// function for this subtarget.
   Align getStackAlignment() const { return stackAlignment; }
 
+  // Returns the required alignment for LDRD/STRD instructions
+  Align getDualLoadStoreAlignment() const {
+    return Align(hasV7Ops() || allowsUnalignedMem() ? 4 : 8);
+  }
+
   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
 
   unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; }
Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -10080,7 +10080,8 @@
   assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
 
   if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
-      !Subtarget->isThumb1Only() && LD->isVolatile()) {
+      !Subtarget->isThumb1Only() && LD->isVolatile() &&
+      LD->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
     SDLoc dl(N);
     SDValue Result = DAG.getMemIntrinsicNode(
         ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
@@ -10137,7 +10138,8 @@
   assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
 
   if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
-      !Subtarget->isThumb1Only() && ST->isVolatile()) {
+      !Subtarget->isThumb1Only() && ST->isVolatile() &&
+      ST->getAlign() >= Subtarget->getDualLoadStoreAlignment()) {
     SDNode *N = Op.getNode();
     SDLoc dl(N);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152790.532567.patch
Type: text/x-patch
Size: 3575 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230619/f90c8f4f/attachment.bin>


More information about the llvm-commits mailing list