From: David Majnemer Date: Mon, 25 Jul 2016 02:21:23 +0000 (+0000) Subject: [GVNHoist] Properly merge alignments when hoisting X-Git-Tag: llvmorg-4.0.0-rc1~14325 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4728569d0a8c255f9727409879bbd290c0953d83;p=platform%2Fupstream%2Fllvm.git [GVNHoist] Properly merge alignments when hoisting 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 --- diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp index e7179a3..0b5e94f 100644 --- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -628,7 +628,6 @@ public: cast(cast(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(Repl)) + if (auto *ReplacementLoad = dyn_cast(Repl)) { + ReplacementLoad->setAlignment( + std::min(ReplacementLoad->getAlignment(), + cast(I)->getAlignment())); ++NumLoadsRemoved; - else if (isa(Repl)) + } else if (auto *ReplacementStore = dyn_cast(Repl)) { + ReplacementStore->setAlignment( + std::min(ReplacementStore->getAlignment(), + cast(I)->getAlignment())); ++NumStoresRemoved; - else if (isa(Repl)) + } else if (auto *ReplacementAlloca = dyn_cast(Repl)) { + ReplacementAlloca->setAlignment( + std::max(ReplacementAlloca->getAlignment(), + cast(I)->getAlignment())); + } else if (isa(Repl)) { ++NumCallsRemoved; + } Repl->intersectOptionalDataWith(I); I->replaceAllUsesWith(Repl); I->eraseFromParent(); diff --git a/llvm/test/Transforms/GVN/hoist.ll b/llvm/test/Transforms/GVN/hoist.ll index 9c2c425..01fedff 100644 --- a/llvm/test/Transforms/GVN/hoist.ll +++ b/llvm/test/Transforms/GVN/hoist.ll @@ -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]]