[llvm-commits] [llvm] r63227 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/volatile.ll

Chris Lattner sabre at nondot.org
Wed Jan 28 12:16:43 PST 2009


Author: lattner
Date: Wed Jan 28 14:16:43 2009
New Revision: 63227

URL: http://llvm.org/viewvc/llvm-project?rev=63227&view=rev
Log:
Fix some issues with volatility, move "CanConvertToScalar" check 
after the others.

Added:
    llvm/trunk/test/Transforms/ScalarRepl/volatile.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=63227&r1=63226&r2=63227&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Jan 28 14:16:43 2009
@@ -123,7 +123,7 @@
     void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocationInst *AI,
                                        SmallVector<AllocaInst*, 32> &NewElts);
     void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst *AI,
-                                       SmallVector<AllocaInst*, 32> &NewElts);
+                                      SmallVector<AllocaInst*, 32> &NewElts);
     
     const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial);
     void ConvertToScalar(AllocationInst *AI, const Type *Ty);
@@ -224,16 +224,6 @@
       continue;
     }
     
-    // If we can turn this aggregate value (potentially with casts) into a
-    // simple scalar value that can be mem2reg'd into a register value.
-    bool IsNotTrivial = false;
-    if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial))
-      if (IsNotTrivial && ActualType != Type::VoidTy) {
-        ConvertToScalar(AI, ActualType);
-        Changed = true;
-        continue;
-      }
-
     // Check to see if we can perform the core SROA transformation.  We cannot
     // transform the allocation instruction if it is an array allocation
     // (allocations OF arrays are ok though), and an allocation of a scalar
@@ -278,7 +268,17 @@
       Changed = true;
       continue;
     }
-        
+
+    // If we can turn this aggregate value (potentially with casts) into a
+    // simple scalar value that can be mem2reg'd into a register value.
+    bool IsNotTrivial = false;
+    if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial))
+      if (IsNotTrivial && ActualType != Type::VoidTy) {
+        ConvertToScalar(AI, ActualType);
+        Changed = true;
+        continue;
+      }
+    
     // Otherwise, couldn't process this.
   }
 
@@ -476,11 +476,13 @@
   if (BitCastInst *C = dyn_cast<BitCastInst>(User))
     return isSafeUseOfBitCastedAllocation(C, AI, Info);
 
-  if (isa<LoadInst>(User))
-    return; // Loads (returning a first class aggregrate) are always rewritable
-
-  if (isa<StoreInst>(User) && User->getOperand(0) != AI)
-    return; // Store is ok if storing INTO the pointer, not storing the pointer
+  if (LoadInst *LI = dyn_cast<LoadInst>(User))
+    if (!LI->isVolatile())
+      return;// Loads (returning a first class aggregrate) are always rewritable
+
+  if (StoreInst *SI = dyn_cast<StoreInst>(User))
+    if (!SI->isVolatile() && SI->getOperand(0) != AI)
+      return;// Store is ok if storing INTO the pointer, not storing the pointer
  
   GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User);
   if (GEPI == 0)
@@ -590,6 +592,9 @@
     } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(UI)) {
       isSafeMemIntrinsicOnAllocation(MI, AI, UI.getOperandNo(), Info);
     } else if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
+      if (SI->isVolatile())
+        return MarkUnsafe(Info);
+      
       // If storing the entire alloca in one chunk through a bitcasted pointer
       // to integer, we can transform it.  This happens (for example) when you
       // cast a {i32,i32}* to i64* and store through it.  This is similar to the
@@ -602,6 +607,9 @@
       }
       return MarkUnsafe(Info);
     } else if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
+      if (LI->isVolatile())
+        return MarkUnsafe(Info);
+
       // If loading the entire alloca in one chunk through a bitcasted pointer
       // to integer, we can transform it.  This happens (for example) when you
       // cast a {i32,i32}* to i64* and load through it.  This is similar to the
@@ -1234,6 +1242,9 @@
     Instruction *User = cast<Instruction>(*UI);
     
     if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
+      if (LI->isVolatile())
+        return 0;
+
       // FIXME: Loads of a first class aggregrate value could be converted to a
       // series of loads and insertvalues
       if (!LI->getType()->isSingleValueType())
@@ -1246,7 +1257,7 @@
     
     if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
       // Storing the pointer, not into the value?
-      if (SI->getOperand(0) == V) return 0;
+      if (SI->getOperand(0) == V || SI->isVolatile()) return 0;
 
       // FIXME: Stores of a first class aggregrate value could be converted to a
       // series of extractvalues and stores
@@ -1653,10 +1664,11 @@
 static bool isOnlyCopiedFromConstantGlobal(Value *V, Instruction *&TheCopy,
                                            bool isOffset) {
   for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) {
-    if (isa<LoadInst>(*UI)) {
-      // Ignore loads, they are always ok.
-      continue;
-    }
+    if (LoadInst *LI = dyn_cast<LoadInst>(*UI))
+      // Ignore non-volatile loads, they are always ok.
+      if (!LI->isVolatile())
+        continue;
+    
     if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI)) {
       // If uses of the bitcast are ok, we are ok.
       if (!isOnlyCopiedFromConstantGlobal(BCI, TheCopy, isOffset))

Added: llvm/trunk/test/Transforms/ScalarRepl/volatile.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/volatile.ll?rev=63227&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/ScalarRepl/volatile.ll (added)
+++ llvm/trunk/test/Transforms/ScalarRepl/volatile.ll Wed Jan 28 14:16:43 2009
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile load}
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile store}
+
+define i32 @voltest(i32 %T) {
+	%A = alloca {i32, i32}
+	%B = getelementptr {i32,i32}* %A, i32 0, i32 0
+	volatile store i32 %T, i32* %B
+
+	%C = getelementptr {i32,i32}* %A, i32 0, i32 1
+	%X = volatile load i32* %C
+	ret i32 %X
+}





More information about the llvm-commits mailing list