Don't move normal loads across volatile/atomic loads.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 29 Aug 2012 20:48:45 +0000 (20:48 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 29 Aug 2012 20:48:45 +0000 (20:48 +0000)
It is technically allowed to move a normal load across a volatile load,
but probably not a good idea.

It is not allowed to move a load across an atomic load with
Ordering > Monotonic, and we model those with MOVolatile as well.

I recently removed the mayStore flag from atomic load instructions, so
they don't need a pseudo-opcode. This patch makes up for the difference.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162857 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineInstr.cpp

index bfb722bf3bb86ec63ea6c40297893b7f3dd90f34..7ff79b3a2230c37d21c41a708410781bae19e303 100644 (file)
@@ -1343,7 +1343,12 @@ bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII,
                                 AliasAnalysis *AA,
                                 bool &SawStore) const {
   // Ignore stuff that we obviously can't move.
-  if (mayStore() || isCall()) {
+  //
+  // Treat volatile loads as stores. This is not strictly necessary for
+  // volatiles, but it is required for atomic loads. It is now allowed to move
+  // a load across an atomic load with Ordering > Monotonic.
+  if (mayStore() || isCall() ||
+      (mayLoad() && hasVolatileMemoryRef())) {
     SawStore = true;
     return false;
   }
@@ -1359,8 +1364,8 @@ bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII,
   // load.
   if (mayLoad() && !isInvariantLoad(AA))
     // Otherwise, this is a real load.  If there is a store between the load and
-    // end of block, or if the load is volatile, we can't move it.
-    return !SawStore && !hasVolatileMemoryRef();
+    // end of block, we can't move it.
+    return !SawStore;
 
   return true;
 }