summaryrefslogtreecommitdiff
path: root/unittests/Transforms/Utils
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2017-02-17 04:21:14 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2017-02-17 04:21:14 +0000
commit56ccc1cdbf5bcbc3e1fa503efab531d7d8a1229e (patch)
treee899dd3da610816d9f34aea41f49a4c17d3922d8 /unittests/Transforms/Utils
parent675c18fef3ae92e2389c6670c4e1049fd7556e08 (diff)
[JumpThreading] Re-enable JumpThreading for guards
Summary: JumpThreading for guards feature has been reverted at https://reviews.llvm.org/rL295200 due to the following problem: the feature used the following algorithm for detection of diamond patters: 1. Find a block with 2 predecessors; 2. Check that these blocks have a common single parent; 3. Check that the parent's terminator is a branch instruction. The problem is that these checks are insufficient. They may pass for a non-diamond construction in case if those two predecessors are actually the same block. This may happen if parent's terminator is a br (either conditional or unconditional) to a block that ends with "switch" instruction with exactly two branches going to one block. This patch re-enables the JumpThreading for guards and fixes this issue by adding the check that those found predecessors are actually different blocks. This guarantees that parent's terminator is a conditional branch with exactly 2 different successors, which is now ensured by assertions. It also adds two more tests for this situation (with parent's terminator being a conditional and an unconditional branch). Patch by Max Kazantsev! Reviewers: anna, sanjoy, reames Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30036 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295410 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Transforms/Utils')
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index 634aa9e7e65..a216959751f 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -201,6 +201,53 @@ TEST_F(CloneInstruction, CallingConvention) {
delete F2;
}
+TEST_F(CloneInstruction, DuplicateInstructionsToSplit) {
+ Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
+ FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+ V = new Argument(Type::getInt32Ty(context));
+
+ Function *F = Function::Create(FT, Function::ExternalLinkage);
+
+ BasicBlock *BB1 = BasicBlock::Create(context, "", F);
+ IRBuilder<> Builder1(BB1);
+
+ BasicBlock *BB2 = BasicBlock::Create(context, "", F);
+ IRBuilder<> Builder2(BB2);
+
+ Builder1.CreateBr(BB2);
+
+ Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
+ Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
+ Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
+ Builder2.CreateRetVoid();
+
+ ValueToValueMapTy Mapping;
+
+ auto Split = DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping);
+
+ EXPECT_TRUE(Split);
+ EXPECT_EQ(Mapping.size(), 2u);
+ EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
+ EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
+
+ auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
+ EXPECT_TRUE(AddSplit);
+ EXPECT_EQ(AddSplit->getOperand(0), V);
+ EXPECT_EQ(AddSplit->getOperand(1), V);
+ EXPECT_EQ(AddSplit->getParent(), Split);
+
+ auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
+ EXPECT_TRUE(MulSplit);
+ EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
+ EXPECT_EQ(MulSplit->getOperand(1), V);
+ EXPECT_EQ(MulSplit->getParent(), Split);
+
+ EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
+ EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
+
+ delete F;
+}
+
class CloneFunc : public ::testing::Test {
protected:
void SetUp() override {