[PATCH] D84785: [PowerPC] Don't remove swap if there is only a single one between the load and store

Nemanja Ivanovic via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 28 11:49:06 PDT 2020


nemanjai created this revision.
nemanjai added reviewers: wschmidt, PowerPC, hfinkel.
Herald added subscribers: shchenz, kbarton, hiraditya.
Herald added a project: LLVM.
nemanjai requested review of this revision.
Herald added a subscriber: wuzish.

The swap removal pass looks to remove swaps when a loaded value is swapped, some number of lane-insensitive operations are performed and then the value is swapped again and stored.
However, in a situation where we load the value, swap it and then store it without swapping again, the pass erroneously removes the single swap. The reason is that both checks in the same equivalence class:

- load feeds a swap
- swap feeds a store

pass. However, there is no check that the two swaps are actually a single swap. This patch just fixes that.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84785

Files:
  llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
  llvm/test/CodeGen/PowerPC/swaps-le-8.ll


Index: llvm/test/CodeGen/PowerPC/swaps-le-8.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/swaps-le-8.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -O3 -mcpu=pwr8 \
+; RUN:   -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
+define dso_local void @test(i64* %Src, i64* nocapture %Tgt) local_unnamed_addr {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lxvd2x 0, 0, 3
+; CHECK-NEXT:    xxswapd 0, 0
+; CHECK-NEXT:    stxvd2x 0, 0, 4
+; CHECK-NEXT:    blr
+entry:
+  %0 = bitcast i64* %Src to i8*
+  %1 = tail call <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8* %0) #2
+  %2 = bitcast i64* %Tgt to <2 x double>*
+  store <2 x double> %1, <2 x double>* %2, align 1
+  ret void
+}
+
+declare <2 x double> @llvm.ppc.vsx.lxvd2x.be(i8*) #1
Index: llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
+++ llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp
@@ -689,6 +689,29 @@
           LLVM_DEBUG(UseMI.dump());
           LLVM_DEBUG(dbgs() << "\n");
         }
+
+        // It is possible that the load feeds a swap and that swap feeds a
+        // store. In such a case, the code is actually trying to store a swapped
+        // vector. We must reject such webs.
+        if (SwapVector[UseIdx].IsSwap && !SwapVector[UseIdx].IsLoad &&
+            !SwapVector[UseIdx].IsStore) {
+          Register SwapDefReg = UseMI.getOperand(0).getReg();
+          for (MachineInstr &UseOfUseMI :
+               MRI->use_nodbg_instructions(SwapDefReg)) {
+            int UseOfUseIdx = SwapMap[&UseOfUseMI];
+            if (SwapVector[UseOfUseIdx].IsStore) {
+              SwapVector[Repr].WebRejected = 1;
+              LLVM_DEBUG(
+                  dbgs() << format(
+                      "Web %d rejected for load/swap feeding a store\n", Repr));
+              LLVM_DEBUG(dbgs() << "  def " << EntryIdx << ": ");
+              LLVM_DEBUG(MI->dump());
+              LLVM_DEBUG(dbgs() << "  use " << UseIdx << ": ");
+              LLVM_DEBUG(UseMI.dump());
+              LLVM_DEBUG(dbgs() << "\n");
+            }
+          }
+        }
       }
 
     // Reject webs that contain swapping stores that are fed by something


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84785.281312.patch
Type: text/x-patch
Size: 2416 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200728/c6beedd9/attachment.bin>


More information about the llvm-commits mailing list