[GVNHoist] Properly merge alignments when hoisting
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 25 Jul 2016 02:21:23 +0000 (02:21 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 25 Jul 2016 02:21:23 +0000 (02:21 +0000)
If we two loads of two different alignments, we must use the minimum of
the two alignments when hoisting.  Same deal for stores.

For allocas, use the maximum of the two allocas.

llvm-svn: 276601

llvm/lib/Transforms/Scalar/GVNHoist.cpp
llvm/test/Transforms/GVN/hoist.ll

index e7179a3..0b5e94f 100644 (file)
@@ -628,7 +628,6 @@ public:
             cast<Instruction>(cast<StoreInst>(OtherInst)->getValueOperand());
         ClonedVal->intersectOptionalDataWith(OtherVal);
       }
-      ClonedVal->clearSubclassOptionalData();
       Repl->replaceUsesOfWith(Val, ClonedVal);
     }
 
@@ -685,12 +684,23 @@ public:
       for (Instruction *I : InstructionsToHoist)
         if (I != Repl) {
           ++NR;
-          if (isa<LoadInst>(Repl))
+          if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
+            ReplacementLoad->setAlignment(
+                std::min(ReplacementLoad->getAlignment(),
+                         cast<LoadInst>(I)->getAlignment()));
             ++NumLoadsRemoved;
-          else if (isa<StoreInst>(Repl))
+          } else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
+            ReplacementStore->setAlignment(
+                std::min(ReplacementStore->getAlignment(),
+                         cast<StoreInst>(I)->getAlignment()));
             ++NumStoresRemoved;
-          else if (isa<CallInst>(Repl))
+          } else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
+            ReplacementAlloca->setAlignment(
+                std::max(ReplacementAlloca->getAlignment(),
+                         cast<AllocaInst>(I)->getAlignment()));
+          } else if (isa<CallInst>(Repl)) {
             ++NumCallsRemoved;
+          }
           Repl->intersectOptionalDataWith(I);
           I->replaceAllUsesWith(Repl);
           I->eraseFromParent();
index 9c2c425..01fedff 100644 (file)
@@ -689,3 +689,24 @@ if.else:                                          ; preds = %entry
 if.end:                                           ; preds = %if.else, %if.then
   ret void
 }
+
+define i32 @mergeAlignments(i1 %b, i32* %y) {
+entry:
+  br i1 %b, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  %l1 = load i32, i32* %y, align 4
+  br label %return
+
+if.end:                                           ; preds = %entry
+  %l2 = load i32, i32* %y, align 1
+  br label %return
+
+return:                                           ; preds = %if.end, %if.then
+  %retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ]
+  ret i32 %retval.0
+}
+; CHECK-LABEL: define i32 @mergeAlignments(
+; CHECK: %[[load:.*]] = load i32, i32* %y, align 1
+; CHECK: %[[phi:.*]] = phi i32 [ %[[load]], %{{.*}} ], [ %[[load]], %{{.*}} ]
+; CHECK: i32 %[[phi]]