Check for volatile loads only once.
authorChris Lattner <sabre@nondot.org>
Sun, 1 May 2005 04:24:53 +0000 (04:24 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 1 May 2005 04:24:53 +0000 (04:24 +0000)
Implement load.ll:test7

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

lib/Transforms/Scalar/InstructionCombining.cpp

index c901b1a45e833fed7d3e8ae402910f4d49023d6b..6b958f2c77f2bc449e8c32af9e200920c68ed11a 100644 (file)
@@ -4750,13 +4750,34 @@ static bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) {
 Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
   Value *Op = LI.getOperand(0);
 
+  // load (cast X) --> cast (load X) iff safe
+  if (CastInst *CI = dyn_cast<CastInst>(Op))
+    if (Instruction *Res = InstCombineLoadCast(*this, LI))
+      return Res;
+
+  // None of the following transforms are legal for volatile loads.
+  if (LI.isVolatile()) return 0;
+
+  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op))
+    if (isa<ConstantPointerNull>(GEPI->getOperand(0)) ||
+        isa<UndefValue>(GEPI->getOperand(0))) {
+      // Insert a new store to null instruction before the load to indicate
+      // that this code is not reachable.  We do this instead of inserting
+      // an unreachable instruction directly because we cannot modify the
+      // CFG.
+      new StoreInst(UndefValue::get(LI.getType()),
+                    Constant::getNullValue(Op->getType()), &LI);
+      return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
+    }
+
   if (Constant *C = dyn_cast<Constant>(Op)) {
-    if ((C->isNullValue() || isa<UndefValue>(C)) &&
-        !LI.isVolatile()) {                          // load null/undef -> undef
+    // load null/undef -> undef
+    if ((C->isNullValue() || isa<UndefValue>(C))) {
       // Insert a new store to null instruction before the load to indicate that
       // this code is not reachable.  We do this instead of inserting an
       // unreachable instruction directly because we cannot modify the CFG.
-      new StoreInst(UndefValue::get(LI.getType()), C, &LI);
+      new StoreInst(UndefValue::get(LI.getType()),
+                    Constant::getNullValue(Op->getType()), &LI);
       return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
     }
 
@@ -4772,18 +4793,23 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
           if (GV->isConstant() && !GV->isExternal())
             if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
               return ReplaceInstUsesWith(LI, V);
+        if (CE->getOperand(0)->isNullValue()) {
+          // Insert a new store to null instruction before the load to indicate
+          // that this code is not reachable.  We do this instead of inserting
+          // an unreachable instruction directly because we cannot modify the
+          // CFG.
+          new StoreInst(UndefValue::get(LI.getType()),
+                        Constant::getNullValue(Op->getType()), &LI);
+          return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
+        }
+
       } else if (CE->getOpcode() == Instruction::Cast) {
         if (Instruction *Res = InstCombineLoadCast(*this, LI))
           return Res;
       }
   }
 
-  // load (cast X) --> cast (load X) iff safe
-  if (CastInst *CI = dyn_cast<CastInst>(Op))
-    if (Instruction *Res = InstCombineLoadCast(*this, LI))
-      return Res;
-
-  if (!LI.isVolatile() && Op->hasOneUse()) {
+  if (Op->hasOneUse()) {
     // Change select and PHI nodes to select values instead of addresses: this
     // helps alias analysis out a lot, allows many others simplifications, and
     // exposes redundancy in the code.