From 355e0a6460c1b76abe966480a6a7401444f48034 Mon Sep 17 00:00:00 2001 From: Michael Zolotukhin Date: Wed, 7 May 2014 14:30:18 +0000 Subject: [InstCombine] Add optimization of redundant insertvalue instructions. rdar://problem/11861387 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208214 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombine.h | 1 + .../InstCombine/InstCombineVectorOps.cpp | 36 ++++++++++++++++++++++ .../InstCombine/OverlappingInsertvalues.ll | 25 +++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 test/Transforms/InstCombine/OverlappingInsertvalues.ll diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h index 88351a09ce..8a082fea04 100644 --- a/lib/Transforms/InstCombine/InstCombine.h +++ b/lib/Transforms/InstCombine/InstCombine.h @@ -211,6 +211,7 @@ public: Instruction *visitStoreInst(StoreInst &SI); Instruction *visitBranchInst(BranchInst &BI); Instruction *visitSwitchInst(SwitchInst &SI); + Instruction *visitInsertValueInst(InsertValueInst &IV); Instruction *visitInsertElementInst(InsertElementInst &IE); Instruction *visitExtractElementInst(ExtractElementInst &EI); Instruction *visitShuffleVectorInst(ShuffleVectorInst &SVI); diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index aa81e8c972..80c20b7075 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -490,6 +490,42 @@ static ShuffleOps CollectShuffleElements(Value *V, return std::make_pair(V, nullptr); } +/// Try to find redundant insertvalue instructions, like the following ones: +/// %0 = insertvalue { i8, i32 } undef, i8 %x, 0 +/// %1 = insertvalue { i8, i32 } %0, i8 %y, 0 +/// Here the second instruction inserts values at the same indices, as the +/// first one, making the first one redundant. +/// It should be transformed to: +/// %0 = insertvalue { i8, i32 } undef, i8 %y, 0 +Instruction *InstCombiner::visitInsertValueInst(InsertValueInst &I) { + bool IsRedundant = false; + ArrayRef FirstIndices = I.getIndices(); + + // If there is a chain of insertvalue instructions (each of them except the + // last one has only one use and it's another insertvalue insn from this + // chain), check if any of the 'children' uses the same indices as the first + // instruction. In this case, the first one is redundant. + Value *V = &I; + unsigned int Depth = 0; + while (V->hasOneUse() && Depth < 10) { + User *U = V->user_back(); + InsertValueInst *UserInsInst = dyn_cast(U); + if (!UserInsInst || U->getType() != I.getType()) { + break; + } + if (UserInsInst->getIndices() == FirstIndices) { + IsRedundant = true; + break; + } + V = UserInsInst; + Depth++; + } + + if (IsRedundant) + return ReplaceInstUsesWith(I, I.getOperand(0)); + return nullptr; +} + Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { Value *VecOp = IE.getOperand(0); Value *ScalarOp = IE.getOperand(1); diff --git a/test/Transforms/InstCombine/OverlappingInsertvalues.ll b/test/Transforms/InstCombine/OverlappingInsertvalues.ll new file mode 100644 index 0000000000..3af684bf4b --- /dev/null +++ b/test/Transforms/InstCombine/OverlappingInsertvalues.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Check that we can find and remove redundant insertvalues +; CHECK-LABEL: foo_simple +; CHECK-NOT: i8* %x, 0 +define { i8*, i64, i32 } @foo_simple(i8* %x, i8* %y) nounwind { +entry: + %0 = insertvalue { i8*, i64, i32 } undef, i8* %x, 0 + %1 = insertvalue { i8*, i64, i32 } %0, i8* %y, 0 + ret { i8*, i64, i32 } %1 +} +; Check that we can find and remove redundant nodes in insertvalues chain +; CHECK-LABEL: foo_ovwrt_chain +; CHECK-NOT: i64 %y, 1 +; CHECK-NOT: i32 555, 2 +define { i8*, i64, i32 } @foo_ovwrt_chain(i8* %x, i64 %y, i64 %z) nounwind { +entry: + %0 = insertvalue { i8*, i64, i32 } undef, i8* %x, 0 + %1 = insertvalue { i8*, i64, i32 } %0, i64 %y, 1 + %2 = insertvalue { i8*, i64, i32 } %1, i32 555, 2 + %3 = insertvalue { i8*, i64, i32 } %2, i64 %z, 1 + %4 = insertvalue { i8*, i64, i32 } %3, i32 777, 2 + ret { i8*, i64, i32 } %4 +} -- cgit v1.2.3